Hi.
I'm trying to learn ADC. I've googled and read datasheets to get started, and I thought I got pretty far, until ...
I got the 2 x 20 LCD connected right, with RS on RA3, RW on RA2, EN on RA1. D4-D7 is connected to RB0-RB3. The display is working properly.
I have a POT connected to 5vDC and GND, with the middle pin going to RA0, which is the pin I will use to read from. The problem is that I only get what seems like random characters on the LCD display. I've tried with different configuration in the ADCInit function - but with no luck.
I think my hardware is set up correctly, so that leaves the program.
Program listing:
Can anyone see any obvious errors or faults?
If so, what's wrong and how do I fix it?
I'm trying to learn ADC. I've googled and read datasheets to get started, and I thought I got pretty far, until ...
I got the 2 x 20 LCD connected right, with RS on RA3, RW on RA2, EN on RA1. D4-D7 is connected to RB0-RB3. The display is working properly.
I have a POT connected to 5vDC and GND, with the middle pin going to RA0, which is the pin I will use to read from. The problem is that I only get what seems like random characters on the LCD display. I've tried with different configuration in the ADCInit function - but with no luck.
I think my hardware is set up correctly, so that leaves the program.
Program listing:
Rich (BB code):
/*
Program : main.c
IDE : MPLAB 8.83
Compiler : Hi TECH C v9.80
PIC : PIC 18F25K22
Date : April 2012
Description : Interfaceing PIC with LCD and ADC
*/
// Include and definitions
#include <htc.h>
#include <pic18f25k22.h>
#include <stdlib.h>
#include "lcd.h"
#include "delay.h"
#define _XTAL_FREQ 4000000
// Configuration bits
#pragma config FOSC = INTIO67 // FOSC = INTIO67 Internal oscillator block
#pragma config PLLCFG = ON // PLLCFG = ON Oscillator multiplied by 4
#pragma config PRICLKEN = ON // PRICLKEN = ON Primary clock enabled
#pragma config FCMEN = OFF // FCMEN = OFF Fail-Safe Clock Monitor disabled
#pragma config IESO = OFF // IESO = OFF Oscillator Switchover mode disabled
#pragma config PWRTEN = ON // PWRTEN = ON Power up timer enabled
#pragma config BOREN = OFF // BOREN = OFF Brown-out Reset disabled in hardware and software
#pragma config WDTEN = OFF // WDTEN = OFF Watch dog timer is always disabled. SWDTEN has no effect.
#pragma config CCP2MX = PORTB3 // CCP2MX = PORTB3 CCP2 input/output is multiplexed with RB3
#pragma config PBADEN = OFF // PBADEN = OFF PORTB<5:0> pins are configured as digital I/O on Reset
#pragma config CCP3MX = PORTC6 // CCP3MX = PORTC6 P3A/CCP3 input/output is mulitplexed with RC6
#pragma config HFOFST = ON // HFOFST = ON HFINTOSC output and ready status are not delayed by the oscillator stable status
#pragma config T3CMX = PORTB5 // T3CMX = PORTB5 T3CKI is on RB5
#pragma config P2BMX = PORTC0 // P2BMX = PORTC0 P2B is on RC0
#pragma config MCLRE = EXTMCLR // MCLRE = EXTMCLR MCLR pin enabled, RE3 input pin disabled
#pragma config STVREN = OFF // STVREN = OFF Stack full/underflow will not cause Reset
#pragma config LVP = OFF // LVP = OFF Single-Supply ICSP disabled
#pragma config XINST = OFF // XINST = OFF Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
#pragma config DEBUG = OFF // DEBUG = OFF Disabled
// Global variables
unsigned char adc_value[3];
unsigned char i;
// Prototype functions
void ADCInit();
// Functions
void ADCInit(){
ADCON0 = 0b00000000;
//0 Unimplemented
//-00000-- Analog Channel Select bit,00000=AN0
//------0- A/D conversion status bit. 1=in progress
//-------0 ADC enable bit. 0=ADC disabled. 1=ADC enable
ADCON1 = 0b00000000;
//0------- Trigger select bit, 0=CCP5, 1=CTMU
//-000---- Unimplemented
//----00-- A/D VRef+ connected to internal signal
//------00 A/D Vref- connected to internal signal
ADCON2 = 0b10000111;
//1------- 0=left justify, 1=right justify
//-0------ Unpmplemented
//--000--- ADC clock source selected to Frc
//-----111 Clock from internal oscillator
}
unsigned int ADCRead(unsigned char ch){
if (ch>13) return 0; // Invalid channel
ADCON0 = (ch<<0); // Select ADC Channel
ADON=1; // Switch on the ADC module
GODONE=1; // Start conversion
while(GODONE); // Wait forthe conversion to finish
ADON=0; // Switch off ADC
return ADRES; // Return value of the ADC
}
// Main
void main(void){
OSCCON = 0x53; // Setup oscillator
CM1CON0 = 0b00000000; // Turn off comparators
CM2CON0 = 0b00000000;
ANSELA = 0b00000000; // Turn off Analog Input Control
ANSELB = 0b00000000;
ANSELC = 0b00000000;
TRISA = 0b00000000; // Setting tris register to output
TRISB = 0b00000000;
TRISC = 0b00000000;
PORTA = 0b00000000; // Setting all pins LOW
PORTB = 0b00000000;
PORTC = 0b00000000;
lcd_init(FOURBIT_MODE); // Initialize LCD in fourbit_mode
lcd_clear();
lcd_puts("ADC Test"); // String on line one
lcd_goto(0x40); // Switch to line 2
lcd_puts("Version 1"); // String on line 2
for(i=0;i<10;i++){ // Short delay. When code works, it will be
__delay_ms(10); // Changed to be a little longer
}
unsigned int val;
ADCInit(); // Initialize the ADC module
while (1) {
lcd_clear();
val = ADCRead(0);
itoa(adc_value, val, 10); // Convert int to ascill
lcd_puts(adc_value);
__delay_ms(100); // Short delay
} // End while
} // End main
If so, what's wrong and how do I fix it?