ScaleRobotics
- 6th May 2009, 19:11
I am having a heck of a time getting A/D conversion to work with the pic18f67j50. I know I am probably missing something basic from rtfm.
In desperation, I have tried to copy some C demo code (that is working on my hardware), and translate the basic setup to picbasic pro. My hardware is the Olimex PIC_LCD3310 located here http://www.olimex.com/dev/pic-lcd3310.html
I have the display working. Right now I just have an analog operator issue.
Here is my setup from the include file:
else
LIST
LIST p = 18F67J50, r = dec, w = -311, w = -230, f = inhx32
INCLUDE "P18F67J50.INC" ; MPASM Header
CONFIG XINST = OFF
CONFIG STVREN = OFF ;added
CONFIG WDTEN = OFF ;added
CONFIG CP0 = OFF ;added
CONFIG IESO = OFF ;added
CONFIG FCMEN = OFF ;added
CONFIG CCP2MX = DEFAULT ;added
CONFIG PLLDIV = 5
CONFIG WDTPS = 32768 ;was 512
CONFIG CPUDIV = OSC1
CONFIG FOSC = HSPLL
CONFIG MSSPMSK = MSK5 ;added
NOLIST
endif
And here is one of my attempts at getting A/D out of it:
DEFINE OSC 48
include "modedefs.bas"
include "LCD_3310.pbp"
TRISD = 0
PORTD.0 = 1 'turn on g sensor
PORTD.1 = 0 'select scale for g sensor
PORTD.2 = 0 'select scale for g sensor
TRISA = %00000111 'set porta.0, 1, and 2 as inputs
TRISB = 0
CM1CON = 7
CM2CON = 7
TRISC = 0
TRISE = 0
ADCON0 = %00000001 'turn on adc
ADCON1 = %00000010 'fosc/32 ??
'am I translating c language ADCON1=0x10 above correctly?
resx var word
x var word
y var word
z var word
adval var word
x=0
y=0
z=0
adval = 0
PORTD.0 = 1 'turn on g sensor (again)
'*************************************************
@bsf WDTCON,ADSHR ;set shared address SFR with WTCON<4> - is this right?
ADCON0 = %11111110 ' channel with a 0 is analog input, all others digital
@bcf WDTCON,ADSHR
ADCON1 = %10111110 'right justified, AD=20AD, A/D clock=fosc/64
ADCON0.0 = 1 'turn on adc
ADCON0.2 = 0 'channel select bit CHS0(should already be a 0)
ADCON0.3 = 0 'Channel select bit CHS1(should already be a 0)
start:
Pause 500 ' Wait .5 second
loop: ADCON0.1 = 1 'Start Conversion
adval = 0 'clear result word
notdone: pause 5
if ADCON0.1 = 1 Then notdone 'wait for low on bit-2 of ADCON0, conversion finished
adval.highbyte = ADRESH 'move HIGH byte of result to adval
adval.lowbyte = ADRESL 'move LOW byte of result to adval
ADCON0 = %00000000 'turn off adc
'Lcdout $fe, 1 'Clear screen
'Lcdout "Value: ", DEC adval 'Display the decimal value
@ PrintStr 0,0, "Z= " ;display on Nokia 3310
@ PrintVar 24,0, _adval ;display result on 3310
Pause 100 'Wait .1 second
'Goto loop 'Do it forever
End
This is an (apparently BAD) attempt at making it look almost just like:
#pragma config XINST = OFF // Extended instruction set
#pragma config STVREN = OFF // Stack overflow reset
#pragma config PLLDIV = 5 // (20 MHz crystal used on this board)
#pragma config WDTEN = OFF // Watch Dog Timer (WDT)
#pragma config CP0 = OFF // Code protect
#pragma config CPUDIV = OSC1 // OSC1 = divide by 1 mode
#pragma config IESO = OFF // Internal External (clock) Switchover
#pragma config FCMEN = OFF // Fail Safe Clock Monitor
#pragma config FOSC = HSPLL // Firmware must also set OSCTUNE<PLLEN> to start PLL!
#pragma config WDTPS = 32768
// #pragma config WAIT = OFF // Commented choices are
// #pragma config BW = 16 // only available on the
// #pragma config MODE = MM // 80 pin devices in the
// #pragma config EASHFT = OFF // family.
#pragma config MSSPMSK = MSK5
// #pragma config PMPMX = DEFAULT
// #pragma config ECCPMX = DEFAULT
#pragma config CCP2MX = DEFAULT
;---------------snip
////////////MMA pins configuration - Sleep mode disabled///////////////////////////////
TRISDbits.TRISD0=0;
PORTDbits.RD0=1;
//GS1 =0
TRISDbits.TRISD1=0;
PORTDbits.RD1=0;
//GS2=0
TRISDbits.TRISD2=0;
PORTDbits.RD2=0;
TRISAbits.TRISA0=1;
TRISAbits.TRISA1=1;
TRISAbits.TRISA2=1;
//ADC module enable
//ADCON1=0x10111110; //right-justified; AD=20AD;A/D clock=fOSC/64
ADCON0=0x01; //Enable ADC module
ADCON1=0x10;
////////////////////////MMA measure/////////////////////
resx=0;
x=0;
y=0;
z=0;
sym=0;
PORTDbits.RD0=1; //MMA SLEEP MODE disable
//************************************************** **************************
ANCON0bits.PCFG0=0; //AN0 - analog input
ADCON1=0b10111110; //right-justified; AD=20AD;A/D clock=fOSC/64
// ADCON1=0x10;
ADCON0bits.ADON=1; //Enable ADC module, AVdref, AVss
//set Z-axis measure
ADCON0bits.CHS0=0;
ADCON0bits.GO=1; //BSF ADCON0,GO ;Start conversion
while(ADCON0bits.GO); // BSC ADCON0,GO ;Is conversion done? ; GOTO $-1 ;No, test again
resz=ADRESL;
z=ADRESH;
z=(z<<8)|resz;
resz=z;
ADCON0=0x00; //stop ADC
//************************************************** **************************
If someone could point out what an idiot I am, that would be great!
Thanks!
Walter
In desperation, I have tried to copy some C demo code (that is working on my hardware), and translate the basic setup to picbasic pro. My hardware is the Olimex PIC_LCD3310 located here http://www.olimex.com/dev/pic-lcd3310.html
I have the display working. Right now I just have an analog operator issue.
Here is my setup from the include file:
else
LIST
LIST p = 18F67J50, r = dec, w = -311, w = -230, f = inhx32
INCLUDE "P18F67J50.INC" ; MPASM Header
CONFIG XINST = OFF
CONFIG STVREN = OFF ;added
CONFIG WDTEN = OFF ;added
CONFIG CP0 = OFF ;added
CONFIG IESO = OFF ;added
CONFIG FCMEN = OFF ;added
CONFIG CCP2MX = DEFAULT ;added
CONFIG PLLDIV = 5
CONFIG WDTPS = 32768 ;was 512
CONFIG CPUDIV = OSC1
CONFIG FOSC = HSPLL
CONFIG MSSPMSK = MSK5 ;added
NOLIST
endif
And here is one of my attempts at getting A/D out of it:
DEFINE OSC 48
include "modedefs.bas"
include "LCD_3310.pbp"
TRISD = 0
PORTD.0 = 1 'turn on g sensor
PORTD.1 = 0 'select scale for g sensor
PORTD.2 = 0 'select scale for g sensor
TRISA = %00000111 'set porta.0, 1, and 2 as inputs
TRISB = 0
CM1CON = 7
CM2CON = 7
TRISC = 0
TRISE = 0
ADCON0 = %00000001 'turn on adc
ADCON1 = %00000010 'fosc/32 ??
'am I translating c language ADCON1=0x10 above correctly?
resx var word
x var word
y var word
z var word
adval var word
x=0
y=0
z=0
adval = 0
PORTD.0 = 1 'turn on g sensor (again)
'*************************************************
@bsf WDTCON,ADSHR ;set shared address SFR with WTCON<4> - is this right?
ADCON0 = %11111110 ' channel with a 0 is analog input, all others digital
@bcf WDTCON,ADSHR
ADCON1 = %10111110 'right justified, AD=20AD, A/D clock=fosc/64
ADCON0.0 = 1 'turn on adc
ADCON0.2 = 0 'channel select bit CHS0(should already be a 0)
ADCON0.3 = 0 'Channel select bit CHS1(should already be a 0)
start:
Pause 500 ' Wait .5 second
loop: ADCON0.1 = 1 'Start Conversion
adval = 0 'clear result word
notdone: pause 5
if ADCON0.1 = 1 Then notdone 'wait for low on bit-2 of ADCON0, conversion finished
adval.highbyte = ADRESH 'move HIGH byte of result to adval
adval.lowbyte = ADRESL 'move LOW byte of result to adval
ADCON0 = %00000000 'turn off adc
'Lcdout $fe, 1 'Clear screen
'Lcdout "Value: ", DEC adval 'Display the decimal value
@ PrintStr 0,0, "Z= " ;display on Nokia 3310
@ PrintVar 24,0, _adval ;display result on 3310
Pause 100 'Wait .1 second
'Goto loop 'Do it forever
End
This is an (apparently BAD) attempt at making it look almost just like:
#pragma config XINST = OFF // Extended instruction set
#pragma config STVREN = OFF // Stack overflow reset
#pragma config PLLDIV = 5 // (20 MHz crystal used on this board)
#pragma config WDTEN = OFF // Watch Dog Timer (WDT)
#pragma config CP0 = OFF // Code protect
#pragma config CPUDIV = OSC1 // OSC1 = divide by 1 mode
#pragma config IESO = OFF // Internal External (clock) Switchover
#pragma config FCMEN = OFF // Fail Safe Clock Monitor
#pragma config FOSC = HSPLL // Firmware must also set OSCTUNE<PLLEN> to start PLL!
#pragma config WDTPS = 32768
// #pragma config WAIT = OFF // Commented choices are
// #pragma config BW = 16 // only available on the
// #pragma config MODE = MM // 80 pin devices in the
// #pragma config EASHFT = OFF // family.
#pragma config MSSPMSK = MSK5
// #pragma config PMPMX = DEFAULT
// #pragma config ECCPMX = DEFAULT
#pragma config CCP2MX = DEFAULT
;---------------snip
////////////MMA pins configuration - Sleep mode disabled///////////////////////////////
TRISDbits.TRISD0=0;
PORTDbits.RD0=1;
//GS1 =0
TRISDbits.TRISD1=0;
PORTDbits.RD1=0;
//GS2=0
TRISDbits.TRISD2=0;
PORTDbits.RD2=0;
TRISAbits.TRISA0=1;
TRISAbits.TRISA1=1;
TRISAbits.TRISA2=1;
//ADC module enable
//ADCON1=0x10111110; //right-justified; AD=20AD;A/D clock=fOSC/64
ADCON0=0x01; //Enable ADC module
ADCON1=0x10;
////////////////////////MMA measure/////////////////////
resx=0;
x=0;
y=0;
z=0;
sym=0;
PORTDbits.RD0=1; //MMA SLEEP MODE disable
//************************************************** **************************
ANCON0bits.PCFG0=0; //AN0 - analog input
ADCON1=0b10111110; //right-justified; AD=20AD;A/D clock=fOSC/64
// ADCON1=0x10;
ADCON0bits.ADON=1; //Enable ADC module, AVdref, AVss
//set Z-axis measure
ADCON0bits.CHS0=0;
ADCON0bits.GO=1; //BSF ADCON0,GO ;Start conversion
while(ADCON0bits.GO); // BSC ADCON0,GO ;Is conversion done? ; GOTO $-1 ;No, test again
resz=ADRESL;
z=ADRESH;
z=(z<<8)|resz;
resz=z;
ADCON0=0x00; //stop ADC
//************************************************** **************************
If someone could point out what an idiot I am, that would be great!
Thanks!
Walter