Menu

Adskeeper - header widge

728x90

Search This Blog

468x60

Navbar

AdsKeeper - IAB Display Standard Ad Unit

Saturday, October 10, 2026

dsPIC30F2010 ADC Programming in MikroC

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.

 

dsPIC30F2010 ADC Programming in MikroC


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. 

 

dsPIC30F2010 ADC Programming in MikroC
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: 

 

dsPIC30F2010 ADC Programming in MikroC
Schematic Diagram

 

It's the same to my dsPIC30F2010 DIY Prototype Board.

 

MikroC Source Code:

 


  1. unsigned
    int temp_res;

  2. void main() {

  3. TRISB = 0xFFFF; // PORTB is input
  4. TRISD = 0; // PORTD is output
  5. TRISF = 0; // PORTF is output
  6. ADC1_Init(); // Enable ADC module

  7. do {
  8. temp_res = ADC1_Read(4); // Get 10-bit results of AD conversion
  9. if(temp_res>=512) LATD=0;
  10. else LATD=1;
  11. } while(1);
  12. }

 

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

 

dsPIC30F2010 ADC Programming in MikroC
Schematic Diagram

 

 The voltage value displaying is in floating point format.

 

MikroC Source Code:

 

  1. // LCD module connections
  2. sbit LCD_RS at LATE0_bit;
  3. sbit LCD_EN at LATE1_bit;
  4. sbit LCD_D4 at LATE2_bit;
  5. sbit LCD_D5 at LATE3_bit;
  6. sbit LCD_D6 at LATE4_bit;
  7. sbit LCD_D7 at LATE5_bit;

  8. sbit LCD_RS_Direction at TRISE0_bit;
  9. sbit LCD_EN_Direction at TRISE1_bit;
  10. sbit LCD_D4_Direction at TRISE2_bit;
  11. sbit LCD_D5_Direction at TRISE3_bit;
  12. sbit LCD_D6_Direction at TRISE4_bit;
  13. sbit LCD_D7_Direction at TRISE5_bit;
  14. // End LCD module connections

  15. unsigned char ch;
  16. unsigned int adc_rd;
  17. char *text;
  18. long tlong;

  19. void main() {
  20. ADPCFG = 0xFFFF; // Configure AN pins as digital

  21. Lcd_Init();
  22. LCD_Cmd(_LCD_CURSOR_OFF); // send command to LCD (cursor off)
  23. LCD_Cmd(_LCD_CLEAR); // send command to LCD (clear LCD)

  24. text = "mikroElektronika"; // assign text to string
  25. LCD_Out(1,1,text); // print string a on LCD, 1st row, 1st column
  26. text = "LCD example"; // assign text to string
  27. LCD_Out(2,3,text); // print string a on LCD, 2nd row, 1st column

  28. Delay_ms(7000);
  29. text = "dsPIC30F2010 ADC";
  30. LCD_Out(1,1,text);
  31. text = "Voltage: "; // assign text to string
  32. while (1) {
  33. adc_rd = ADC1_read(4); // get ADC value from 2nd channel
  34. LCD_Out(2,1,text); // print string a on LCD, 2nd row, 1st column

  35. tlong = (long)adc_rd * 5000; // covert adc reading to milivolts
  36. tlong = tlong / 1023; // 0..1023 -> 0-5000mV

  37. ch = tlong / 1000; // extract volts digit
  38. LCD_Chr(2,10,48+ch); // write ASCII digit at 2nd row, 9th column
  39. LCD_Chr_CP('.');

  40. ch = (tlong / 100) % 10; // extract 0.1 volts digit
  41. LCD_Chr_CP(48+ch); // write ASCII digit at cursor point

  42. ch = (tlong / 10) % 10; // extract 0.01 volts digit
  43. LCD_Chr_CP(48+ch); // write ASCII digit at cursor point

  44. LCD_Chr_CP('V');

  45. Delay_ms(100);
  46. }
  47. }//~!

 

I tested this example on my DIY dsPIC30F2010 Prototype Board.

 

dsPIC30F2010 ADC Programming in MikroC
Reading +5.00V

  

dsPIC30F2010 ADC Programming in MikroC
Reading +2.53V

  

dsPIC30F2010 ADC Programming in MikroC
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:



  1. unsigned
    int adc_rd;
  2. char *text;
  3. float voltage;

  4. void main() {
  5. ADPCFG = 0xFFFF;
  6. // Initialize UART module at 9600 bps
  7. UART1_Init(9600);
  8. Delay_ms(10);
  9. text = "dsPIC30F2010 ADC UART Example\n\r";
  10. UART1_Write_Text(text); // Write message on UART

  11. while(1){
  12. adc_rd = ADC1_read(4);
  13. voltage = 5.0 * adc_rd / 1023;
  14. sprintf(text,"AN4 Channel ADC Value: %d Decimal\n\r",adc_rd);
  15. UART1_Write_Text(text); // Write message on UART
  16. sprintf(text,"%0.2f Volts\n\r",voltage);
  17. UART1_Write_Text(text); // Write message on UART
  18. Delay_ms(2000);
  19. }
  20. }


 In the Library Manager, don't forget to tick on ADC, UART and Sprintf functions.

 

dsPIC30F2010 ADC Programming in MikroC
USART Terminal

 

 


dsPIC30F2010 MikroC for dsPIC UART Example

Overview

The UART is a simple serial communication interface exists in most of micro-controllers. Its protocol is very simple. A build-in UART module of a micro-controller offer a high speed, configurable and reliable data communication. This module doesn't exist in some low-end 8-bit micro-controller for example the PIC16F54 or the popular PIC16F84A. However the programmer can emulate this communication protocol in firmware such Assembly or even embedded C programming language (Software UART) due to its clarity. Some C compilers have their software UART allowing the user access to their build-in function libraries.

 

dsPIC30F2010 MikroC for dsPIC UART Example
UART Received ASCII Data

 

This communication interface is used to interact between micro-controller to microcontroller due to its two data wire - Transmit (TX) and Receive (RX). Some peripheral device such as GSM module, Wi-Fi modem (ESP8266), or HMI use UART.

 

MikroC for dsPIC UART Library

MikroC has built-in UART library that supports both hardware and software UART. Hardware UART implements the internal dedicated UART modules of any 16-bit PIC micro-controllers. Some 16-bit PIC micro-controllers have more than one UART interface, UART1, UART2, etc.

These are MikroC Hardware UART Library Routines:

Library Routines

Generic Routines

 

Now let test the UART1 communication interface of the dsPIC30F2010 using the MikroC UART example.

MikroC Source Code:



  1. char uart_rd;

  2. void main() {

  3. UART1_Init(9600); // Initialize UART module at 9600 bps
  4. Delay_ms(100); // Wait for UART module to stabilize

  5. // U1MODEbits.ALTIO = 1; // Un-comment this line to have Rx and Tx pins on their alternate
  6. // locations. This is used to free the pins for other module, namely the SPI.

  7. UART1_Write_Text("Start");
  8. UART1_Write(10);
  9. UART1_Write(13);

  10. while (1) { // Endless loop
  11. if (UART1_Data_Ready()) { // If data is received,
  12. uart_rd = UART1_Read(); // read the received data,
  13. UART1_Write(uart_rd); // and send data via UART
  14. }
  15. }
  16. }

 

In the Library Manger Window, Tick on UART. Then build the source code.

 

dsPIC30F2010 MikroC for dsPIC UART Example
UART in Library Manager

 

In MikroC IDE, go to Tools -> USART Terminal to open the interface.

 

dsPIC30F2010 MikroC for dsPIC UART Example
USART Terminal

 

Enter any characters and click Send, then the MCU will send back the received data. UART requires a precise micro-controller timing. So don't forget to set a correct clock source and frequency.

Let put a character LCD that displays received ASCII characters from PC Serial Port Terminal.

MikroC Source Code:

  1. // LCD module connections
  2. sbit LCD_RS at LATE0_bit;
  3. sbit LCD_EN at LATE1_bit;
  4. sbit LCD_D4 at LATE2_bit;
  5. sbit LCD_D5 at LATE3_bit;
  6. sbit LCD_D6 at LATE4_bit;
  7. sbit LCD_D7 at LATE5_bit;

  8. sbit LCD_RS_Direction at TRISE0_bit;
  9. sbit LCD_EN_Direction at TRISE1_bit;
  10. sbit LCD_D4_Direction at TRISE2_bit;
  11. sbit LCD_D5_Direction at TRISE3_bit;
  12. sbit LCD_D6_Direction at TRISE4_bit;
  13. sbit LCD_D7_Direction at TRISE5_bit;
  14. // End LCD module connections

  15. char txt1[] = "dsPIC30F2010";
  16. char txt2[] = "UART Example";
  17. char txt3[] = "Lcd4bit";
  18. char txt4[] = "example";

  19. char i=1;
  20. char uart_rd;

  21. void main(){
  22. ADPCFG = 0xFFFF; // Configure AN pins as digital I/O

  23. Lcd_Init(); // Initialize LCD
  24. UART1_Init(9600); // Initialize UART module at 9600 bps
  25. Delay_ms(100); // Wait for UART module to stabilize
  26. UART1_Write_Text("Reply for dsPIC30F2010 MCU");
  27. UART1_Write(10);
  28. UART1_Write(13);
  29. Lcd_Cmd(_LCD_CLEAR); // Clear display
  30. Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
  31. Lcd_Out(1,3,txt1); // Write text in first row

  32. Lcd_Out(2,3,txt2); // Write text in second row
  33. Delay_ms(5000);

  34. Lcd_Cmd(_LCD_CLEAR); // Clear display
  35. Delay_ms(10);
  36. Lcd_Out(1, 1 ,"PC Terminal:");

  37. while(1) { // Endless loop
  38. if (UART1_Data_Ready()) { // If data is received,
  39. uart_rd = UART1_Read(); // read the received data,
  40. UART1_Write(uart_rd); // and send data via UART
  41. Lcd_Chr(2, i, uart_rd);
  42. i++;
  43. }
  44. if(i>15) {
  45. i = 1;
  46. Lcd_Cmd(_LCD_CLEAR);
  47. Delay_ms(10);
  48. Lcd_Out(1 ,1 ,"PC Terminal:");
  49. }
  50. }
  51. }

 

The LCD shows UART characters, and the MCU will clears it automatically whenever the UART receiving counts reach 15.

Schematic:


dsPIC30F2010 MikroC for dsPIC UART Example
Schematic Diagram in Proteus


dsPIC30F2010 Prototype Board Testing:

 

dsPIC30F2010 MikroC for dsPIC UART Example
Serial Port Terminal

 

dsPIC30F2010 MikroC for dsPIC UART Example
Testing Program

 
dsPIC30F2010 MikroC for dsPIC UART Example
UART ASCII Data Receiving

Using the Sprint Library

The mikroC PRO for dsPIC30/33 and PIC24 provides the standard ANSI C Sprintf function for easy data formatting.

Note : In addition to ANSI C standard, the Sprint Library also includes two limited versions of the sprintf function (sprinti and sprintl)
     
    These functions take less ROM and RAM and may be more convenient for use in                 some cases.  

Functions

 

Since UART terminal accept only binary ASCII codes. Other data types such as array, integer or floating point numbers could not be directly transmitted over this communication protocol. So additional C function libraries is useful for converting non-ASCII characters into a readable ASCII characters.

 

MikroC Source Code:

 

  1. double ww = -1.2587538e+1;
  2. char buffer[15];

  3. void main(){

  4. UART1_Init(9600); // Initialize UART module at 4800 bps
  5. Delay_ms(10);

  6. UART1_Write_Text("Floating point number representation"); // Write message on UART

  7. sprintf(buffer, "%12e", ww); // Format ww and store it to buffer
  8. UART1_Write_Text("rne format:"); // Write message on UART
  9. UART1_Write_Text(buffer); // Write buffer on UART

  10. sprintf(buffer, "%12f", ww); // Format ww and store it to buffer
  11. UART1_Write_Text("rnf format:"); // Write message on UART
  12. UART1_Write_Text(buffer); // Write buffer on UART

  13. sprintf(buffer, "%12g", ww); // Format ww and store it to buffer
  14. UART1_Write_Text("rng format:"); // Write message on UART
  15. UART1_Write_Text(buffer); // Write buffer on UART
  16. }

 

We need to set a correct on board clock to 20MHz HS, and also include the UART and SPrint Library in Library Manager.

 

dsPIC30F2010 MikroC for dsPIC UART Example
USART Terminal

 

 


 

 

dsPIC30F2010 ds18B20 HD44780 LCD in MikroC

Introduction

The ds18S20/ds18B20 is one-wire precision digital temperature sensor. It implements only one data cable for command and data. The resolution of the ds18S20 is 9-bit while the ds18B20 is 12-bit higher resolution with floating point numbers.

dsPIC30F2010 ds18B20 HD44780 LCD in MikroC
A DS18B20 Sample from Ali Express

 

To interface with this sensor the master MCU program commonly uses the high speed Assembly language due to its fast response and its one-by-one instruction executions. However the manufactures of this chip (DALLAS) provide some sample programs written in C for the 8051-base devices.

Today using the Arduino is very common and ease of use for most of electronic hobbyists and engineers. There a lot of libraries and demo programs using this sensors. 

dsPIC30F2010 and ds18B20 Programming in MikroC

MikroC supports this one-wire digital temperature sensor for both the ds18S20 and the ds18B20. Unlike the Arduino libraries, using the MikroC One-Wire library, the master MCU need to process many steps such as writing command, reset, reading from scratch-pad, etc.

 

dsPIC30F2010 ds18B20 HD44780 LCD in MikroC
Schematic Diagram


In this example, the dsPIC30F2010 read the temperature data from a connected ds18B20 and it will be displayed on a character LCD. Both LCD and the sensor can be connect to any pins of an MCU upon the programming settings.

dsPIC30F2010 ds18B20 HD44780 LCD in MikroC
Edit Project

 

Timing is important for this one-wire sensor incorrect timing could cause command and data reading errors. The clock source is directly driven from an external 20MHz crystal oscillator without using Phase Lock Loop (PLL).

MikroC Source Code:

 

  1. // LCD module connections
  2. sbit LCD_RS at LATE0_bit;
  3. sbit LCD_EN at LATE1_bit;
  4. sbit LCD_D4 at LATE2_bit;
  5. sbit LCD_D5 at LATE3_bit;
  6. sbit LCD_D6 at LATE4_bit;
  7. sbit LCD_D7 at LATE5_bit;

  8. sbit LCD_RS_Direction at TRISE0_bit;
  9. sbit LCD_EN_Direction at TRISE1_bit;
  10. sbit LCD_D4_Direction at TRISE2_bit;
  11. sbit LCD_D5_Direction at TRISE3_bit;
  12. sbit LCD_D6_Direction at TRISE4_bit;
  13. sbit LCD_D7_Direction at TRISE5_bit;
  14. // End LCD module connections

  15. // Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
  16. // 18S20: 9 (default setting; can be 9,10,11,or 12)
  17. // 18B20: 12
  18. const unsigned short TEMP_RESOLUTION = 12;

  19. char *text = "000.0000";
  20. unsigned temp;

  21. void Display_Temperature(unsigned int temp2write) {
  22. const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
  23. char temp_whole;
  24. unsigned int temp_fraction;

  25. // check if temperature is negative
  26. if (temp2write & 0x8000) {
  27. text[0] = '-';
  28. temp2write = ~temp2write + 1;
  29. }

  30. // extract temp_whole
  31. temp_whole = temp2write >> RES_SHIFT ;

  32. // convert temp_whole to characters
  33. if (temp_whole/100)
  34. text[0] = temp_whole/100 + 48;
  35. else
  36. text[0] = '0';

  37. text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
  38. text[2] = temp_whole%10 + 48; // Extract ones digit

  39. // extract temp_fraction and convert it to unsigned int
  40. temp_fraction = temp2write << (4-RES_SHIFT);
  41. temp_fraction &= 0x000F;
  42. temp_fraction *= 625;

  43. // convert temp_fraction to characters
  44. text[4] = temp_fraction/1000 + 48; // Extract thousands digit
  45. text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit
  46. text[6] = (temp_fraction/10)%10 + 48; // Extract tens digit
  47. text[7] = temp_fraction%10 + 48; // Extract ones digit

  48. // print temperature on LCD
  49. Lcd_Out(2, 5, text);
  50. }

  51. void main() {

  52. ADPCFG = 0xFFFF; // Configure AN pins as digital

  53. Lcd_Init(); // Initialize LCD
  54. Lcd_Cmd(_LCD_CLEAR); // Clear LCD
  55. Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
  56. Lcd_Out(1, 1, " Temperature: ");
  57. // Print degree character, 'C' for Centigrades
  58. Lcd_Chr(2,13,223); // different LCD displays have different char code for degree
  59. // if you see greek alpha letter try typing 178 instead of 223

  60. Lcd_Chr(2,14,'C');

  61. //--- main loop
  62. do {
  63. //--- perform temperature reading
  64. Ow_Reset(&PORTC, 14); // Onewire reset signal
  65. Ow_Write(&PORTC, 14, 0xCC); // Issue command SKIP_ROM
  66. Ow_Write(&PORTC, 14, 0x44); // Issue command CONVERT_T
  67. Delay_us(120);

  68. Ow_Reset(&PORTC, 14);
  69. Ow_Write(&PORTC, 14, 0xCC); // Issue command SKIP_ROM
  70. Ow_Write(&PORTC, 14, 0xBE); // Issue command READ_SCRATCHPAD
  71. Delay_ms(400);

  72. temp = Ow_Read(&PORTC, 14);
  73. temp = (Ow_Read(&PORTC, 14) << 8) + temp;

  74. //--- Format and display result on Lcd
  75. Display_Temperature(temp);

  76. Delay_ms(500);
  77. } while (1);
  78. }

 

LCD and One-Wire libraries are not include in project by default. So we need select these two drivers.

 

dsPIC30F2010 ds18B20 HD44780 LCD in MikroC
Go to View -> Library Manager

 

If we temperature reading program please check connection or set its correct resolutions - 9-bit for ds18S20 and 12-bit for ds18B20.

 

dsPIC30F2010 ds18B20 HD44780 LCD in MikroC
Program Testing on my DIY dsPIC30F2010 Prototype Board

 

 

 

 

Adskeep- Standard Ads

336x280

DIY Electronic Projects And Instruments

AdsKeeper - 2091654

Labels

23K256 (1) 24C16B (2) 25AA010A (2) 8051 (7) 93AA46B (1) ADC (37) Analog Comparator (1) Arduino (16) ARM (32) AT89C52 (7) ATMega32 (59) ATMega644P (27) AVR (88) AVR PCB (2) Bootloader (1) CCS PICC (31) Change Notify Interrupt (CNI) (2) DAC (2) DHT11 (5) Display (153) Distance Sensor (3) dot matrix (1) ds1307 (10) DS18B20 (6) ds3231 (1) ds3232 (2) dsPIC (9) dsPIC30F1010 (3) dsPIC30F2010 (9) EEPROM (5) Environment Sensor (6) ESP32 (1) esp8266 (1) Graphical LCD (3) HD44780 (9) I2C (38) ILI9341 (1) Input/Output (83) Interrupt (22) IoT PCB (1) Keil (5) Keypad (16) KS0108 (3) LCD (83) LM35 (4) Master/Slave (2) MAX7221 (1) MCP23017 (8) MCP23S17 (7) MCP4921 (1) MCP4922 (2) Meter (3) MikroC (2) MikroC ARM (1) MikroC dsPIC (4) Module PCB (2) Motor (15) MPLABX (73) Nokia 5110 LCD (4) OLED (2) One-Wire (7) Oscillator (8) PCB (13) PCD8544 (3) PCF8574 (10) PIC (113) PIC12F (3) PIC16 (105) PIC16F628A (3) PIC16F630 (2) PIC16F716 (4) PIC16F818 (11) PIC16F818/819 (3) PIC16F84A (16) PIC16F876A (2) PIC16F877A (9) PIC16F88 (2) PIC16F887 (60) PIC18 (19) PIC18F1220 (5) PIC18F2550 (5) PIC18F4550 (12) PICKit2 (1) PICMicro PCB (4) Pin Change Interrupt (1) PWM (12) RTC (12) SBN0064G (1) Sensor (15) SH1106 (3) Shift Register (14) Shift Registers (16) SN74HC595N (4) Software TWI (2) SPI (41) sprinf (2) ST7735 (1) STM32 (29) STM32 Black Pill (1) STM32 Blue Pill (12) STM32 HAL (23) STM32CubeIDE (32) STM32F103C8T6 (9) STM32F103R6 (18) STM32F401CCU6 (1) SysTick (7) temperature sensor (15) TFT (1) TG12864A (1) Thermometer (22) Timer/Counter (32) TM1637 (2) twi (10) UART (11) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (96)