Hi again folks. Let’s get Analog! This time we will go through a discussion on ARM7 LPC2148 DAC programming tutorial. As you might be knowing, DAC stands for Digital to Analog Conversion. The DAC block in ARM7 LPC214x microcontroller is one of the simplest to program and use. Basically we feed in a digital value and the DAC block outputs it equivalent analog signal as shown below:
LPC2148 DAC Block
ARM7 LPC2148 MCU incorporates a 10 bit DAC and provides buffered analog output. As per the datasheet, it is implemeneted as a string DAC which is the most simplest form of DAC consisting of 2N resistors in series where N = no. of bits which simply forms a Kelvin-Varley Divider. LPC214x DAC has only 1 output pin, referred to as AOUT. The Analog voltage at the output of this pin is given as:
Where VALUE is the 10-bit digital value which is to be converted into its Analog counterpart and VREF is the input reference voltage.
Pins relating to LPC2148 DAC block:
Pin | Description |
---|---|
AOUT (P0.25) | Analog Output pin. Provides the converted Analog signal which is referenced to VSSA i.e. the Analog GND. Set Bits[19:18] in PINSEL1 register to [10] to enable this function. |
VREF | This is the voltage reference pin used by DAC for conversion. |
VDDA, VSSA | VDDA is Analog Power pin and VSSA is Ground pin used to power the DAC module. These are generally same as VCC and GND but with additional filtering to reduce noise. |
DACR register in LPC2148
Only one register is used to program the DAC block in ARM7 LPC214x viz. DACR. The field containing bits 6 to 15 is used to feed a digital value which needs to be converted and bit 16 is used to select settling time. The bit significance is as shown below:
- Bit[5:0]: Reserved.
- Bit[15:6] – VALUE: After a new VALUE is written to this field, given settling time selected using BIAS has elapsed, we get the converted Analog voltage at the output. The formula for analog voltage at AOUT pin is as shown above.
- Bit[16] – BIAS: Setting this bit to 0 selects settling time of 1us max with max current consumption of 700uA. Setting it to 1 will select settling time of 2.5us but with reduce max current consumption of 300uA.
- Bits[31:17]: Reserved
ARM7 LPC2148 DAC example
As it can been seen, programming the DAC block is very straight forward. We just need to select DAC function for P0.25 pin and feed a 10-bit value which needs to be converted into its Analog form. Lets see a basic LPC2148 DAC example. For most development boards VREF will be connected to VCC using some form of noise isolation. In this DAC example, we will be changing the output from 0V to VREF and then falling back to 0V in steps of 10ms. This DAC program will basically output a sawtooth waveform. We will be using BIAS = 0 i.e. settling time of 1us. You can connect an Oscilloscope or a Multimeter between P0.25 and GND to check the changing analog output. Since the output is buffered you can drive an LED from AOUT but it won’t glow until it reaches its forward bias voltage of around 1.7 Volts. So, keep this in mind when checking for analog output using an LED. Also, I have used Timer0 for generating delay. You can check my previous timer tutorial.
[Note: VSSA and GND will be common for most development boards.]
C/C++ Source Code:
/*(C) Umang Gajera - www.ocfreaks.com
LPC2148 DAC Example 1 Source Code using KEIL ARM
More Embedded tutorials @ www.ocfreaks.com/cat/embedded/
License : GPL.*/
#include <lpc214x.h>
void initTimer0(void);
void delayMS(unsigned int milliseconds);
int main(void)
{
initTimer0();
PINSEL1 |= (1<<19); //Select AOUT function for P0.25. bits[19:18] = [10]
unsigned int value=0; //Binary value used for Digital To Analog Conversion
while(1)
{
if(value > 1023) value=0; //For 10-bit DAC max-value is 2^10 - 1 = 1023
DACR = (value<<6);
delayMS(10);
value++;
}
}
void initTimer0(void)
{
/*Assuming that PLL0 has been setup with CCLK = 60Mhz*/
VPBDIV = 0x01; //Set PCLK = CCLK = 60Mhz
T0CTCR = 0x0;
T0PR = 60000-1; //60000 clock cycles @60Mhz = 1 ms
T0TCR = 0x02; //Reset Timer
}
void delayMS(unsigned int milliseconds) //Using Timer0
{
T0TCR = 0x02; //Reset Timer
T0TCR = 0x01; //Enable timer
while(T0TC < milliseconds); //wait until timer counter reaches the desired delay
T0TCR = 0x00; //Disable timer
}