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.

ADC implementation in PIC18LF4550

Status
Not open for further replies.

Akhil Mohan

Member level 2
Joined
May 13, 2011
Messages
53
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
1,731
Hello all,
I am trying to use the ADC of 18LF4550 to display the analog voltage levels on an 16x2LCD. My code is compiling giving me an out,
ADC OUT =
0000
This is not varying as I change the pot. (1k pot used, variable to AN2, one leg to supply, and another leg to GND).
Can you help me to identify the mistake in my code (LCD part is working fine, and there is no error there) ?
Code:
#include <p18f4550.h>
#include <delays.h>
#include <htc.h>

#define rs LATCbits.LATC0
#define rw LATCbits.LATC1
#define en LATCbits.LATC2

#define _XTAL_FREQ 20000000

__CONFIG (1, FOSC_HS);
__CONFIG (2, WDTDIS & PWRTEN & BORDIS & LVPDIS);

void lcd_init(void);
void disp(unsigned int);
void commd(unsigned int);
void adc_init();
void readADC(unsigned int);
void adc_conv(unsigned int);
void Delay10KTCYx(unsigned char unit);
void Delay1KTCYx(unsigned char unit);

unsigned char out[20]="ADC OUT=";
unsigned int count = 0;
unsigned int result;

void main(void)
{
TRISA = 0x04;
LATA = 0x00;
TRISC = 0x00;
LATC = 0x00;
TRISD = 0x00;
LATD = 0x00;
TRISE = 0x00;
LATE = 0x00;

Delay10KTCYx(200);
lcd_init();
while(out[count]!='\0')
{
disp(out[count]);
count++;
}
adc_init();
while (1)
{
readADC(result);
adc_conv(result);// Function to convert the decimal vaule to its corresponding ASCII
Delay1KTCYx (240);
}
}

void adc_init()
{
// configure A/D convertor
ADCON0bits.ADON = 0; // Disable A/D module
ADCON1 = 0x0C;
//Read port AN2
ADCON0bits.CHS0 = 0;
ADCON0bits.CHS1 = 1;
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS3 = 0;
//Set FOSC/32
ADCON2bits.ADCS0 = 0;
ADCON2bits.ADCS1 = 1;
ADCON2bits.ADCS2 = 0;
// Acquisition time (2TAD)
ADCON2bits.ACQT0 = 1;
ADCON2bits.ACQT1 = 0;
ADCON2bits.ACQT2 = 0;
TRISAbits.TRISA2 = 1; // input
ADCON0bits.ADON = 1; //Turn on ADC
}

void readADC(unsigned int result)
{
Delay10KTCYx( 5 ); // Delay for 50TCY
ADCON0bits.GO = 1; // Code for starting A/D conversion
while (ADCON0bits.GO!= 0); // Wait until the A/D conversion is over
PORTE = ADRESH;
result = ADRESH;
Delay1KTCYx (240);
}

void adc_conv(unsigned int result)
{
unsigned int result_new;
int i = 0;
char position = 0xC0;
for(i=0; i<=3; i++)
{
result_new = result%10; // To exract the unit position digit
result = result/10;
commd(position);
disp(48 + result_new); // Convert into its corresponding ASCII
position++;
}
}
void lcd_init(void)
{
en = 0;
rs = 0;
rw = 0;

Delay10KTCYx( 10 );

commd(0x33); // Set interface to 8-bit
Delay10KTCYx( 5 );  

commd( 0x33 ); // Set interface to 8-bit
Delay10KTCYx( 1 );   

commd( 0x33 ); // Set interface to 8-bit
Delay10KTCYx( 1 );   

commd( 0x28 ); // Set interface to 4-bit

commd( 0x28 ); // Function Set

commd(0x0C); // Display On and Cursor Off

commd(0x01); // Clear display screen
Delay10KTCYx( 5 );  

commd(0x06); // Increment cursor

}

void disp(unsigned int character)
{

PORTD=character >> 4;

rs = 1;
rw = 0;
en = 1;
en = 0;

PORTD=character & 0x0f;

rs = 1;
rw = 0;
en = 1;
en = 0;

Delay1KTCYx(1);

}

void commd(unsigned int commd)
{

PORTD=commd >> 4;
rs = 0;
rw = 0;
en = 1;
en = 0;

PORTD=commd &0x0f;
rs = 0;
rw = 0;
en = 1;
en = 0;

Delay1KTCYx(1);

}

Thanks in advance,
Akhil
 

Hi,
I think there are multiple problems in this code.
1. you should either pass 'result' variable to readADC via reference or using pointer or you can make readADC return the result.
2. I guess there is a problem in ADC result format
as you are using ADRESH register only, you should set ADCON2.ADFM bit (make the result right justified) as it's 0 (left justified) on reset. Because if result format is left-justified and your temperature is less than 256, there will always be 0 in ADRESH.

plus i think there is some problem in your conversion to ascii logic. bcoz ... suppose temp value is 37, this logic will print 73 ..
you probably should revise this logic too

hope it helps
 

Thanks Shihab for your suggestion, last day I got the output and as you told there was few mistakes (declaration errors) and I corrected it :)
 

Check out this article, although it uses a diferent PIC but it should work for u as well:
**broken link removed**

Thanks for sharing this, a nice article to read :)
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top