PDA

View Full Version : I need help on ADC interrupt



tacbanon
- 18th December 2011, 06:24
Hi everyone, I have a working code that receives numbers 1-3 from a cellphone (Bluetooth enabled)


clear
DEFINE OSC 20
pause 4000
Include "modedefs.bas"


B0 Var Byte


TRISD = %00000000
TRISC = %10000000'set TX (PORTC.6) to out, rest in
TRISB = %0111101 ' Set PORTB.0-2 (LEDs) to output, 3-6 to input
PortB = 0
PortD = %00000000

' send command to Bluetooth(IP, name)
SerOut2 PortC.6,84, [$02,$52,$27,$06,$00,$7F,$12,$13,$23,$17,$09,$00,$0 3]
pause 200
SerOut2 PortC.6,84, [$02,$52,$66,$00,$00,$B8,$03]
pause 200
Serout2 PortC.6,84, [$02,$52,$04,$11,$00,$67,$10,$4D,$49,$43,$52,$4F,$4 2,$4F,$58,$42,$54,$31,$20,$20,$20,$20,$00,$03]

RX var byte ' Receive byte

'------------------------------------------------------------------------------
'@ DEVICE HS_OSC
Define ADC_BITS 8 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS


adval1 Var Byte ' Create adval to store result
adval2 Var Byte
adval3 Var Byte


TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %00000010 ' Set PORTA analog


TRISD = %00000000
led0 var PORTD.3
led1 var PORTD.4


cnt var byte
OPTION_REG = $7f ' Enable PORTB pull-ups
TRISB = %00000000 ' Set PORTB.0-2 (LEDs) to output, 3-7 to input
PortB = 0
'------------------------------------------------------------------------------
serout PortD.2,T9600,[$1B,$45]
serout PortD.2,T9600,["Loging on.."]
pause 300

Menu:


'****** [Menu setup on PC screen] *************************

serout PortD.2,T9600,[$1B,$45,"**System Ready**"]
pause 500
serout PortD.2,T9600,[$D,"GSTS week"]

Receive:
' ***** [Receive the menu selection from PC] ***************
serin PortC.7, T9600, RX 'Receive menu from PC
serout PortD.2,T9600,[$1B,$45,RX]
pause 500
RX = RX - $30 'Convert ASCII to decimal value

If RX > 3 then Error ' Test for good value
Branch RX, [zero, one, two, Three] 'redirect to menu selection code

error:
serout PortD.2,T9600,[$1B,$45,"Try again"]
serout PortD.2,T9600,[$D,"GSTS week"]
goto menu

Zero:
'***** [ Code for zero value ] *****************************
goto menu 'Return to menu, zero is not a valid selection

One:
'***** [Code for selection 1] ************************


Toggle PortB.0
pause 100
serout PortD.2,T9600,[$1B,$45,"**System Ready**"]
serout PortD.2,T9600,[$D,"Toggle L1"]
pause 500
goto menu 'Return to main menu


Two:
pause 100
Toggle PortB.1
serout PortD.2,T9600,[$1B,$45,"**System Ready**"]
serout PortD.2,T9600,[$D,"Toggle L2"]
pause 500
goto menu 'Return to main menu


Three:
pause 100
Toggle PortB.2
serout PortD.2,T9600,[$1B,$45,"**System Ready**"]
serout PortD.2,T9600,[$D,"Toggle L3"]
pause 500
goto menu 'Return to main menu


End


I'm trying to add the following codes


ADCIN 0, adval1 ' Read channel 0 to adval D1
ADCIN 1, adval2 ' Read channel 0 to adval D0

if adval1 >25 then
SerOut2 PortC.6,84, ["1"]
Serout PortD.0,T9600, [$1B,$45,"[1] ",#adval1]
Pause 100
Endif
if adval2 >25 then
SerOut2 PortC.6,84, ["2"]
Serout PortD.0,T9600, [$1B,$45,"[2] ",#adval1]
Pause 100
Endif

The above codes works in a different application, this triggers when an RF data is received on A0 and A1..and now I'm trying to combine this code in the above code. I tried merging the two codes but it seems the RF codes does not response when triggering the RF transmitter. Do you think I need to apply an interrupt? Can you anyone guide me how?

Thanks in advance,
tacbanon

mackrackit
- 18th December 2011, 08:58
Check the data sheet for the MCU you are using, you do not say which one.
Something does not look correct.


ADCON1 = %00000010 ' Set PORTA analog

ADCIN 0, adval1 ' Read channel 0 to adval D1
ADCIN 1, adval2 ' Read channel 0 to adval D0

tacbanon
- 18th December 2011, 09:39
Hi macrackit,
Sorry for that my mistake...here is the whole code, I'm using Pic16F877A with 20mhz crystal


clear
INCLUDE "MODEDEFS.BAS" ' Include Shiftin/out modes


pause 4000


'@ DEVICE HS_OSC
DEFINE OSC 20
Define ADC_BITS 8 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS


adval1 Var Byte ' Create adval to store result
adval2 Var Byte
adval3 Var Byte


TRISA = 111111 ' Set PORTA to all input
ADCON1 = 000010 ' Set PORTA analog



TRISC = 000000 ' PORTC.7 is the RX input, PORTC.6 is the TX output
TRISD = 000000
led0 var PORTD.0
led1 var PORTD.1
' The following codes is for bluetooth------------------------------------------------------------------------------------
SerOut2 PortC.6,84, [$02,$52,$27,$06,$00,$7F,$12,$13,$23,$17,$09,$00,$0 3]
pause 200
SerOut2 PortC.6,84, [$02,$52,$66,$00,$00,$B8,$03]
pause 200
Serout2 PortC.6,84, [$02,$52,$04,$11,$00,$67,$10,$4D,$49,$43,$52,$4F,$4 2,$4F,$58,$42,$54,$31,$20,$20,$20,$20,$00,$03]
'-------------------------------------------------------------------------------------------------------------------------
RX var byte ' Receive byte




mainloop:
ADCIN 0, adval1 ' Read channel 0 to adval1
ADCIN 1, adval2 ' Read channel 1 to adval2

pause 20
Pause 100 ' Wait .1 second
if adval1 >25 then
SerOut2 PortC.6,84, ["1"] ' sends 1 to Bluetooth TX
Serout PortD.2,T9600, [$1B,$45,"[1] ",#adval1] ' Displays to serial LCD for debugging
Pause 100
Endif
if adval2 >25 then
SerOut2 PortC.6,84, ["2"] ' sends 2 to Bluetooth TX
Serout PortD.2,T9600, [$1B,$45,"[2] ",#adval2] ' Displays to serial LCD for debugging
Pause 100
Endif

Goto mainloop ' Do it forever



My problem is how to receive incoming data from bluetooth with SERIN without freezing the application..

regards,
tacbanon

tacbanon
- 23rd December 2011, 21:06
I'm trying to play with this code from Mister_e, but my trouble is I can not send message to PC at the same time(Sending Hello and reading from analog pin). I hope anyone can give a hint on this.




'
' Simple program to handle USART interrupt using PIC16F877 @20MHZ
' ================================================== =============
'
' This program will Blink a LED on PORTB.0 to show
' that the PIC is running.
'
' This program also allow the user to activate or deactivate
' a LED connected on PORTB.1 pin by sending command from a PC
' terminal software using 9600,n,8,1 setting
'
' User command:
' =============
' 1. If character "1" is received => enable the LED1
' 2. if character "2" is received => disable the LED1
' 3. If character "3" is received => enable the LED2
' 4. if character "4" is received => disable the LED2
'
'
'DEFINE LOADER_USED 1 ' using bootloader
Include "modedefs.bas"
DEFINE OSC 20 ' running at 20 MHZ

' PORT setting
' ============
'
TRISC=%10000000 ' RC.7 => USART RX pin set to input
' all other pin set to output
'
TRISB=0 ' RB<7:0> set to output

' USART setting
' =============
' Since we will not use HSERIN/HSEROUT, we must
' write directly to internal PIC register
'
TXSTA=$24 ' enable transmit and SPBRGH=1
RCSTA=$90 ' Enable USART and continuous receive
SPBRG=129 ' BAUD RATE = 9600 BAUDS

' Interrupt definition
' ====================
'
PIE1.5 =1 ' enable USART receive interrupt
INTCON.6 =1 ' enable peripheral interrupt

' Alias definition
' ================
'
RCIF var PIR1.5 ' receiver interrupt
StatusLED var PORTB.0 ' the LED who show a 'running process'
UserLED1 var PORTB.1 ' the LED1 that user want to control
UserLED2 var PORTB.2 ' the LED2 that user want to control
UserLED3 var PORTB.3 ' the LED3 that user want to control
UserLED4 var PORTB.4 ' the LED4 that user want to control

' Variable definition
' ===================
'
Delay var word '
DataIn var byte ' use to store RCREG content
Discard var byte ' use to erase RCREG register

' Hardware/software initialisation
' ================================
'
PORTB=0 ' clear PORTB
on interrupt goto USARTInterrupt
'------------------------------------------------------------------------------
DEFINE ADC_BITS 8 ' Set A/D for 8-bit operation
DEFINE ADC_CLOCK 1 ' Set A/D clock Fosc/8
DEFINE ADC_SAMPLEUS 50 ' Set A/D sampling time @ 50 uS


adval Var Byte ' Create adval to store result
TRISA = %11111111 ' Set PORTA to all input
'ADCON1 = %00000011 ' Set PORTA.0,1,2,5 = A/D, PortA.3 = +Vref
ADCON1 = %00000010 ' Set PORTA analog


pause 500

Start:
' Main program loop that make the user happy to
' see a LED flashing to mean that something is
' running
'
Serout2 PortC.6, 84,["Hello",13]
toggle statusled
'for delay = 1 to 5000 ' use a loop delay to ensure
'pauseus 5 ' getting interrupt as fast as possible
'next
ADCIN 0, adval
Serout2 PORTC.6, 84, ["Value: ", DEC adval, 13, 10] ' Display value
pause 100

goto start



disable interrupt
USARTInterrupt:
' Here's the interrupt routine who will make the user
' much happy by giving him the feeling to have the
' control on the machine when the status of the user
' LED will change
'
RCSTA=0 ' Disable serial port AND
' clear possible error (FERR,OERR)

datain=RCREG ' Get data

while RCif ' wait untill the RCREG is empty
discard=RCREG ' by reading it and store result in a
wend ' don't care variable

select case datain ' What to do with that data???

case "1" ' User selection = 1
userled1=1 ' => Enable the LED

case "2" ' User selection =2
userled1=0 ' => disable the LED

case "3" ' User selection = 3
userled2=1 ' => Enable the LED

case "4" ' User selection =4
userled2=0 ' => disable the LED

case "5" ' User selection = 3
userled3=1 ' => Enable the LED

case "6" ' User selection =4
userled3=0 ' => disable the LED

case "7" ' User selection = 3
userled4=1 ' => Enable the LED

case "8" ' User selection =4
userled4=0 ' => disable the LED

end select
RCSTA=$90 ' Re-enable the serial PORT AND
resume ' get out of here
enable interrupt

Hardware: Pic16F877A at 20Mhz crystal

regards,
tacbanon

tacbanon
- 23rd December 2011, 22:35
I managed to send message to PC and added sensor reading(working in a separate program), but now I have strange reading on my temperature and light sensors. kindly check my code.


'DEFINE LOADER_USED 1 ' using bootloader
Include "modedefs.bas"
DEFINE OSC 20 ' running at 20 MHZ

' PORT setting
' ============
'
TRISC=%10000000 ' RC.7 => USART RX pin set to input
' all other pin set to output
'
TRISB=0 ' RB<7:0> set to output

' USART setting
' =============
' Since we will not use HSERIN/HSEROUT, we must
' write directly to internal PIC register
'
TXSTA=$24 ' enable transmit and SPBRGH=1
RCSTA=$90 ' Enable USART and continuous receive
SPBRG=129 ' BAUD RATE = 9600 BAUDS

' Interrupt definition
' ====================
'
PIE1.5 =1 ' enable USART receive interrupt
INTCON.6 =1 ' enable peripheral interrupt

' Alias definition
' ================
'
RCIF var PIR1.5 ' receiver interrupt
StatusLED var PORTB.0 ' the LED who show a 'running process'
UserLED1 var PORTB.1 ' the LED1 that user want to control
UserLED2 var PORTB.2 ' the LED2 that user want to control
UserLED3 var PORTB.3 ' the LED3 that user want to control
UserLED4 var PORTB.4 ' the LED4 that user want to control

' Variable definition
' ===================
'
Delay var word '
DataIn var byte ' use to store RCREG content
Discard var byte ' use to erase RCREG register

' Hardware/software initialisation
' ================================
'
PORTB=0 ' clear PORTB
on interrupt goto USARTInterrupt
'------------------------------------------------------------------------------
DEFINE ADC_BITS 8 ' Set A/D for 8-bit operation
DEFINE ADC_CLOCK 1 ' Set A/D clock Fosc/8
DEFINE ADC_SAMPLEUS 50 ' Set A/D sampling time @ 50 uS


adval Var Byte ' Create adval to store result
TRISA = %11111111 ' Set PORTA to all input
ADCON1 = %00000011 ' Set PORTA.0,1,2,5 = A/D, PortA.3 = +Vref
'ADCON1 = %00000010 ' Set PORTA analog
'--------Variables--------------------------------------------------------------
light var WORD
samples VAR WORD ' Multiple A/D sample accumulator
sample VAR BYTE ' Holds number of samples to take
temp VAR BYTE ' Temperature storage
samples = 0 ' Clear samples accumulator on power-up


samples2 var word
sample2 VAR BYTE
samples2 = 0


pause 500

Start:
' Main program loop that make the user happy to
' see a LED flashing to mean that something is
' running
'
toggle statusled
Pause 100
FOR sample = 1 TO 20 ' Take 20 samples
ADCIN 1, temp ' Read channel 0 into temp variable
samples = samples + temp ' Accumulate 20 samples
PAUSE 100 ' Wait approximately 1/4 seconds per loop
NEXT sample
temp = (samples/20)
Hserout ["Temp=",DEC temp ,"'C" ,13]

ADCIN 0, light
Hserout ["Light=",DEC light ,13]
goto start



disable interrupt
USARTInterrupt:
' Here's the interrupt routine who will make the user
' much happy by giving him the feeling to have the
' control on the machine when the status of the user
' LED will change
'
RCSTA=0 ' Disable serial port AND
' clear possible error (FERR,OERR)

datain=RCREG ' Get data

while RCif ' wait untill the RCREG is empty
discard=RCREG ' by reading it and store result in a
wend ' don't care variable

select case datain ' What to do with that data???

case "1" ' User selection = 1
userled1=1 ' => Enable the LED

case "2" ' User selection =2
userled1=0 ' => disable the LED

case "3" ' User selection = 3
userled2=1 ' => Enable the LED

case "4" ' User selection =4
userled2=0 ' => disable the LED

case "5" ' User selection = 3
userled3=1 ' => Enable the LED

case "6" ' User selection =4
userled3=0 ' => disable the LED

case "7" ' User selection = 3
userled4=1 ' => Enable the LED

case "8" ' User selection =4
userled4=0 ' => disable the LED

end select
RCSTA=$90 ' Re-enable the serial PORT AND
resume ' get out of here
enable interrupt


regards,
tacbanon

tacbanon
- 24th December 2011, 08:02
I finally got the code to work, the problem was faulty circuitry, sorry for not double checking on my part before posting...Thank God for this forum and everyone here who I believed to be my PICexperts(macrackit, Mr_e, DT, Skimask, Henrick just to name a few) heroes...:)
Merry Christmas everyone!!!!

regards,
Tacbanon