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.
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.