hi
m trying to read two adcs together using PIC16F877A ( 6 adc inputs
have to be read at a time so i have taken adcon1 = 10001001) . but for
testing purpose only intitailly m giving +5v to AN0 and 0V to AN1 and
on display m getting 05 for AN0 and 0000 for AN1. if i give +5 v to
both the input pins of adc ...i get 1023 and 1023.
m sending the full code. i have used nigel's code and edited it .please
help me out to find tHe error.
m trying to read two adcs together using PIC16F877A ( 6 adc inputs
have to be read at a time so i have taken adcon1 = 10001001) . but for
testing purpose only intitailly m giving +5v to AN0 and 0V to AN1 and
on display m getting 05 for AN0 and 0000 for AN1. if i give +5 v to
both the input pins of adc ...i get 1023 and 1023.
m sending the full code. i have used nigel's code and edited it .please
help me out to find tHe error.
Code:
;Tutorial 11_1
;Reading an analogue input, and displaying it on the LCD
;Nigel Goodwin 2004
; Device 16F876
LIST p=16F877A, W=2, X=ON, R=DEC ;tell assembler what chip we are using
include "P16F877A.inc" ;include the defaults for the chip
ERRORLEVEL 0, -302 ;suppress bank selection messages
__CONFIG 0x393A ;sets the configuration settings (oscillator type etc.)
cblock 0x20 ;start of general purpose registers
count
count1
counta
countb
LoX
Bit_Cntr
Timer_H
Flags
Flags2
tmp1
tmp2
tmp3
NumL
NumH
V1N_HIGH
V1N_LOW
V2N_HIGH
V2N_LOW
V3N_HIGH
V3N_LOW
TenK
Thou
Hund
Tens
Ones
templcd
templcd2
Acc1L ;16 bit maths register 1
Acc1H
Point ;position of decimal point
endc
LCD_PORT Equ PORTD
LCD_TRIS Equ TRISD
LCD_RS Equ 0x05 ;LCD handshake lines
LCD_RW Equ 0x06
LCD_E Equ 0x07
LEADZ Equ 0x00 ;set to display leading zeros
;start of program
ORG 0x0000
NOP
BCF PCLATH, 3
BCF PCLATH, 4
GOTO Initialise
ORG 0x0004
RETURN
ORG 0x0005
Initialise clrf count
clrf PORTA
clrf PORTD
clrf PORTC
clrf Flags
BANKSEL ADCON1 ;disable A2D
movlw 0x06
movwf ADCON1
BANKSEL PORTA
;variables for decimal numbers display
bsf Flags, LEADZ ;show leading zeros
movlw 0x00 ;set decimal point position to zero (none)
movwf Point
CLRF NumL
CLRF NumH
CLRF V1N_HIGH
CLRF V1N_LOW
CLRF V2N_HIGH
CLRF V2N_LOW
CLRF V3N_HIGH
CLRF V3N_LOW
SetPorts bsf STATUS, RP0 ;select bank 1
movlw 0x00 ;make all LCD pins outputs
movwf LCD_TRIS
bcf STATUS, RP0 ;select bank 0
call LCD_Init ;setup LCD module
call LCD_CurOff ;turn cursor off
call Init_ADC ;initialise analogue input
Main
CLRF NumL
CLRF NumH
CALL Init_ADC0
call Read_ADC ;read analogue input
movfw NumH
movwf V1N_HIGH
movfw NumL
movwf V1N_LOW
;CALL Delay50
CLRF NumL
CLRF NumH
CALL Init_ADC1
call Read_ADC ;read analogue input
movfw NumH
movwf V2N_HIGH
movfw NumL
movwf V2N_LOW
;CALL Delay50
CLRF NumL
CLRF NumH
movf V1N_HIGH,W
movwf NumH
movf V1N_LOW,W
movwf NumL
movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
call LCD_Decimal ;and display on LCD (in decimal)
movlw ' '
call LCD_Char ;display a space
nop
nop
movf V2N_HIGH,W
movwf NumH
movf V2N_LOW,W
movwf NumL
movlw 0x85 ;move to 1st row, first column
call LCD_Cmd
call LCD_Decimal ;and display on LCD (in decimal)
movlw ' '
call LCD_Char ;display a space
nop
nop
call Delay255 ;delay to give 10 readings per second
call Delay255
call Delay255
call Delay255
call Delay255
goto Main ;loop for ever
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Init_ADC0
; Set ADCON0
clrf W
clrf NumH
clrf NumL
movlw b'10000001'
movwf ADCON0
; Set ADCON1
BANKSEL ADCON1
movlw b'10001001'
movwf ADCON1
BANKSEL ADCON0
return
Init_ADC1
; Set ADCON0
clrf W
clrf NumH
clrf NumL
movlw b'10001001'
movwf ADCON0
; Set ADCON1
BANKSEL ADCON1
movlw b'10001001'
movwf ADCON1
BANKSEL ADCON0
return
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Init_ADC
; Set ADCON1
BANKSEL ADCON1
movlw b'10001001'
movwf ADCON1
BANKSEL ADCON0
return
Read_ADC
bsf ADCON0, GO_DONE ;initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ;wait for ADC to finish
movf ADRESH,W
andlw 0x03
movwf NumH
BANKSEL ADRESL
movf ADRESL,W
BANKSEL ADRESH
movwf NumL ;return result in NumL and NumH
;bcf STATUS, C
;bcf STATUS, DC
;bcf STATUS, Z
return
;TABLES
HEX_Table addwf PCL , f
retlw 0x30
retlw 0x31
retlw 0x32
retlw 0x33
retlw 0x34
retlw 0x35
retlw 0x36
retlw 0x37
retlw 0x38
retlw 0x39
retlw 0x41
retlw 0x42
retlw 0x43
retlw 0x44
retlw 0x45
retlw 0x46
Xtext addwf PCL, f
retlw 'T'
retlw 'u'
retlw 't'
retlw 'o'
retlw 'r'
retlw 'i'
retlw 'a'
retlw 'l'
retlw ' '
retlw '1'
retlw '1'
retlw '.'
retlw '1'
retlw 0x00
;end of tables
String1 clrf count ;set counter register to zero
Mess1 movf count, w ;put counter value in W
call Xtext ;get a character from the text table
xorlw 0x00 ;is it a zero?
btfsc STATUS, Z
retlw 0x00 ;return when finished
call LCD_Char
incf count, f
goto Mess1
;LCD routines
;Initialise LCD
LCD_Init call LCD_Busy ;wait for LCD to settle
movlw 0x20 ;Set 4 bit mode
call LCD_Cmd
movlw 0x28 ;Set display shift
call LCD_Cmd
movlw 0x06 ;Set display character mode
call LCD_Cmd
movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd ;Set cursor off
call LCD_Clr ;clear display
retlw 0x00
; command set routine
LCD_Cmd movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_CharD addlw 0x30 ;add 0x30 to convert to ASCII
LCD_Char movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call LCD_Busy
retlw 0x00
LCD_Line1 movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
retlw 0x00
LCD_Line2 movlw 0xc0 ;move to 2nd row, first column
call LCD_Cmd
retlw 0x00
LCD_Line1W addlw 0x80 ;move to 1st row, column W
call LCD_Cmd
retlw 0x00
LCD_Line2W addlw 0xc0 ;move to 2nd row, column W
call LCD_Cmd
retlw 0x00
LCD_CurOn movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_CurOff movlw 0x0c ;Set display on/off and cursor command
call LCD_Cmd
retlw 0x00
LCD_Clr movlw 0x01 ;Clear display
call LCD_Cmd
retlw 0x00
LCD_HEX movwf tmp1
swapf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
movf tmp1, w
andlw 0x0f
call HEX_Table
call LCD_Char
retlw 0x00
Pulse_e bsf LCD_PORT, LCD_E
nop
bcf LCD_PORT, LCD_E
retlw 0x00
LCD_Busy
bsf STATUS, RP0 ;set bank 1
movlw 0x0f ;set Port for input
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
bcf LCD_PORT, LCD_RS ;set LCD for command mode
bsf LCD_PORT, LCD_RW ;setup to read busy flag
bsf LCD_PORT, LCD_E
swapf LCD_PORT, w ;read upper nibble (busy flag)
bcf LCD_PORT, LCD_E
movwf templcd2
bsf LCD_PORT, LCD_E ;dummy read of lower nibble
bcf LCD_PORT, LCD_E
btfsc templcd2, 7 ;check busy flag, high = busy
goto LCD_Busy ;if busy check again
bcf LCD_PORT, LCD_RW
bsf STATUS, RP0 ;set bank 1
movlw 0x00 ;set Port for output
movwf LCD_TRIS
bcf STATUS, RP0 ;set bank 0
return
LCD_Decimal
call Convert
;btfsc Flags, LEADZ
goto LCD_THOU
;movf TenK, w
;btfss STATUS, Z
;goto LCD_TENK
movf Thou, w
btfss STATUS, Z
goto LCD_THOU
movf Hund, w
btfss STATUS, Z
goto LCD_HUND
movf Tens, w
btfss STATUS, Z
goto LCD_TENS
goto LCD_ONES
LCD_TENK
movlw 0x05 ;test if decimal point 5
subwf Point, w
btfss STATUS , Z
goto NO_DP5
movlw '.'
call LCD_Char ;display decimal point
NO_DP5 movf TenK, w
call LCD_CharD
movlw 0x04 ;test if decimal point 4
subwf Point, w
btfss STATUS , Z
goto LCD_THOU
movlw '.'
call LCD_Char ;display decimal point
LCD_THOU
movf Thou, w
call LCD_CharD
movlw 0x03 ;test if decimal point 3
subwf Point, w
btfss STATUS , Z
goto LCD_HUND
movlw '.'
call LCD_Char ;display decimal point
LCD_HUND
movf Hund, w
call LCD_CharD
movlw 0x02 ;test if decimal point 2
subwf Point, w
btfss STATUS , Z
goto LCD_TENS
movlw '.'
call LCD_Char ;display decimal point
LCD_TENS
movf Tens, w
call LCD_CharD
movlw 0x01 ;test if decimal point 1
subwf Point, w
btfss STATUS , Z
goto LCD_ONES
movlw '.'
call LCD_Char ;display decimal point
LCD_ONES
movf Ones, w
call LCD_CharD
return
;end of LCD routines
;Delay routines
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (20 MHz clock)
d0 movwf count1
d1 movlw 0xE7
movwf counta
movlw 0x04
movwf countb
Delay_0 decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
retlw 0x00
;end of Delay routines
;This routine downloaded from http://www.piclist.com
Convert: ; Takes number in NumH:NumL
; Returns decimal in
; TenK:Thou:Hund:Tens:Ones
swapf NumH, w
iorlw B'11110000'
movwf Thou
addwf Thou,f
addlw 0XE2
movwf Hund
addlw 0X32
movwf Ones
movf NumH,w
andlw 0X0F
addwf Hund,f
addwf Hund,f
addwf Ones,f
addlw 0XE9
movwf Tens
addwf Tens,f
addwf Tens,f
swapf NumL,w
andlw 0X0F
addwf Tens,f
addwf Ones,f
rlf Tens,f
rlf Ones,f
comf Ones,f
rlf Ones,f
movf NumL,w
andlw 0X0F
addwf Ones,f
rlf Thou,f
movlw 0X07
movwf TenK
; At this point, the original number is
; equal to
; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
; if those entities are regarded as two's
; complement binary. To be precise, all of
; them are negative except TenK. Now the number
; needs to be normalized, but this can all be
; done with simple byte arithmetic.
movlw 0X0A ; Ten
Lb1:
addwf Ones,f
decf Tens,f
btfss 3,0
goto Lb1
Lb2:
addwf Tens,f
decf Hund,f
btfss 3,0
goto Lb2
Lb3:
addwf Hund,f
decf Thou,f
btfss 3,0
goto Lb3
Lb4:
addwf Thou,f
decf TenK,f
btfss 3,0
goto Lb4
retlw 0x00
end