LPC2148 DAC
LPC2148 DAC Features:
- 10-bit DAC: The LPC2148 microcontroller comes equipped with a 10-bit DAC, meaning it can represent digital values in the range of 0 to 1023 .
- Resistor String Architecture: The DAC in the LPC2148 is based on a resistor string architecture, ensuring stable and accurate analog conversion. (R2R اللي استخدمناها في بروجيكت اللوجيك)
- Low-Power Mode: The DAC continues to work even in Power Down mode, which helps save energy in low-power applications.
Key DAC Components and Pins:
The DAC in LPC2148 involves several important components and pins:
- AOUT (Analog Output Pin): This is the pin where the analog voltage corresponding to the digital input is output.
- Analog Voltage Calculation: The analog output voltage on AOUT is calculated by the formula:
- Example: If
VALUE = 512, the output voltage isVREF/2.
- VREF (Voltage Reference): This provides the reference voltage for the DAC, which determines the scale of the output voltage.
- VDDA & VSSA (Analog Power and Ground): These pins supply power and ground for the DAC. They are similar to the VDD and VSS pins used for digital power supply and grounding.
DAC Registers
DACR Register Overview
The DACR is a 32-bit register that allows us to set the digital value and configure the DAC’s behavior. Here’s a breakdown of the key bits in the DACR register:
-
Bits 15:6 – VALUE: These bits hold the 10-bit digital value (ranging from 0 to 1023) that we want to convert into an analog voltage.
- The formula to calculate the analog output voltage is:
- The formula to calculate the analog output voltage is:
-
Bit 16 – BIAS: This bit controls the settling time and current of the DAC:
0: Maximum settling time of 1 µsec and current of 700 µA.1: Settling time of 2.5 µsec and current of 350 µA.
-
Bits 31:17 – RESERVED: These bits are not used and are reserved for future implementations. You should not modify these bits.
DACR Register Structure
flowchart LR DACR["DACR Register (32-bit)"] DACR --> BIAS["BIAS (Bit 16) 1 bit 0: Max 1μs settling 1: 2.5μs settling"] DACR --> VALUE["VALUE (Bits 15:6) 10-bit digital value Converted to Analog Voltage"]
How to Use the DACR Register?
To use the DAC effectively, you follow these steps:
- Set the DAC Output Pin: First, configure the output pin (P0.25) using the PINSEL Register to use it for DAC output.
- Set the Settling Time (BIAS): Adjust the settling time by setting the BIAS bit in the DACR Register. This determines how quickly the output voltage stabilizes.
- Write the 10-bit VALUE: Finally, write the 10-bit digital value (VALUE) to the DACR Register. This value will be converted into an analog voltage according to the formula mentioned earlier.
DACR Register Example
Let’s say we want to output a value of 512. To do this, we need to write the following to the DACR register:
DACR = (1 << 16) | (512 << 6);Here’s what happens:
(1 << 16): This sets the BIAS bit to1, meaning a settling time of 2.5 µsec and current of 350 µA.(512 << 6): This sets the VALUE field to512, which corresponds to half of the reference voltage (VREF / 2).
Summary of DACR Register Configuration:
| Field | Description | Example Value |
|---|---|---|
| VALUE (15:6) | 10-bit digital value (0-1023) to be converted to analog voltage. | 512 |
| BIAS (bit 16) | Controls settling time and current: 0 for fast, 1 for slow. | 1 (2.5 µsec settling) |
Code Example
1. Initial Setup
The code starts by configuring the necessary hardware:
- PINSEL1 is used to configure P0.25 as the DAC output pin.
- IO0DIR sets the direction of the input pins, which are used for selecting the waveform type through switches.
PINSEL1 = 0x00080000; /* P0.25 as DAC output */
IO0DIR = (IO0DIR & 0xFFFFF0FF); /* Input pins for switches: P0.8 (sine), P0.9 (triangular), P0.10 (sawtooth), P0.11 (square) */This setup ensures that P0.25 will output the analog signal and the switches are configured as inputs.
2. Waveform Definitions
In this part of the code, arrays for different waveforms are defined. For example, a sine wave (لو عندي اي شكل تاني بقى هحط قيمه كده برضو) is represented as an array of 42 values (since sine waves typically have multiple samples per period).
uint16_t sin_wave[42] = {
512, 591, 665, 742, 808, 873, 926, 968, 998, 1017, 1023, 1017, 998, 968, 926, 873, 808, 742, 665,
591, 512, 436, 359, 282, 216, 211, 151, 97, 55, 25, 6, 0, 6, 25, 55, 97, 151, 211, 216, 282, 359, 436
};3. Waveform Generation Logic
The while loop continuously checks which switch is pressed and generates the corresponding waveform:
- Sine Wave: When P0.8 is pressed, the code iterates through the sin wave array and writes each value to the DACR register.
if (!(IO0PIN & (1 << 8))) { // If sine wave switch is pressed
while (i != 42) {
value = sin_wave[i];
DACR = ((1 << 16) | (value << 6)); // Write value to DACR
delay_ms(1); // Delay to control frequency
i++;
}
i = 0; // Reset the counter for next sine wave cycle
}- Triangular Wave: When P0.9 is pressed, the code increments and decrements the VALUE from 0 to 1023, creating a triangular waveform.
else if (!(IO0PIN & (1 << 9))) { // If triangular wave switch is pressed
value = 0;
while (value != 1023) {
DACR = ((1 << 16) | (value << 6));
value++; // Increment for upward slope
}
while (value != 0) {
DACR = ((1 << 16) | (value << 6));
value--; // Decrement for downward slope
}
}- Sawtooth Wave: When P0.10 is pressed, the code generates a sawtooth wave by continuously incrementing the value from 0 to 1023.
else if (!(IO0PIN & (1 << 10))) { // If sawtooth wave switch is pressed
value = 0;
while (value != 1023) {
DACR = ((1 << 16) | (value << 6));
value++; // Continuous increment to create sawtooth
}
}- Square Wave: When P0.11 is pressed, the code alternates between high (1023) and low (0) values to create a square wave.
else if (!(IO0PIN & (1 << 11))) { // If square wave switch is pressed
value = 1023;
DACR = ((1 << 16) | (value << 6)); // High state
delay_ms(100); // Delay for desired frequency
value = 0;
DACR = ((1 << 16) | (value << 6)); // Low state
delay_ms(100); // Delay for desired frequency
}- DC Voltage: If no switch is pressed, a constant DC voltage is output (1023, which represents the reference voltage VREF).
else { // If no switch is pressed, output DC voltage
value = 1023;
DACR = ((1 << 16) | (value << 6)); // Constant DC voltage
}