Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] ADC conversion in MikroC

Status
Not open for further replies.

Kunal2

Junior Member level 3
Joined
Jun 21, 2011
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,512
Hi all

I wrote a program for adc conversion in mikroC as follows:

//ADC conversion and outputting digital value on leds

void ADCInit(){ //configuring A/D module

ADCON1 = 0b00000111; //channels AN8-An12 are digital and AN0-AN7 are analog
//Vref+ = Vdd and Vref- = Vss

ADCON2 = ox8A; //Right justified, Tad=2xacquisition time
//conversion clock = 32Tosc

}

//function to read ADC channel
unsigned int ADCRead( unsigned char ch){

ADCON0 = 0x00;//configuring analog channel
ADCON = (ch<<2); //selecting analog channel
ADON = 1; //switch on adc module
GODONE=1;//Start conversion

while(GODONE); //wait for the conversion to finish
ADON=0; //switch off adc

return ADRES;
}
void main() {

ADCInit(); //initialises adc in main program


TRISB = 0xff;//putting port b as output

while(1){
//always true condition. Endless loop

unsigned int val; //adc value

val=ADCRead(0); //read from channel 0
PORTB = val; // outputting result of AD conversion
}
}


on building the project i am getting errors like 1.Undeclared identifier 'ox8A' in expression adc.c
2.Undeclared identifier 'ADCON' in expression adc.c

I tried writing the program with ANSEL and ANSELH first but i was getting the same errors regarding identifiers.

Is it because i need to include a special library??

Kindly help folks

REgards
 

Which PIC are you using?
It should be 0x8A not ox8A, what you wrote is wrong. Type "0" instead of "o".

There is no register called ADCON. It's ADCON0, ADCON1, etc. And some PICs use ADCON1 for analogue/digital selection, others make use of ANSEL(H), so you need to tell us which PIC you are using.

Hope this helps.
Tahmid.

---------- Post added at 14:49 ---------- Previous post was at 14:46 ----------

In mikroC you don't need to include any special library files or anything.
 
I corrected the mistakes you pointed. I am using PIC 18F4520. ADCON0. ADCON1 are not encountering a compilation problem but ADCON2 on the other side is being referred to Undeclared identifier 'ADCON2' in expression adc.c

ADON, ADRES and GODONE also are encountering problems.
Assigning to non-lvalue 'ADON' adc.c
Undeclared identifier 'GODONE' in expression adc.c
Undeclared identifier 'GODONE' in expression adc.c
Assigning to non-lvalue 'ADON' adc.c
Undeclared identifier 'ADRES' in expression adc.c

I referred to the specification data sheet and tried writing the program with reference to ADON, GODONE, ADRES. I wonder where the problem actually lie.

Kindly help Tahmid

REgards
 

Here is the fixed code:
Code:
//ADC conversion and outputting digital value on leds

 void ADCInit(){ //configuring A/D module
 ADCON1 = 0b00000111; //channels AN8-An12 are digital and AN0-AN7 are analog
 //Vref+ = Vdd and Vref- = Vss

 ADCON2 = 0x8A; //Right justified, Tad=2xacquisition time
 //conversion clock = 32Tosc

 }

 //function to read ADC channel
 unsigned int ADCRead( unsigned char ch){

 ADCON0 = 0x00;//configuring analog channel
 ADCON0 = (ch<<2); //selecting analog channel
 ADON_bit = 1; //switch on adc module
 GO_DONE_bit =1;//Start conversion

 while(GO_DONE_bit); //wait for the conversion to finish
 ADON_bit =0; //switch off adc

 return ADRES;
 }
 void main() {

 ADCInit(); //initialises adc in main program

 TRISC = 0;
 TRISB = 0x00;//putting port b as output

 while(1){
 //always true condition. Endless loop

 unsigned int val; //adc value

 val=ADCRead(0); //read from channel 0
 PORTB = val; // outputting result of AD conversion
 PORTC = val >> 8;
 }
 }

Problems:

When you refer to a specific bit such as ADON, you refer to it as ADON_bit, GO_DONE_bit, etc
Setting 0 to TRIS sets PORT as output, setting 1 sets it as input.
You get a 10-bit value from ADRES. So, send 8-bits to PORTB, and the other 2 to PORTC.

Hope this helps.
Tahmid.
 
Thanks a lot tahmid for your precious help. The program compiled successfully. However on the Oshon software while loading the program it is saying the following : "Input program file in intel Hex format contain errors. Line number 1: Invalid data type in the record."

What's being meant by this??

Kindly help.

Regards
 

hello all
Has anyone ever simulated adc conversion on oshon software??? If yes let me know how to do it with the above program because im trying but its not working.

Regards
 

Infact the issue was about the windows.....I am presently using windows 7 which is not compatible with oshon software. Maybe the time at which the software was developed only windows xp configurations were taken into account. The program works well but it must be tried on windows XP or with a virtual machine XP can be installed followed by the oshon simulator and it will work..
 

sir tahmid,

can you write an example program regarding this using mikro C? thanks
 

What kind of program? One demonstrating the ADC?

Here is a sample program that samples AN2 and converts to a digital value that is displayed on PORTB and PORTC:
Code:
unsigned int temp_res;

void main() {
  ANSEL  = 0x04;              // Configure AN2 pin as analog
  ANSELH = 0;                 // Configure other AN pins as digital I/O
  C1ON_bit = 0;               // Disable comparators
  C2ON_bit = 0;
  
  TRISA  = 0xFF;              // PORTA is input
  TRISC  = 0;                 // PORTC is output
  TRISB  = 0;                 // PORTB is output

  do {
    temp_res = ADC_Read(2);   // Get 10-bit results of AD conversion
    PORTB = temp_res;         // Send lower 8 bits to PORTB
    PORTC = temp_res >> 8;    // Send 2 most significant bits to RC1, RC0
  } while(1);
}

Hope this helps.
Tahmid.
 
the example codes in micro c needs to be modified if you are using a device other than in the example given..
 

Obviously, but they should changed for any compiler. The only major change would be the setting of the ADCON1/ANSEL(H) and comparator register settings. The ADC function setting is the same.

Hope this helps.
Tahmid.
 
Last edited:

Here is the fixed code:
Code:
//ADC conversion and outputting digital value on leds

 void ADCInit(){ //configuring A/D module
 ADCON1 = 0b00000111; //channels AN8-An12 are digital and AN0-AN7 are analog
 //Vref+ = Vdd and Vref- = Vss

 ADCON2 = 0x8A; //Right justified, Tad=2xacquisition time
 //conversion clock = 32Tosc

 }

 //function to read ADC channel
 unsigned int ADCRead( unsigned char ch){

 ADCON0 = 0x00;//configuring analog channel
 ADCON0 = (ch<<2); //selecting analog channel
 ADON_bit = 1; //switch on adc module
 GO_DONE_bit =1;//Start conversion

 while(GO_DONE_bit); //wait for the conversion to finish
 ADON_bit =0; //switch off adc

 return ADRES;
 }
 void main() {

 ADCInit(); //initialises adc in main program

 TRISC = 0;
 TRISB = 0x00;//putting port b as output

 while(1){
 //always true condition. Endless loop

 unsigned int val; //adc value

 val=ADCRead(0); //read from channel 0
 PORTB = val; // outputting result of AD conversion
 PORTC = val >> 8;
 }
 }

Problems:

When you refer to a specific bit such as ADON, you refer to it as ADON_bit, GO_DONE_bit, etc
Setting 0 to TRIS sets PORT as output, setting 1 sets it as input.
You get a 10-bit value from ADRES. So, send 8-bits to PORTB, and the other 2 to PORTC.

Hope this helps.
Tahmid.

Sit Tahmid,

The above program you have made sir, ive modified some for my project, but its not working, im using Pic18f4550 and having an ADC conversion for LM35 for heat sensor. Heres my code sir:
Code:
//ADC conversion and outputting digital value on leds

 void ADCInit(){ //configuring A/D module
 ADCON1 = 0b00001110; //channels AN12-AN1 are digital and AN0 is analog
 //Vref+ = Vdd and Vref- = Vss

 ADCON2 = 0b10010100; //Right justified, Tad=4xacquisition time
 //conversion clock = 4Tosc

 }

 //function to read ADC channel
 unsigned int ADCRead( unsigned char ch){

 ADCON0 = 0x00;//configuring analog channel
 ADCON0 = (ch<<0); //selecting analog channel
 ADON_bit = 1; //switch on adc module
 GO_DONE_bit =1;//Start conversion

 while(GO_DONE_bit); //wait for the conversion to finish
 ADON_bit =0; //switch off adc

 return ADRES;
 }
 void main() {

 ADCInit(); //initializes adc in main program

 TRISC = 0;
 TRISB = 0x00;//putting port b as output
 PORTB = 0x00; // initial value of PORTB

 while(1){
 //always true condition. Endless loop

 unsigned int val; //adc value
 int finalval;

 val=ADCRead(0); //read from channel 0
 finalval= 5.00 * val * 100.00/ 1023.00; // converting adc reading to celsius
 
 if((finalval >= 0) && (finalval <=10))
 {
  RB0_bit=1;
  RB1_bit=0;
  RB2_bit=0;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
 else if((finalval >= 11) && (finalval <=20))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=0;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
 else if((finalval >= 21) && (finalval <=30))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
  else if((finalval >= 31) && (finalval <=40))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=0;
  RB5_bit=0;
 }
  else if((finalval >= 41) && (finalval <=50))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=1;
  RB5_bit=0;
 }
 else
 {
 RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=1;
  RB5_bit=1;
  }
 }
 }

please kindly check for errors sir, ive just tried it on breadboard but still no correct output. thanks sir.
 

Here's the fixed code:
Code:
//ADC conversion and outputting digital value on leds

 void ADCInit(){ //configuring A/D module
 ADCON1 = 0b00001110; //channels AN12-AN1 are digital and AN0 is analog
 //Vref+ = Vdd and Vref- = Vss

 ADCON2 = 0b10010100; //Right justified, Tad=4xacquisition time
 //conversion clock = 4Tosc

 }

 //function to read ADC channel
 unsigned int ADCRead( unsigned char ch){

 ADCON0 = 0x00;//configuring analog channel
 ADCON0 = (ch<<2); //selecting analog channel
 ADON_bit = 1; //switch on adc module
 GO_DONE_bit =1;//Start conversion

 while(GO_DONE_bit); //wait for the conversion to finish
 ADON_bit =0; //switch off adc

 return ADRES;
 }
 void main() {

 ADCInit(); //initializes adc in main program

 TRISC = 0;
 TRISB = 0x00;//putting port b as output
 PORTB = 0x00; // initial value of PORTB

 while(1){
 //always true condition. Endless loop

 unsigned int val; //adc value
 unsigned long int finalval;

 val=ADCRead(0); //read from channel 0
 finalval= (500 * val)/ 1023; // converting adc reading to celsius

 if((finalval >= 0) && (finalval <=10))
 {
  RB0_bit=1;
  RB1_bit=0;
  RB2_bit=0;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
 else if((finalval >= 11) && (finalval <=20))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=0;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
 else if((finalval >= 21) && (finalval <=30))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
  else if((finalval >= 31) && (finalval <=40))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=0;
  RB5_bit=0;
 }
  else if((finalval >= 41) && (finalval <=50))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=1;
  RB5_bit=0;
 }
 else
 {
 RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=1;
  RB5_bit=1;
  }
 }
 }

The problem in your code was mainly in these lines:

Code:
 ADCON0 = (ch<<0); //selecting analog channel
It should be
Code:
 ADCON0 = (ch<<2); //selecting analog channel

Code:
finalval= 5.00 * val * 100.00/ 1023.00; // converting adc reading to celsius
The way you've written this always produces a result of 0 as division takes place first. 100/1023 results in 0 (integer division). So finalval = 0
I fixed this to
Code:
 finalval= (500 * val)/ 1023; // converting adc reading to celsius

Hope this helps.
Tahmid.
 
Sir Tahmid,

Thank you for correcting the program sir.

I have a question sir regarding ADCON0 = (ch<<0); //selecting analog channel and ADCON0 = (ch<<2); //selecting analog channel. what i understand about ADCON0 = (ch<<0); //selecting analog channel is i am selecting channel 0 to be my ADC input. and if i used ADCON0 = (ch<<2); //selecting analog channel will be selecting channel 2 as my ADC input. looking at the data sheet channel 0 is RA0 and channel 2 is RA2, if ill used channel 0(RA0) to be my ADC input ill used ADCON0 = (ch<<0) same goes with channel 2(RA2), am i right sir? please if im wrong, do correct me sir, thanks in advance.

By the way sir, my modified code above was correctly done when i simulate it on proteus, but never been accurate when i tried it on actual components / breadboarding.
 

Take a look at the ADCON0 register in the datasheet (page 225). The selection bits are bits 2,3,4,5 and not bits 0,1,2,3. So, for selection, the channel variable is shifted 2 bits to the left, so that they are "entered" correctly in the ADCON0 register.

Hope this helps.
Tahmid.
 
Here's the fixed code:
Code:
//ADC conversion and outputting digital value on leds

 void ADCInit(){ //configuring A/D module
 ADCON1 = 0b00001110; //channels AN12-AN1 are digital and AN0 is analog
 //Vref+ = Vdd and Vref- = Vss

 ADCON2 = 0b10010100; //Right justified, Tad=4xacquisition time
 //conversion clock = 4Tosc

 }

 //function to read ADC channel
 unsigned int ADCRead( unsigned char ch){

 ADCON0 = 0x00;//configuring analog channel
 ADCON0 = (ch<<2); //selecting analog channel
 ADON_bit = 1; //switch on adc module
 GO_DONE_bit =1;//Start conversion

 while(GO_DONE_bit); //wait for the conversion to finish
 ADON_bit =0; //switch off adc

 return ADRES;
 }
 void main() {

 ADCInit(); //initializes adc in main program

 TRISC = 0;
 TRISB = 0x00;//putting port b as output
 PORTB = 0x00; // initial value of PORTB

 while(1){
 //always true condition. Endless loop

 unsigned int val; //adc value
 unsigned long int finalval;

 val=ADCRead(0); //read from channel 0
 finalval= (500 * val)/ 1023; // converting adc reading to celsius

 if((finalval >= 0) && (finalval <=10))
 {
  RB0_bit=1;
  RB1_bit=0;
  RB2_bit=0;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
 else if((finalval >= 11) && (finalval <=20))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=0;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
 else if((finalval >= 21) && (finalval <=30))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=0;
  RB4_bit=0;
  RB5_bit=0;
 }
  else if((finalval >= 31) && (finalval <=40))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=0;
  RB5_bit=0;
 }
  else if((finalval >= 41) && (finalval <=50))
 {
  RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=1;
  RB5_bit=0;
 }
 else
 {
 RB0_bit=1;
  RB1_bit=1;
  RB2_bit=1;
  RB3_bit=1;
  RB4_bit=1;
  RB5_bit=1;
  }
 }
 }

The problem in your code was mainly in these lines:

Code:
 ADCON0 = (ch<<0); //selecting analog channel
It should be
Code:
 ADCON0 = (ch<<2); //selecting analog channel

Code:
finalval= 5.00 * val * 100.00/ 1023.00; // converting adc reading to celsius
The way you've written this always produces a result of 0 as division takes place first. 100/1023 results in 0 (integer division). So finalval = 0
I fixed this to
Code:
 finalval= (500 * val)/ 1023; // converting adc reading to celsius

Hope this helps.
Tahmid.

i tried to execute this program using mikroC 2011 but i got this "error message main function is not define"... i am using PIC18f4620
sorry for my english... :)
 
It compiles fine for me. Did you select the microcontroller properly? Maybe, by mistake, you selected some other microcontroller. Did you copy-paste the code or did you make any changes? Can I see the exact code you're trying to compile?
Create a new project, paste the code and build it again. That might solve the problem.

Hope this helps.
Tahmid.
 
Take a look at the ADCON0 register in the datasheet (page 225). The selection bits are bits 2,3,4,5 and not bits 0,1,2,3. So, for selection, the channel variable is shifted 2 bits to the left, so that they are "entered" correctly in the ADCON0 register.

Hope this helps.
Tahmid.[/QUOT


hi...
i am monir. I am new here. i saw the above information. its so much helful for me. But i am facing one problem to understand the channel select register. if i use ADCON0 = (ch<<2) then how can i understand channel 0 or channel 12 will be select. can u please help me.
 

hello,
i have a program of IR remote control for pic 16f887.
Anybody please help me to convert it so that i can use it in pic 18f4520.



// Lcd pinout settings
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D4 at RD4_bit;

// Pin direction
sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D7_Direction at TRISD7_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISd4_bit;
char *text = "ER-4 Remote"; // Define message
unsigned char ir_cmd=0; // Keep Command button from ER-4 Remote
//------------------ Interrupt service routine INT -----------------//
void interrupt()
{
unsigned char i; // Keep counter
if(INTCON.INTF) // Check interrupt flag RB0 (Falling edge)
{
Delay_us(416); // Delay 1/2 of 1 bit timing
// (baudrate 1200 bps)
for(i=0;i<8;i++) // Loop 8 times for keep data from ER-4
{
Delay_us(833); // Delay of 1 bit timing
// (baudrate 1200 bps)
ir_cmd = ir_cmd>>1; // **** bit 1 time
if((PORTB & 0x01)==1) // Get logic @ RB0 = '1'?
ir_cmd = ir_cmd | 0x80; // Inset bit data is '1'
}
Delay_us(833); // Delay of 1 bit timing
// (baudrate 1200 bps)
INTCON.INTF =0; // Clear interrupt flag
}
}
//------------------ Function for get character from Remote ---------//
unsigned char get_remote()
{
unsigned char _key=ir_cmd; // Get character to buffer
ir_cmd=0; // Clear old data
return(_key); // Return character from Remote
}
//------------------ Main Program ----------------------------------//
void main()
{
unsigned char key; // Save Remote Key Press
ANSELH.F4=0; // RB0 ==> Digital IO
OPTION_REG.INTEDG = 0; // INT falling edge
INTCON.INTE =1; // Enable INT/PB0
INTCON.GIE =1; // Enable Global interrupt
Lcd_Init(&PORTD); // Initialize LCD connected to PORTD
Lcd_Cmd(Lcd_CLEAR); // Clear display
Lcd_Cmd(Lcd_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, text); // Print text to LCD,2nd row,1st column
Sound_Init(&PORTC,0);
while(1) // Infinite loop
{
key = get_remote(); // Get Remote
if(key=='a' || key=='A') // Button A press?
{
Lcd_Out(2, 1, "Button A Press "); // Display message Button A press
Sound_Play(100,500);
}
else if(key=='b' || key=='B') // Button B press?
{
Lcd_Out(2, 1, "Button B Press "); // Display message Button B press
Sound_Play(110,500);
}
else if(key=='c' || key=='C') // Button C press?
{
Lcd_Out(2, 1, "Button C Press "); // Display message Button C press
Sound_Play(120,500);
}
else if(key=='d' || key=='D') // Button D press?
{
Lcd_Out(2, 1, "Button D Press "); // Display message Button D press
Sound_Play(130,500);
}
}
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top