Introduction
An Analog to Digital Converter (ADC) translates continuous voltage signal into a digital data that a digital or computer system could understands. For short, in most of modern micro-controllers have at least one dedicated ADC module inside. It range from 8-bit, 10-bit, 12-bit or even 16-bit in a mixed signal processor such as the MSP430 micro-controller series.
An ADC is needed in an audio sampling system, analog temperature reading, strain gauge, etc. Using a micro-controller's build-in ADC module is very cost effective reducing of complexities in hardware wiring.
![]() |
| 10-BIT HIGH SPEED A/D FUNCTIONAL BLOCK DIAGRAM |
The dsPIC30F2010 has six-channel 10-bit ADC module that able to convert any analog input channel up to 500KSPS. It has a programmable reference voltage pins - AVREF+ and AVREF-, and select able ADC supply voltage pins - AVDD and AVSS .
In some compilers there is no ADC library. So the programmer need configures its registers before allowing the ADC module to operate.
The A/D module has six 16-bit registers:
• A/D Control Register1 (ADCON1)
• A/D Control Register2 (ADCON2)
• A/D Control Register3 (ADCON3)
• A/D Input Select Register (ADCHS)
• A/D Port Configuration Register (ADPCFG)
• A/D Input Scan Selection Register (ADCSSL)
The programmer needs to configure its, clock source/frequency, result preparation, number of analog inputs, reference voltage pins, etc.
dsPIC30F2010 ADC Programming in MikroC
Using MikroC, reading any ADC inputs is very easy. Because it has a ready-to-use function library.
Library Routines
ADC AN4 and LED
Here I make a simple ADC reading example from AN4 pin that connects to a POT (on-board). I use its 10-bit resolution that ranges from 0 to 1023. If the result is over 512 an LED connects to RD0 will turn on, otherwise it will turns off.
Schematic Diagram:
![]() |
| Schematic Diagram |
It's the same to my dsPIC30F2010 DIY Prototype Board.
MikroC Source Code:
unsigned int temp_res;- void main() {
- TRISB = 0xFFFF; // PORTB is input
- TRISD = 0; // PORTD is output
- TRISF = 0; // PORTF is output
- ADC1_Init(); // Enable ADC module
- do {
- temp_res = ADC1_Read(4); // Get 10-bit results of AD conversion
- if(temp_res>=512) LATD=0;
- else LATD=1;
- } while(1);
- }
ADC AN4 and Character LCD
Following the Mikroelektronika Development Board example, I use a character LCD to read the analog input from AN4, showing its analog voltage result on a 16x4 character LCD.
Schematic Diagram
![]() |
| Schematic Diagram |
The voltage value displaying is in floating point format.
MikroC Source Code:
- // LCD module connections
- sbit LCD_RS at LATE0_bit;
- sbit LCD_EN at LATE1_bit;
- sbit LCD_D4 at LATE2_bit;
- sbit LCD_D5 at LATE3_bit;
- sbit LCD_D6 at LATE4_bit;
- sbit LCD_D7 at LATE5_bit;
- sbit LCD_RS_Direction at TRISE0_bit;
- sbit LCD_EN_Direction at TRISE1_bit;
- sbit LCD_D4_Direction at TRISE2_bit;
- sbit LCD_D5_Direction at TRISE3_bit;
- sbit LCD_D6_Direction at TRISE4_bit;
- sbit LCD_D7_Direction at TRISE5_bit;
- // End LCD module connections
- unsigned char ch;
- unsigned int adc_rd;
- char *text;
- long tlong;
- void main() {
- ADPCFG = 0xFFFF; // Configure AN pins as digital
- Lcd_Init();
- LCD_Cmd(_LCD_CURSOR_OFF); // send command to LCD (cursor off)
- LCD_Cmd(_LCD_CLEAR); // send command to LCD (clear LCD)
- text = "mikroElektronika"; // assign text to string
- LCD_Out(1,1,text); // print string a on LCD, 1st row, 1st column
- text = "LCD example"; // assign text to string
- LCD_Out(2,3,text); // print string a on LCD, 2nd row, 1st column
- Delay_ms(7000);
- text = "dsPIC30F2010 ADC";
- LCD_Out(1,1,text);
- text = "Voltage: "; // assign text to string
- while (1) {
- adc_rd = ADC1_read(4); // get ADC value from 2nd channel
- LCD_Out(2,1,text); // print string a on LCD, 2nd row, 1st column
- tlong = (long)adc_rd * 5000; // covert adc reading to milivolts
- tlong = tlong / 1023; // 0..1023 -> 0-5000mV
- ch = tlong / 1000; // extract volts digit
- LCD_Chr(2,10,48+ch); // write ASCII digit at 2nd row, 9th column
- LCD_Chr_CP('.');
- ch = (tlong / 100) % 10; // extract 0.1 volts digit
- LCD_Chr_CP(48+ch); // write ASCII digit at cursor point
- ch = (tlong / 10) % 10; // extract 0.01 volts digit
- LCD_Chr_CP(48+ch); // write ASCII digit at cursor point
- LCD_Chr_CP('V');
- Delay_ms(100);
- }
- }//~!
I tested this example on my DIY dsPIC30F2010 Prototype Board.
![]() |
| Reading +5.00V |
![]() |
| Reading +2.53V |
![]() |
| Reading 0.00V |
Sending the ADC Data Over The Serial Port
We can send the ADC conversion data over the serial port using additional C sprintf and UART function.
MikroC Source Code:
unsigned int adc_rd;- char *text;
- float voltage;
- void main() {
- ADPCFG = 0xFFFF;
- // Initialize UART module at 9600 bps
- UART1_Init(9600);
- Delay_ms(10);
- text = "dsPIC30F2010 ADC UART Example\n\r";
- UART1_Write_Text(text); // Write message on UART
- while(1){
- adc_rd = ADC1_read(4);
- voltage = 5.0 * adc_rd / 1023;
- sprintf(text,"AN4 Channel ADC Value: %d Decimal\n\r",adc_rd);
- UART1_Write_Text(text); // Write message on UART
- sprintf(text,"%0.2f Volts\n\r",voltage);
- UART1_Write_Text(text); // Write message on UART
- Delay_ms(2000);
- }
- }
In the Library Manager, don't forget to tick on ADC, UART and Sprintf functions.
![]() |
| USART Terminal |















