High Resolution Dithered DAC in PSoC

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Dithering is a widely used technique in Digital Processing where a noise is intentionally introduced into a system to increase the resolution of the system.  Say we have an 8 bit DAC with a full scale value of 255mV.  Each count of the DAC represents 1mV.  What if we wanted an output of 1.25mV from the DAC.  Switch the DAC output between 1mv and 2mV keeping the output at 2mV 25% of the time and 1mV 75% of the time, the average value of the output would be 1.25mV.  For an output of 1.5mV, the DAC output should be maintained at 2mV for 50% of the time and 1mV 50% of the time.

   


   

Now let us see how this method can be implemented using the PSoC 3 hardware to create a 10 bit DAC.

   

   

Place an 8 bit voltage DAC.  Select 1.020V (4mV / bit) as the range.  Set the Data_Source to “DAC Bus” and Strobe_Mode to “External”.  The output of the DAC can now be controlled using an 8 bit data bus and the output will be updated on the rising edge of the Strobe input.

   

Place a Multiplexer from the Digital >> Logic category.  Set number of input terminals to 2 and terminal width to 8.  The multiplexer can now switch between two 8 bit data buses.  Place two control registers from the Digital >> Registers category.  Set the number of outputs to 8.  Connect the 8 bit data bus of the Control registers to the input of the Multiplexer. 

   

Place a PWM, with a period of 3 and compare type set to “Less than”.  The output of the PWM now can be controlled to 0%, 25% and 75% duty cycle.  Connect the output of the PWM to the control input of the Mux.  Use the same clock of the PWM as a strobe to the DAC.  The hardware is now ready.

In firmware, write the Most Significant 8 bits of the 10 bit DAC value to the ControlRegister0 and one count higher value to ControlRegister1.  Use the Least Significant 2 bits to update the PWM’s pulse width.  Now, the PWM switches the input of the DAC between the two 8 bit Control Register values and the average output of the DAC would be our 10 bit DAC result.  Use an external Low Pass filter to remove the switching frequency.  As the switching frequency is at 125KHz, a simple RC filter will do the trick.  Below is the code.

   

void main()
{
   uint16 DacValue;
   VDAC8_Start();
   PwmMsb_Start();
   Amplifier_Start();
   for(;;)
   {
      DacMsbReg0_Write(DacValue >> 2);
      DacMsbReg1_Write((DacValue >> 2) + 1);
      PwmMsb_WriteCompare((uint8)(DacValue & 0x03));
   }
}

   

The range of the DAC now is 0 to 1020 counts; each count representing 1mV, subject to some offset and gain error inherent in the 8 bit DAC.

0 Likes
2 Replies
Anonymous
Not applicable

Since the VDAC is already a IDAC on a resistor only a capacitor is what you need for the RC filter. For this you just need to get the VDAC output on an intermediate pin which has teh capcitor as per the design of the RC filter. the internal resistor is a 4k for the 1 V range and 16k for the 4 v range. The tolerances would have ot be taken care of for the design.

   

0 Likes
MarkH_61
Employee
Employee
25 likes received 50 replies posted 25 replies posted

DAC dithering can be accomplished with the DMA as well, which can save you hardware.  You can create an array of values and have DMA periocically up the DAC.  (See image below)

   

   

Application note AN64275 describes this method and a couple others.  Also,  components are included in the application note that implement three of these methods.

   

Mark Hastings

0 Likes