PDA

View Full Version : AD works in Porta.0 but not in porta.1



ruijc
- 18th February 2008, 12:59
Hi all,

i've sucessfuly made some programs already but i'm still in a very rookie position.

I'm working on a program ( pic 16F88 ) to read temp and save it into an external eeprom.

Here's the code and at the end the questions ;)



*****

SSPCON.5 = 0 ; Disable SSP Module
TXSTA.5 = 0 ; Disable AUSART Tx
RCSTA.7 = 0 ; Disable Serial Port


OSCCON = %01111110 'Internal RC w/ I/Os

INTCON=0

PIE1 = 0
'PIE2 = 0

PIR1 = 0 'off

CMCON= 7
CVRCON= 0 'Vref Off
CCP1CON= 0

T1CON= 0
'T2CON = %00000100

'************************************************* ****************************
'DEFINEs
'************************************************* ****************************

@ DEVICE INTRC_OSC
@ DEVICE MCLR_OFF
@ DEVICE PROTECT_OFF

DEFINE osc 4

@ DEVICE CPD_OFF
@ DEVICE LVP_OFF
@ DEVICE BOD_OFF
@ DEVICE PWRT_OFF
@ DEVICE WDT_OFF

'************************************************* ****************************
'ADC

DEFINE ADC_BITS 10 ' Set number of bits in result ( 8 or 10 bits )
DEFINE ADC_CLOCK 3 ' Set clock source (3=rc)
DEFINE ADC_SAMPLEUS 50 ' Set sampling time in uS


'************************************************* ****************************
'ADC parameters

ADCON1 =%10000000 'right justify
ANSEL =%00000101
ADCON0 =%11000001

'************************************************* ****************************

INCLUDE "modedefs.bas"

'settings for serial comm

DEFINE debug_reg PORTA
DEFINE debug_bit 1
DEFINE debug_baud 9600
DEFINE debug_mode 1

'************************************************* ****************************
'I/O's

PORTA=0
PORTB=0

TRISA=%00100101
TRISB=%00000011

'************************************************* ****************************
'PINS

temp var PORTA.0
out var PORTA.1
volt var PORTA.2
a3 var PORTA.3
A4 var PORTA.4
but1 var PORTA.5
led2 var PORTA.6
led1 var PORTA.7

but2 var PORTB.0
but3 var PORTB.1
SCL var PORTB.2
SDA var PORTB.3

green var PORTB.4
red var PORTB.5
led4 var PORTB.6
led3 var PORTB.7

************************************************** ***************************
' variables

va var word
va2 var word
tempe var word
volte var word
mem var byte
p1a var word
p1b var word
p2a var word
p2b var word
p3a var word
p3b var word
p4a var word
p4b var word
state var byte
st var word
ed var word
ADDR var word
m1 var byte
m2 var byte
m3 var byte
m4 var byte
slot var bit
w var byte
CTW VAR BYTE
km var byte
ra var word
set1 VAR BYTE
set2 VAR BYTE
rm var byte
x var byte

CLEAR

'************************************************* ****************************

mem=1
state=1
p1a=$10
p1b=$1070
p2a=$1080
p2b=$2140
p3a=$2160
p3b=$3220
p4a=$3230
p4b=$4290

'************************************************* ****************************
start:

high out
debug $0D, $0A
PAUSE 50

CTW=$A0

'************************************************* ****************************

debug "start menu",13,10

startmenu:

I2CREAD SDA,SCL,CTW,1,[m1]
I2CREAD SDA,SCL,CTW,2,[m2]
I2CREAD SDA,SCL,CTW,3,[m3]
I2CREAD SDA,SCL,CTW,4,[m4]


if (mem=1) and (m1=0) then
led1=1
led2=0
led3=0
led4=0
slot=0
endif


if (mem=1) and (m1<>0) then
pause 300
toggle led1
led2=0
led3=0
led4=0
slot=1
endif


if (mem=2) and (m2=0) then
led1=0
led2=1
led3=0
led4=0
slot=0
endif


if (mem=2) and (m2<>0) then
led1=0
pause 300
toggle led2
led3=0
led4=0
slot=1
endif


if (mem=3) and (m3=0) then
led1=0
led2=0
led3=1
led4=0
slot=0
endif


if (mem=3) and (m3<>0) then
led1=0
pause 300
led2=0
toggle led3
led4=0
slot=1
endif


if (mem=4) and (m4=0) then
led1=0
led2=0
led3=0
led4=1
slot=0
endif


if (mem=4) and (m4<>0) then
led1=0
pause 300
led2=0
led3=0
toggle led4
slot=1
endif


if state=1 then
green=0
red=1
endif

if state=2 then
green=1
red=0
endif
if state=3 then
green=1
red=1
endif



if (but1=1) and (state=1) then
gosub readmenu
endif

if (but1=1) and (state=2) then
gosub recordmenu
endif

if (but1=1) and (state=3) then
gosub erasemenu
endif


if but3=1 then
gosub memorymenu
endif


if but2=1 then
gosub statemenu
endif


goto startmenu


'*****************
recordmenu:

debug "Record Menu",13,10

if slot=1 then
goto warningmenu
endif

if mem=1 then
st=p1a
ed=p1b
endif
if mem=2 then
st=p2a
ed=p2b
endif
if mem=3 then
st=p3a
ed=p3b
endif
if mem=4 then
st=p4a
ed=p4b
endif

'******************

recordmem:

debug "2s pause before start recording",13,10
PAUSE 2000


FOR ADDR= st TO ed

for w = 0 to 15
ADCIN temp, va
va2=va + (temp>>4)
NEXT

va = (va2 */ 5000 ) >> 2
va=va/10

toggle red
pause 824
debug " Saved value: ", dec va2," - ", dec va," In position ", dec ADDR, 13,10
debug " VA2 = ", dec va2,13,10
I2CWRITE SDA,SCL,CTW,ADDR,[VA.highbyte]
pause 10
ADDR=ADDR+1
I2CWRITE SDA,SCL,CTW,ADDR,[VA.lowbyte]
pause 10
ADDR=ADDR+1
I2CWRITE SDA,SCL,CTW,mem,[addr]
if but1=1 then 'stop recording
pause 600
goto startmenu
endif
toggle led1
toggle led4
NEXT
red=1
return

'******************

erasemenu:

'*****************

eraseblock:

debug "erasing block",dec mem,13,10
red=0
I2Cread SDA,SCL,CTW,mem,[x]
debug "before in position ",dec mem," - ",dec x,13,10
I2CWRITE SDA,SCL,CTW,mem,[0]
pause 500
red=1
return

'******************

memorymenu:
if mem < 4 then
mem=mem+1
else
mem=1
endif
debug DEC mem,13,10
pause 300
return

'******************

statemenu:

if state < 3 then
state=state+1
else
state=1
endif
debug "state change - ", DEC state,13,10
pause 300
return

'******************

end




The code is mostly working but i have encountered some issues.
One of them is the eeprom ( 24LC512 ). I cant access ( read or write ) into it.
I have sucessfuly worked with this eeprom with a PIC12F675 but not with this 16F88 :(


Other issue is reading the temp sensor. If i connect the sensor into PORTa.1 i get no decent readings ( just 1 and 0 ).
But if i change ADCON0, Ansel and Trisa to porta.0 it works.

I'm guessing this is due to some bad configuration i dont know were.

This is why i'm asking you pros to help me and take some questions away.


questions:

1.How do i turn the comparator off ?
I'm guessing that CCP1CON will turn it off.
If this is right, do i still need to add CMCON ?

2. I'm using the internal osc ( with MCLR off ). The OSCCON option should be "10 = Internal RC is used for system clock".
what does the other mean ?
00 = Oscillator mode defined by FOSC<2:0>
01 = T1OSC is used for system clock


3. For AD i have seen 2 diferent ways of programing:
One where we use a line to start the conversion, a line to capture the value and another to stop the conversion.

I always used the ADCin portx,a mode to do the job.
So, for ADCON0, my way i shoud use :
"bit 0 ADON: A/D On bit - 1 = A/D converter module is operating"
and "bit 2 GO/DONE: A/D Conversion Status bit - 1 = A/D conversion in progress (setting this bit starts the A/D conversion)"
Am i right ?


For the next bits :
000 = Channel 0 (RA0/AN0)
001 = Channel 1 (RA1/AN1)
010 = Channel 2 (RA2/AN2)
011 = Channel 3 (RA3/AN3)
100 = Channel 4 (RA4/AN4)
101 = Channel 5 (RB6/AN5)
110 = Channel 6 (RB7/AN6)

this means i can only choose one channel for ADC ? What if i need 2 input channels ?


Finally the last bits:

Since i'm using the internal OSC which one should i use and why ?

bit 7-6 ADCS<1:0>: A/D Conversion Clock Select bits
If ADSC2 = 0:
00 = FOSC/2
01 = FOSC/8
10 = FOSC/32
11 = FRC (clock derived from the internal A/D module RC oscillator)
If ADSC2 = 1:
00 = FOSC/4
01 = FOSC/16
10 = FOSC/64
11 = FRC (clock derived from the internal A/D module RC oscillator)



Sorry for the long post and many questions
.

Dave
- 18th February 2008, 17:00
ruijc , You need to set ANSEL to enable the other input to be used by the A/D convertor....

Dave Purola,
N8NTA

ruijc
- 18th February 2008, 17:03
Thanks Dave ;)

I did that



ANSEL =%00000101


So this means that this line is all i need to set which and how many Analog channels to be used ?

This makes me confused because of the ADCON0 settings:
000 = Channel 0 (RA0/AN0)
001 = Channel 1 (RA1/AN1)
010 = Channel 2 (RA2/AN2)
011 = Channel 3 (RA3/AN3)
100 = Channel 4 (RA4/AN4)
101 = Channel 5 (RB6/AN5)
110 = Channel 6 (RB7/AN6)

So what does these ADCON0 settings mean ?
.

Dave
- 18th February 2008, 17:14
ruijc, You really need to read the data sheet for the part. Yes, you are right about the adcon0 register as the value you write to it will select which a/d channel will be selected, however the ansel register selects the hardware connections to the a/d multiplexer. It only needs to be written 1 time unless you are changing the port directions.

Dave Purola,
N8NTA

ruijc
- 18th February 2008, 17:24
How about not working with PORTA.1 but working with PORTA.0 ?

For PORTA.1 this is what i used diferent:



ANSEL =%00000110
ADCON0 =%11001001
TRISA =%00100110


This way it should work, right ? But it doesnt :(

And how about the external eeprom ?
I have connected this eeprom the same way as i connected to a pic12F675 but for the pic16F88 is not working.

Do i need to do something diferent ?
I've done some searches and some recomend to use the IC slow line, but this eeprom is high speed one and does not require that line.

Any ideas ?

.

Dave
- 19th February 2008, 17:59
ruijc, Here, Try this as it is known working code....


@ __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
@ __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

DEFINE OSC 20
DEFINE NO_CLRWDT 1

************************************************** ******************
' Declare Port Variables
' ************************************************** ******************
ANA0 VAR PORTA.0 '1-1st PRESSURE SENSOR INPUT (MAIN SENSOR)
ANA1 VAR PORTA.1 '1-2nd PRESSURE SENSOR INPUT (SPARE SENSOR INPUT)

************************************************** ******************
' Declare Variables
' ************************************************** ******************
ADREADS VAR WORD 'A/D READINGS (0-4095)
CHANNEL VAR BYTE 'A/D CHANNEL TO ACCESS
SCRATCH VAR BYTE 'SCRATCH VARIABLE

************************************************** ******************
' SYSTEM INITIALIZATION
' ************************************************** ******************
TRISA = %10100011 'INITIALIZE PORT DIRECTIONS
TRISB = %00000000
OSCCON = 0 'SET SYSTEM CLOCK SWITCH BIT
INTCON = %00000000 'CLEAR GIE,PEIE,TMR0IE,INTE,RBIE,TMR0IF,INTF,RBIF
PIE1 = %00000000 'CLEAR ALL INTERRUPT ENABLE BITS
PIR1 = %00000000 'CLEAR ALL INTERRUPT FLAGS
PIE2 = %00000000 'CLEAR ALL INTERRUPT ENABLE BITS
PIR2 = %00000000 'CLEAR ALL INTERRUPT FLAGS
ANSEL = %00000011 'AN0,AN1 ANALOG INPUTS, AN2:AN6 DIGITAL
ADCON0 = %10000001 'FOSC/64,CHS2:0,GO/DONE,ADON
ADCON1 = %11000000 'RIGHT JUSTIFIED,ADSC2,VCFG
CMCON = %00000111 'CLEAR/DISABLE COMPARATOR
CVRCON = %00000000 'DISABLE COMPARATOR VOLTAGE REFERENCE
OPTION_REG = %10000000 'CLEAR ALL PULL-UPS,INTEDG,T0CS,T0SE,PSA,PS
T1CON = %00000000 'PRESCALER 1/1,STOP TIMER 1
T2CON = %00000000 'POSTSCALER 1/1,STOP,PRESCALER 1/1
CCP1CON = %00000000 'PLACE CCP1 INTO DISABLE MODE
TMR2 = 0 'CLEAR TMR2 MODULE REGISTER
PR2 = $FF 'SET PERIOD (1/1 PRESCALE * 256 PR2 * 1/20,000,000 * 4 = 19.53 Khz.
CCPR1L = $00 'CLEAR LOWER 8 BITS
CCPR1H = $00 'CLEAR UPPER 2 BITS
SSPCON = %00000000 'PLACE SSP INTO DISABLE MODE
SPBRG = 0 'SET LOW BYTE OF BAUD GENERATOR
RCSTA = %00000000 'DISABLE RECEIVER,CONTINUOUS
TXSTA = %00000000 'DISABLE TRANSMIT,HIGH BAUD

' INTERBIT = INTCON.7 'SAVE STATUS OF INTERRUPT ENABLE BIT
' INTCON.7 = 0 'DISABLE ALL INTERRUPTS
' INTCON.7 = INTERBIT 'RE-ENABLE ALL INTERRUPTS

GOTO COLD

'************************************************* *******************' Subroutines
'************************************************* *******************READAD: 'READ ALL A/D INPUT CHANNELS FROM CONTROLLER
'************************************************* *******************
CHANNEL = 0
WHILE CHANNEL < 2
ADCON0 = $81 | (CHANNEL << 3) ' Set A/D to Fosc/64, Channel X, On
PAUSEUS 40
ADCON0.2 = 1 ' START CONVERSION
NDONE:
while ADCON0.2 = 1 ' WAIT FOR 10 BIT CONVERSION TO COMPLETE
wend

volts(channel) = (((ADRESH & $3) << 8) + ADRESL) 'BUILD SENSOR WORD
CHANNEL = CHANNEL + 1
WEND
RETURN

Cold:


Dave Purola
N8NTA

ruijc
- 19th February 2008, 20:22
Hi Dave,

first of all, thanks for the help.

Will take your code and test on my workbench tonight ;)

.