![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| Considered a higher level programming language such as Proton? Code: Result = ADIN 0 Result = Result * 5 / 1023 Select Result Case >= 3.000 LED_1 = 1 Case 1.700 To 2.999 LED_1 = 0 Case < 1.700 LED_1 = 1 EndSelect
__________________ Spency. PIC Micro's - Your mind is the limit PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net | |
| |
| | (permalink) |
| Can anyone go over this code, and tell me if I'm on right track. I tried the MPLAB simulator, but I am at a loss when it comes to (stimulus functions). This code was partially copied from Pommie(thanks), and I hope it is well implemented. All it does is read AN0 and AN1, and compare the results to < than or > than a certain value, and if out of range, LED goes on GP5. If in range LED stays off. I hope code OK. May need some tweaking. I know it's been a while since original post, but my family and work, are also a priority. Here it is, Code: list p=12f675 ; list directive to define processor
#include <p12f675.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
;***** VARIABLE DEFINITIONS
Word equ 0x30
;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program
ORG 0x004 ; interrupt vector location
; isr code can go here or be located as a call subroutine elsewhere
; these first 4 instructions are not required if the internal oscillator is not used
main
call 0x3FF ; retrieve factory calibration value
bsf STATUS,RP0 ; set file register bank to 1
movwf OSCCAL ; update register with factory cal value
bcf STATUS,RP0 ; set file register bank to 0
;*******************************************************************************************************
;************************************** Begining of application code *********************************
;*******************************************************************************************************
portsetup
; ensure Bank "0" is previously selected
clrf GPIO ; clear GPIO
; the default chip configuration upon start up, or reset, is analogue input on GP0, GP1, GP2 and GP4
; to alter this configuration, next 2 instructions are necessary, customize per your application.
movlw 03h ; move literal 03h working register
movwf ANSEL ; move working register to file ANSEL, setting GP2 as digital input and GP1 and GP0 as analogue input.
movlw 07h ; move literal to working register
movwf CMCON ; turn comparators off as they are not used here
bsf STATUS, RP0 ; switch to Bank "1" to set up ports
movlw 0Bh ; move literal to working register, 0Bh (001011b) (1 = input, 0 = output)
movwf TRISIO ; move working register value to TRISIO setting GP3, GP1 and GP0, as inputs, and GP2, GP4 and GP5, as digital outputs.
bcf STATUS, RP0 ; return to Bank "0"
start
nop ; small delay to settle micro
nop
nop
nop
nop
btfss GPIO,3 ; check to see if PTO is engaged.(high) if set then skip next instruction
goto start ; if not set, loop back to start
call Init_ADC0
call Read_ADC1
nop
nop
nop
call result
nop
nop
nop ; small delay to settle micro
btfss GPIO,3 ; check to see if PTO is engaged.(high) if set then skip next instruction
goto start ; if not set, loop back to start
call Init_ADC1
nop
nop
nop
call Read_ADC2
nop
nop
nop
call result
goto start
Init_ADC0 ;set for AN0
; Set ADCON0
movlw b'10000001'
movwf ADCON0 ; bit 7 is set meaning results will be right justified, and bit 0 is also set, meaning A/D module is operating. no other bit are set so Channel 00 for AN0 will be read.
; Set ADCON1
BANKSEL ANSEL
movlw b'10100001'
movwf ANSEL ; bit 7 is set, but is unimplemented. bit 0 is set, meaning GP0(AN0) is assigned as an analogue input.
BANKSEL ADCON0 ; switch to bank 0.
return
Init_ADC1 ; set for AN1
; Set ADCON0
movlw b'10000101'
movwf ADCON0 ; bit 7 is set meaning results will be right justified, and bit 0 is also set, meaning A/D module is operating. bit 2 is set, meaning Channel 01 for AN1 is ready for reading.
; Set ADCON1
BANKSEL ANSEL
movlw b'10100101'
movwf ANSEL ; bit 7 is set, but is unimplemented. bit 0 and 2 are set, meaning GP0(AN0) and GP2(AN1), are assigned as an analogue input.
BANKSEL ADCON0
return
Read_ADC1 ; read CHS0 ( channel 0)
bsf ADCON0, GO_DONE ; initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ; wait for ADC to finish
movf ADRESH,W ; move results from ADRESH file to W
movwf Word ; move value from W to file named Word
BANKSEL ADRESL ; switch to bank 1
movf ADRESL,W ; move results from ADRESL file to W
movwf Word+1 ; move value from W to file named Word and add 1
return
Read_ADC2 ; read CHS1 (channel 1)
bsf ADCON0, GO_DONE ; initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ; wait for ADC to finish
movf ADRESH,W ; move results from ADRESH file to W
movwf Word ; move value from W to file named Word
BANKSEL ADRESL ; switch to bank 1
movf ADRESL,W ; move results from ADRESL file to W
movwf Word+1 ; move value from W to file named Word and add 1
return
result
movlw low(0x015B) ; load W with value of low 0x15
subwf Word,W ; subtract value in file Word, with value in W
movlw high(0x015B) ; load W with value of 0x15
btfss STATUS,C ; check to see if bit "C", in Status is set.
movlw high(0x015B)+1 ; load W with value high 0x15 and add 1
subwf Word+1,W ; subtract value in file Word, with value in W
btfss STATUS,C ; carry clear if word is less than 0x15B
call LEDoff
movlw low(0x0266)
subwf Word,W
movlw high(0x0266)
btfss STATUS,C
movlw high(0x0266)+1
subwf Word+1,W
btfsc STATUS,C ; carry set if word is greater or equal to 0x266
call LEDon
goto start
; turn LED off here
LEDon
bsf GPIO,5 ; set bit 5 of GPIO register to 1 (high)
return
LEDoff
bcf GPIO,5 ; set bit 5 of GPIO register to 0 (low)
return
; initialize eeprom locations
ORG 0x2100
DE 0x00, 0x01, 0x02, 0x03
END ; directive 'end of program' | |
| |
| | (permalink) |
| I would suggest to configure the ansel register at the beginnig only. Code: movlw b'00010011'
movwf ANSEL | |
| |
| | (permalink) | |
| Quote:
| ||
| |
| | (permalink) |
| It seems that you can select a channel without turning the ADC off, but a minimum delay is reqiuired. I'm reading AN546. | |
| |
| | (permalink) |
| Yes it is what I thought, as App notes state that after read and conversion done, GO_DONE bit is cleared. as for delay, 5micro secs should do it? Right? P.S. thanks for the help, eng1. | |
| |
| | (permalink) |
| Ok so I modified my code, so ANSEL at the beginning of portsetup, is only time ANSEL is setup. | |
| |
| | (permalink) |
| You need to change the comparison slightly. What it is doing at the moment is checking if the voltage is less than 1.7V and if it is then turn on LED. It then returns, because of the call, and checks if it's less than 3.0V which it will be as 1.7 is less than 3.0 so it turns it off again. Try changing the code to, Code: result
movlw low(0x015B) ; load W with value of low 0x15
subwf Word,W ; subtract value in file Word, with value in W
movlw high(0x015B) ; load W with value of 0x15
btfss STATUS,C ; check to see if bit "C", in Status is set.
movlw high(0x015B)+1 ; load W with value high 0x15 and add 1
subwf Word+1,W ; subtract value in file Word, with value in W
btfss STATUS,C ; carry clear if word is less than 0x15B
goto LEDon ; <-----changed
movlw low(0x0266)
subwf Word,W
movlw high(0x0266)
btfss STATUS,C
movlw high(0x0266)+1
subwf Word+1,W
btfsc STATUS,C ; carry set if word is greater or equal to 0x266
goto LEDon ; <------changed
; goto start <------removed
; turn LED off here
LEDoff ; <-------moved
bcf GPIO,5 ; set bit 5 of GPIO register to 0 (low)
goto start ; <-------changed
LEDon
bsf GPIO,5 ; set bit 5 of GPIO register to 1 (high)
goto start ; <-------changed Mike. | |
| |
| | (permalink) |
| Thanks Pommie, It needed some straightening out. I will try and see if it works. | |
| |
| | (permalink) |
| Also, I noticed you don't allow a delay for the ADC acquisition time. I posted some code in this thread that shows how to read the ADC. Mike. | |
| |
| | (permalink) |
| Here is code modified. Pommie, you will probably recognize a lot of your work. Please go over this, as it compiles well for asm. Code:
Init_ADC0 ;set for AN0
; Set ADCON0
movlw b'10000001'
movwf ADCON0 ; bit 7 is set meaning results will be right justified, and bit 0 is also set, meaning A/D module is operating. no other bit are set so Channel 00 for AN0 will be read.
return
Init_ADC1 ; set for AN1
; Set ADCON0
movlw b'10000101'
movwf ADCON0 ; bit 7 is set meaning results will be right justified, and bit 0 is also set, meaning A/D module is operating. bit 2 is set, meaning Channel 01 for AN1 is ready for reading.
return
Read_ADC1
call delay1 ; small delay for A/D aquisition time.
; read CHS0 ( channel 0)
bsf ADCON0, GO_DONE ; initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ; wait for ADC to finish
movf ADRESH,W ; move results from ADRESH file to W
movwf Word ; move value from W to file named Word
BANKSEL ADRESL ; switch to bank 1
movf ADRESL,W ; move results from ADRESL file to W
movwf Word+1 ; move value from W to file named Word and add 1
nop
nop
nop
return
Read_ADC2
call delay1 ; small delay for A/D aquisition time.
; read CHS1 (channel 1)
bsf ADCON0, GO_DONE ; initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ; wait for ADC to finish
movf ADRESH,W ; move results from ADRESH file to W
movwf Word ; move value from W to file named Word
BANKSEL ADRESL ; switch to bank 1
movf ADRESL,W ; move results from ADRESL file to W
movwf Word+1 ; move value from W to file named Word and add 1
nop
nop
nop
return
result
movlw low(0x015B) ; load W with value of low 0x15
subwf Word,W ; subtract value in file Word, with value in W
movlw high(0x015B) ; load W with value of 0x15
btfss STATUS,C ; check to see if bit "C", in Status is set.
movlw high(0x015B)+1 ; load W with value high 0x15 and add 1
subwf Word+1,W ; subtract value in file Word, with value in W
btfss STATUS,C ; carry clear if word is less than 0x15B
call LEDon
movlw low(0x0266)
subwf Word,W
movlw high(0x0266)
btfss STATUS,C
movlw high(0x0266)+1
subwf Word+1,W
btfsc STATUS,C ; carry set if word is greater or equal to 0x266
goto LEDon
; turn LED off here
LEDoff
bcf GPIO,5 ; set bit 5 of GPIO register to 0 (low)
goto start
LEDon
bsf GPIO,5 ; set bit 5 of GPIO register to 1 (high)
goto start
delay1 ; will delay W*8 cycles including the call/return
addlw 0xff ; add -1 to W 1
btfsc STATUS,Z ; =zero? 1/2
goto DoneDelay ; yes, better get out of here 2
nop ; delay a bit 1
goto $+1 ; delay a bit more 2
goto delay1 ; go around again 2
DoneDelay return ; 2 | |
| |
| | (permalink) |
| One little problem, the delay routine requires a value in W so put a movlw 5 before the call. The 5 assumes you have a low impedance source, if you get incorrect readings then change the 5 to something bigger. Apart from that it looks fine. Does it work? Mike. | |
| |
| | (permalink) |
| I will keep you posted, and will add value to W for delay. I should know by early afternoon if it works. Thanks for all the help. | |
| |
| | (permalink) |
| Properly selecting Banks in portsetup would help. But it didn't help. I'm still wondering what is wrong, and maybe 2V on AN0 or 1.5V on AN1 isn't enough. I will try opamp LM358 or similar. LED does not light up. OH well, it's Sunday after all. | |
| |
| | (permalink) |
| It's been a week, and I think I finally got it. Here is code, and again if it looks like you can improve on it, let me know. Code: ;***** VARIABLE DEFINITIONS
Word equ 0x30
;**********************************************************************
ORG 0x000 ; processor reset vector
goto main ; go to beginning of program
ORG 0x004 ; interrupt vector location
; isr code can go here or be located as a call subroutine elsewhere
; these first 4 instructions are not required if the internal oscillator is not used
main
call 0x3FF ; retrieve factory calibration value
bsf STATUS,RP0 ; set file register bank to 1
movwf OSCCAL ; update register with factory cal value
bcf STATUS,RP0 ; set file register bank to 0
;*******************************************************************************************************
;************************************** Begining of application code *********************************
;*******************************************************************************************************
portsetup
bcf STATUS, RP0 ; ensure Bank "0" is previously selected
; The default chip configuration upon start up, or reset of 12f675, is analogue input on GP0, GP1, GP2 and GP4
; to alter this configuration, next 2 instructions are necessary, customize per your application.
movlw 07h ; move literal to working register
movwf CMCON ; turn comparators off as they are not used here
bsf STATUS, RP0 ; switch to Bank "1" to set up analogue ports
movlw 03h ; move literal 03h working register
movwf ANSEL ; move working register to file ANSEL, setting GP1 and GP0 as analogue input.
movlw 0Bh ; move literal to working register, 0Bh (001011b) (1 = input, 0 = output)
movwf TRISIO ; move working register value to TRISIO setting GP3, GP1 and GP0, as inputs, and GP2, GP4 and GP5, as digital outputs.
bcf STATUS, RP0 ; return to Bank "0"
start
nop ; small delay to settle micro
nop
nop
nop
nop
btfss GPIO,3 ; check to see if PTO is engaged.(high) if set then skip next instruction
goto start ; if not set, loop back to start
call Init_ADC0
call Read_ADC0
nop
nop
BANKSEL GPIO ; this is necessary only if control of pins,(such as outputs) on GPIO5 is needed after reading A/D.
call result
nop
nop
nop ; small delay to settle micro
btfss GPIO,3 ; check to see if PTO is engaged.(high) if set then skip next instruction
goto start ; if not set, loop back to start
call Init_ADC1
call Read_ADC1
nop
nop
BANKSEL GPIO ; this is necessary only if control of pins,(such as outputs) on GPIO5 is needed after reading A/D.
call result
goto start
Init_ADC0
movlw b'10000001'
movwf ADCON0 ; bit 7 is set meaning results will be right justified, and bit 0 is also set, meaning A/D module is operating. no other bits are set so Channel 00 for AN0 will be set for read.
return
Init_ADC1
movlw b'10000101'
movwf ADCON0 ; bit 7 is set meaning results will be right justified, and bit 0 is also set, meaning A/D module is operating. bit 2 is set, meaning Channel 01 for AN1 is set for reading.
return
Read_ADC0
call delay1 ; small delay for A/D aquisition time.
; read CHS0 ( channel 0)
bsf ADCON0, GO_DONE ; initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ; wait for ADC to finish, after which GO/DONE bit is cleared automaticaly after conversion.
movf ADRESH,W ; move results from ADRESH file to W
movwf Word ; move value from W to file named Word
BANKSEL ADRESL ; switch to bank 1
movf ADRESL,W ; move results from ADRESL file to W
movwf Word+1 ; move value from W to file named Word and add 1
nop
nop
nop
return
Read_ADC1
call delay1 ; small delay for A/D aquisition time.
; read CHS1 (channel 1)
bsf ADCON0, GO_DONE ; initiate conversion
btfsc ADCON0, GO_DONE
goto $-1 ; wait for ADC to finish, after which GO/DONE bit is cleared automaticaly after conversion
movf ADRESH,W ; move results from ADRESH file to W
movwf Word ; move value from W to file named Word
BANKSEL ADRESL ; switch to bank 1
movf ADRESL,W ; move results from ADRESL file to W
movwf Word+1 ; move value from W to file named Word and add 1
nop
nop
nop
return
result
movlw low(0x015B) ; load W with value of low 0x15
subwf Word,W ; subtract value in file Word, with value in W
movlw high(0x015B) ; load W with value of 0x15
btfss STATUS,C ; check to see if bit "C", in Status is set.
movlw high(0x015B)+1 ; load W with value high 0x15 and add 1
subwf Word+1,W ; subtract value in file Word, with value in W
btfss STATUS,C ; carry clear if word is less than 0x15B
call LEDon
movlw low(0x0266)
subwf Word,W
movlw high(0x0266)
btfss STATUS,C
movlw high(0x0266)+1
subwf Word+1,W
btfsc STATUS,C ; carry set if word is greater or equal to 0x266
goto LEDon
LEDoff
bcf GPIO,5 ; set bit 5 of GPIO register to 0 (low)
goto start
LEDon
bsf GPIO,5 ; set bit 5 of GPIO register to 1 (high)
goto start
delay1
movlw 05h ; will delay W*8 cycles including the call/return
addlw 0xff ; add -1 to W 1
btfsc STATUS,Z ; =zero? 1/2
goto DoneDelay ; yes, better get out of here 2
nop ; delay a bit 1
goto $+1 ; delay a bit more 2
goto delay1 ; go around again 2
DoneDelay
return
END ; directive 'end of program' Can it read 1 volt,to a maximum of 5v?? Is it necessary to amplify above 1 v as this is too low??? Thanks to all who have helped me. P.S. what stumped me for so long, was the fact that, to control an output pin,after reading A/D, you have to switch back to bank "0", after manipulating value in ADRESL. Otherwise nothing happens. Also,the datasheet is wrong . Code: movlw 07h movwf CMCON It does not setup ANSEL register or modify analogue inputs, but makes sure that Comparators are turned off. [code] | |
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| Microcontroller interface with ADC | revjam | Chit-Chat | 4 | 1st August 2008 09:21 AM |
| rms reading | mpj111 | General Electronics Chat | 3 | 10th July 2006 01:37 PM |
| is reading lots of schematics the best way to learn? | psasidisrcum | General Electronics Chat | 17 | 18th April 2005 09:57 PM |
| Specifications Applied | Caltech | General Electronics Chat | 1 | 25th December 2003 06:00 PM |
| A/D help steady reading in low range but bounces in high | usaf1 | Micro Controllers | 3 | 30th September 2003 02:14 AM |