In this tutorial, we will see how to use the DAC module of a PIC microcontroller. Digital to Analog converter is an electronics circuit that converts digital values into analog values. In other words, it converts digital voltage levels into an analog voltage levels. Furthermore, we can use DAC modules to generate different types of electrical waveforms such as sawtooth, triangular, sine wave, etc. Its working principle is the exact opposite of an analog to digital converter module.
If you want to recall ADC concepts and How to use Analog to digital converter module of pic microcontroller, go through these tutorials:
PIC Microcontroller Built-in DAC ModulesAlmost all Pic microcontroller that belongs to advance series of PIC16 and PIC18 has built-in DAC modules inside a chip. Therefore, we don’t need to use any external electronics circuits with a pic microcontroller. We can easily configure internal digital to analog converter module for generating analog signals. By using registers, a module can be easily configured. We will see examples in the latter part of this tutorial.
However, if built-in DAC does not support the specific requirement for your embedded design, we can look for off the chip external DAC ICs such as DAC0832. But in this tutorial, we will see how to use internal DAC modules of Microchip devices.
DAC Output SelectionIn this tutorial, we will use the PIC18F46K22 microcontroller. It has a built-in 5-bit DAC module. Some PIC chips also have 8-bit DAC modules. Like ADC, we also define its resolution with the help of a number of bits. A number of bits defines the number of steps or Resolution. Therefore, a 5-bit converter generates 32 levels. Few pic microcontrollers also have both 5-bit and 8-bit DACs inside a single MCU.
DAC Module PIC18F46K22PIC18F46K22 has one 5-bit module. This 5-bit module can provide 32 levels of the output voltage. We can select levels using control registers. We will see later on how to select levels. This picture shows a block diagram of a pic microcontroller. As you can see, it consists of resistor ladder types digital to analog converter. We can control the output voltage of the ladder resistive network with DACR [0:3] bits.
We can use it for the following applications:
It mainly consists of two control registers such as VREFCON1 and VREFCON2. But these are 8-bit registers.
DAC VREFCON1: VOLTAGE REFERENCE CONTROL REGISTER 0This register used to enable the DAC module, enable DACOUT (RA2) pin and a reference voltage. It is an 8-bit register and out of which 4 and 1 are unused.
VREFCON1bits.DACEN=1
VREFCON1bits.DACLPS=1 // Setting to active selects positive reference voltage VREFCON1bits.DACLAP=0 //clearing this selects negative reference voltage
VREFCON1bits.DACOE=1;
With the help of these two bits, we select a positive voltage source for DAC from these three options:
DACPSS Positive voltage source 00 Vdd 01 VREF+ 10 FVR BUF1 outputLike DAVPSS, DACNSS selects negative voltage reference from these two options:
DACNSS Negative voltage source 1 Vref 0 VSS DAC VREFCON2: VOLTAGE REFERENCE CONTROL REGISTER 2These bits select the level of output voltage from the DAC. This module generates output voltage according to this formula.
VOUT = ((VSRC+) - (VSRC-)) * (DACR [4:0]/(2^5)) + VSRC
The value of DAC will be in the range of 0-31 due to 5 bits resolution.
Now we will see three example and their codes to generate different waveforms with DAC module of PIC18F46K22 microcontroller.
In this section, we will see a code to generate a triangular waveform using the DAC module of PIC18F46K22 microcontroller. We can use a simple oscilloscope to see the waveform. RA2 pin which is PORTA pin2 provides DAC OUT signal. This circuit diagram shows the connection of RA2 with an oscilloscope.
Sawtooth is a ramp-up voltage that increases from a minimum value to the maximum value linearly. After reaching a maximum value, it suddenly falls to zero voltage. The operating voltage of the PIC18F46K22 microcontroller is 5 volts. Therefore, the ramp-up voltage goes from 0 to 5 volts.
PIC Microcontroller DAC Module ProgrammingWe used MPLAB XC8 Compiler to write a program for this tutorial. You may refer to getting started with MPLAB XC8 Compiler tutorial.
This code generates a sawtooth signal at the output pin.
#include "Config_PIC18F46K22.h" void internal_16(){ //Clock determined by FOSC in configuration bits SCS0 = 0; SCS1 = 0; //Frequency select bits IRCF0 = 1; IRCF1 = 1; IRCF2 = 1; //IRCF3 = 1; //SET PLLx4 OFF //SPLLEN = 0; } void initMain(){ // Run at 16 MHz internal_16(); // Set PIN D1 as output TRISAbits.TRISA1 = 0; TRISAbits.TRISA2 = 0; // Turn off LED LATAbits.LATA2 = 0; LATAbits.LATA1 = 0; ////////////////////// // Configure DAC ///////////////////// //VREFCON0bits.FVRS=0b11; // DAC enabled DACEN = 1; // DACOUT pin enabled DACOE = 1; // +ve source is Vdd VREFCON1bits.DACPSS = 0b00; // -ve source is Vss DACNSS = 0; DACLPS = 1; // Initial output is 0v VREFCON2bits.DACR=0b0000; } void main(void) { initMain(); int i=0; while(1) { VREFCON2bits.DACR=i; // increasing i value linearly to get linear output voltage i++; __delay_us(310); if(i>=31) i=0; } return; }
In this code, we define every DAC control register and its bits according to the information provided in registers sections. For example, we want to generate a sawtooth waveform of frequency 10HZ. The time period of 10Hz will be T= 1/10 = 10ms.
In order to get a 10Hz time period, we need to know the sampling period. But if we know a number of bits of DAC, we can easily calculate the DAC sampling period.
Ts=10ms/25 Ts= 10ms/32=312.5µs = 310µs
Therefore, we used a delay of 310µs after every DAC output sample.
PIC DAC Simulation Result Triangular Wave Generation using PIC DAC ModuleIn this section, we will see how to generate a triangular waveform with pic microcontroller DAC. A triangular wave consists of ramp-up and ramp-down voltage of equal lengths. For instance, we want to generate a triangular wave of 5Hz frequency.
This program will generate a 5Hz wave.
#include "Config_PIC18F46K22.h" void internal_16(){ //Clock determined by FOSC in configuration bits SCS0 = 0; SCS1 = 0; //Frequency select bits IRCF0 = 1; IRCF1 = 1; IRCF2 = 1; //IRCF3 = 1; //SET PLLx4 OFF //SPLLEN = 0; } void initMain(){ // Run at 16 MHz internal_16(); // Set PIN D1 as output TRISAbits.TRISA1 = 0; TRISAbits.TRISA2 = 0; // Turn off LED LATAbits.LATA2 = 0; LATAbits.LATA1 = 0; ////////////////////// // Configure DAC ///////////////////// //VREFCON0bits.FVRS=0b11; // DAC enabled DACEN = 1; // DACOUT pin enabled DACOE = 1; // +ve source is Vdd VREFCON1bits.DACPSS = 0b00; // -ve source is Vss DACNSS = 0; DACLPS = 1; // Initial output is 0v //DACR = 0; //VREFCON2bits.DACR=0b1111; } void main(void) { initMain(); int i=0; while(i<32) { VREFCON2bits.DACR=i; i++; } int j=31; while(j>-1) { VREFCON2bits.DACR=j; j--; } return; }
This code is exactly similar to the last code except for this part.
while(i<32) { VREFCON2bits.DACR=i; i++; } int j=31; while(j>-1) { VREFCON2bits.DACR=j; j--; }
First, while loop generates rump-up voltage output and second while loop generates a ramp-down voltage as shown in the figure below:
Sine wave generation using DAC ModuleLike sawtooth and triangular waves, we can also generate a sine wave using built-in digital to analog converter module of PIC18F46K22 microcontroller. To generate a sine wave, we need to create a sine table inside the code. We use a look-up table that stores values to create a sine wave. Although, you can calculate these values manually using a sine wave formula. But I have used this sine table calculator.
You can generate sine table values according to the size of your DAC module. PIC18F46K22 microcontroller has 5-bit DAC. Therefore, we will use 32 values.
{0,0,1,3,5,7,10,13, 16,19,22,25,27,28,30,31,31,31,30,28,27,25,22,19,16,13,10,7,5,3,1,0};
For example, we want to generate a 50Hz sine wave. We can calculate the sampling period similar to the last sections.
T=1/50=20ms Ts=20ms/32 = 625 micro seconds
That means we will increment the DACOUT value after every 635 microseconds.
Sine wave with DAC Code#include "Config_PIC18F46K22.h" void internal_16(){ //Clock determined by FOSC in configuration bits SCS0 = 0; SCS1 = 0; //Frequency select bits IRCF0 = 1; IRCF1 = 1; IRCF2 = 1; //IRCF3 = 1; //SET PLLx4 OFF //SPLLEN = 0; } int sinetable[32]= {0,0,1,3,5,7,10,13, 16,19,22,25,27,28,30,31,31,31,30,28,27,25,22,19,16,13,10,7,5,3,1,0}; void initMain(){ // Run at 16 MHz internal_16(); // Set PIN D1 as output TRISAbits.TRISA1 = 0; TRISAbits.TRISA2 = 0; // Turn off LED LATAbits.LATA2 = 0; LATAbits.LATA1 = 0; ////////////////////// // Configure DAC ///////////////////// //VREFCON0bits.FVRS=0b11; // DAC enabled DACEN = 1; // DACOUT pin enabled DACOE = 1; // +ve source is Vdd VREFCON1bits.DACPSS = 0b00; // -ve source is Vss DACNSS = 0; DACLPS = 1; // Initial output is 0v //DACR = 0; //VREFCON2bits.DACR=0b1111; } void main(void) { initMain(); int i=0; while(1) { VREFCON2bits.DACR=sinetable[i]; i++; __delay_us(620); if(i == 33) i=0; } return; }
This code produces a sine wave as shown in this simulation result.
In summary, in this tutorial, we have learned the use of DAC module of pic microcontroller with three examples and their programs.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4