PDA

View Full Version : Interrupt not working?



tacbanon
- 21st October 2012, 03:17
Hello everyone,
I'm trying to build an application that will simply trigger relays using sms on GSM module.
What I have done so far (basically)..
1. Get GSM signal and manufacturer
2. Send sms
Now I'm trying to read incoming messages but with interrupt (with DT's). but it seems that when I send a message to the GSM the following block of code does not function


Getbytes:
HSEROUT ["Went here!!",13]
i=i+1 ' coubt how many time it pass here
cntr = 0
While RCIF = 1 ' clear the buffer
HSERIN 50,error,[Wait("P")] ' test it
Hserout ["Got it!!",13]
Wend
@INT_return


The following code is what I'm testing...I strip out the other codes within the main loop just to simply...


'************************************************* ***************
'* Name : HACS.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 10/20/2012 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
asm
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
;__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm
INCLUDE "MODEDEFS.BAS" ' Include Shiftin/out modes
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts
; create the transmition interrupt
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _Getbytes, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
;


;------------------------------------------------------------------------

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50


define OSC 48
TRISA = %00001111
PortA = %00000000
TRISC = %10000000 ' PORTC.7 is the RX input, PORTC.6 is the TX output
ADCON1 = %00001111
TRISD = %00000111
PortD = %00000000
PORTD = %00000000 ; set to PORTD low
LedA var PortD.0 ;assign var LedA to PortD.0
LedB var PortD.1 ;assign var LedB to PortD.1
LedC var PortD.2 ;assign var LedC to PortD.2
Load1 var PortD.3
Load2 var PortD.4
Load3 var PortD.5
'CONFIGURE DISPLAY
pause 100
ln1 con $80
ln2 con $C0

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 1
DEFINE HSER_BAUD 9600
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
; setup serial port line for transmition
RCIF VAR PIR1.5 ' Receive interrupt flag (1=full , 0=empty)
TXIF VAR PIR1.4 ' Transmit interrupt flag (1=empty, 0=full)
'------------------------------------------------------Transmition-------------
But0 var PortA.0
But1 var PortA.1
But2 var PortA.2
But3 var PortA.3

Led1 var PortC.0
Led2 var PortC.1
Led3 var PortC.2
Led1 = 0
Led2 = 0
Led3 = 0
flag1 var bit
flag1 = 0
flag2 var bit
flag2 = 0
flag3 var bit
flag3 = 0
Pswd var byte[5]
Data @0, 5,"12345"
ArrayNum var byte[12]
'------------------------------------------------------------------------------
cntr var byte 'count error occur
cntr = 0
i var byte
i = 0
PortB = %00000000
SerialData var byte[10]
LCDOUT $Fe,1
'--------------------------------------------------------------
pause 1000
LCDOUT $Fe,ln2 , "System loading.."
pause 5000
Gosub ButtOption1
;----Initialize text mode--------
HSEROUT ["AT+CMGF=",49,13,10]
HSERIN 5000, GSM_CHECK_ERR, [WAIT("OK")]
LCDOUT $Fe,1 , "HASMS-CMS"
pause 1000
LCDOUT $Fe,192, "Init Text MODE"
pause 1000
LCDOUT $Fe,ln2, " " ' clear second line
Lcdout $FE, ln2,"system ready..."
cntr = 0
PAUSE 2000
LCDOUT $Fe,ln2, " " ' clear second line
@ INT_ENABLE RX_INT ; enable RX_INT interrupts


'--------------Main program start here--------------
Main
LCDOUT $Fe, ln1, "HASMS-CMS", Dec3 i
LCDOUT $Fe,ln2 , "Listening...", DEC3 cntr
if cntr < 254 then
cntr = cntr + 1
else
cntr = 0
Endif
pause 2000

GOTO Main
'--------------Main program end here--------------
GSM_CHECK_ERR:
cntr = cntr + 1
LCDOUT $Fe, ln1, "HASMS-CMS"
pause 1000
LCDOUT $Fe, ln2, "GSM Error #", DEC3 cntr
pause 1000
return


Getbytes:
HSEROUT ["Went here",13]
i=i+1 ' count how many time it pass here
cntr = 0
While RCIF = 1 ' clear the buffer
HSERIN 50,error,[Wait("P")] 'test it
Hserout ["Got it!!",13]
Wend

@INT_return

error:
Hserout ["Error",13]
goto Main


ButtOption1:
LCDOUT $Fe,1 , "GSM Info"
LCDOUT $Fe, ln2, "processing... "
pause 1200
High PortD.4
pause 1200
Low PortD.4

'------------------- Determine Signal
HSEROUT ["AT+CSQ",13,10]
HSERIN 1000, GSM_CHECK_ERR, [WAIT("+CSQ: "),STR Serialdata\4]
LCDOUT $Fe,1 , "GSM Info"
LCDOUT $Fe,ln2, "SIGNAL:",STR Serialdata\4
cntr = 0
'------------------- Determine Manufacturer
PAUSE 3000
HSEROUT ["AT+CGMI",13,10] 'Ask model name
HSERIN 5000, GSM_CHECK_ERR, [WAIT("SIMCOM"),STR Serialdata\4]
LCDOUT $Fe,1 , "GSM Info"
LCDOUT $Fe,ln2, "MANUF:SIMCOM",STR Serialdata\4
cntr = 0
pause 3000
LCDOUT $Fe,1 ' Clear LCD
return

END

I think the GetBytes sub program triggers on boot up because it displays Hserout ["Went here",13]...after that when it enters to the main loop and try to send sms to the device it never get the interrupt.
Can anyone spot what I'm missing? I've been going nuts with it the whole week :frown:

Regards,
tacbanon

mackrackit
- 21st October 2012, 09:07
I might not be thinking correctly, but I think the reset flag should be set to "yes".

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _Getbytes, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

tacbanon
- 22nd October 2012, 08:53
Hi mackrackit, I tried what you suggested but no luck...thanks for replying.

/tacbanon

Demon
- 23rd October 2012, 04:57
I have this:


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX1_INT, _ReceiveInterrupt, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

and it works fine on 6 slaves.

Robert

Demon
- 23rd October 2012, 05:06
PortD = %00000000
PORTD = %00000000 ; set to PORTD low

Are you sure that's enough? :D


Seriously, I've seen several comments about both TX and RX pins should be set to input in TRIS. USART then takes control and decides what they should be.



CCP2MX_ON_3H

Do you really need that feature enabled?

Robert

tacbanon
- 23rd October 2012, 07:48
Hi Robert, thanks for giving the time to look onto the codes...I will try to check on it and see what will happen...

Regards,
tacbanon

Ioannis
- 23rd October 2012, 08:20
Leave the GSM aside for a while and test you program with a terminal.

Then just type on the keyboard what you expect your PIC to receive and see if that works.

Ioannis

tacbanon
- 23rd October 2012, 15:52
@Ioannis
I have the following code below that works when sending to the SerialComm...


'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
'Hserin with Darryl Taylor's Instant Interrupts
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
asm
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
;__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm



DEFINE OSC 48
DEFINE HSER_RCSTA 90h ' enable serial port,
DEFINE HSER_TXSTA 20h ' enable transmit,
DEFINE HSER_BAUD 9600
DEFINE HSER_CLOERR 1 ' automatic clear overrun error

TRISC = %10000000 ' PORTC.7 is the RX input, PORTC.6 is the TX output


' Serial communication definition
' ===============================
'
ADCON1 = %00001111 'Set up ADCON1 register no matter what you're doing!!!!!!
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::

INCLUDE "MODEDEFS.BAS" ' Include Shiftin/out modes
INCLUDE "DT_INTS-18.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" ' Include if using PBP interrupts
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
' Variable definition
'::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::
PortB = %00000000
TRISB = %00000000
RCIF VAR PIR1.5 ' Receive interrupt flag (1=full , 0=empty)
TXIF VAR PIR1.4 ' Transmit interrupt flag (1=empty, 0=full)
led var PORTC.0
led1 var PORTC.1
holdoff var word
SerialData var byte
SerialInput var byte[50]
PortB = 0
c var byte
i var byte
c = 0
clear

'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _Getbytes, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE RX_INT ; enable RX_INT interrupts


'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
' Subroutine to slow loop down some and toggle heartbeat
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
Mainloop:
c = 0
for holdoff = 1 to 100
pause 1
next holdoff
toggle led 'toggle led every loop for heartbeat

goto Mainloop


'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))
'ISR for RX_int interrupt
'((((((((((((((((((((((((((((((((((((((()))))))))) )))))))))))))))))))))))))))))

Getbytes:

While RCIF = 1 ' clear the buffer
c = c + 1
'HSEROUT ["Process "]
HSERIN 100,error,[Serialdata] ' take it
HSEROUT [Serialdata] ' take it out
SerialInput[c] = Serialdata
select case Serialdata ' What to do with that data???
case "^" ' User selection = 1
HSEROUT ["Goto Sub Process "] ' take it out
gosub displaydata
End select
Wend

toggle led 'led to confirm program went to RX ISR

@ INT_RETURN


error:
Toggle led1
@ INT_RETURN
end

displaydata:
for i = 1 to c
Hserout [SerialInput[i]]
next i

return


Then I tried to insert GSM related one block of code at a time but the same result (triggers interrupt only once--upon bootup)..

>>>tacbanon

HenrikOlsson
- 23rd October 2012, 16:50
Some random thoughts:
The TX interrupt flag gets cleared by the hardware when the buffer is emptied - which it is by reading it so Reset Flag=NO is correct.

Perhaps you're overflowing the buffer?
When you're "emulating" the GSM-module by sending characters manually from the terminal your sending them quite slowly - if you're sendig them one by one as you are typing them. When you then plugin the GSM-module it'll send the same string (hopefully) at the same baudrate as you did manually but the time between each character is a lot shorter so the time the ISR has to process each character is shorter.

I see that you have a HSEROUT ["Process"] in the ISR, things like that WILL overflow the buffer because your sitting in a loop spitting out the word 'Process' (7 bytes) while more might be comming in. The TX-buffer is only one byte deep so the program will have to put in the 'P' then wait for it to go out, put in the 'r', then wait for it to go out and so. Not untill it has put the last 's' in the Tx-buffer will it continue. In the meantime bytes are still trying to get into the Rx-buffer which is only 2 bytes deep - the buffer will likely overflow.

Now, I see that you've commented the above line out which is good but it illustrates the issue I'm trying to get at perfectly.


Also, I'm not sure if it's intentionally but you're resetting the counter (c) each time thru the main loop so if the mainloop startover in the middle of a string it will start overwriting itself. I think that what you want is to reset (c) at the end of DisplayData routine, and possible in the Error routine.

Finally, at the beginning of the program, try inserting a lengthy pause to allow the PIC and the GSM-module to power up properly then make sure the USART buffer is clear and the interrupt flag reset - then enable the interrupt. If the GSM module has an enable input or something tie that to an output on the PIC so you can keep it disabled untill you're ready.

/Henrik.

Demon
- 23rd October 2012, 16:50
Is that too much stuff going on inside ISR?

What if you simplify usart logic until you get things working as expected?

Do you really need byte-by-byte reception? Can you get away with a fixed length message?

My interrupt routine looks like this:

ReceiveInterrupt:
HSERIN 50,No232,[DEC5 PicIn.byte1, DEC5 PicIn.byte0, DEC1 CommandIn, _
STR DataIn1\24, STR DataIn2\24, _
DEC5 CheckSumIn.byte1, DEC5 CheckSumIn.byte0]
RS232Flag = StateTrue
No232:
@ INT_RETURN

I check in main loop if RS232Flag was set, and then do all the processing there.

Robert

tacbanon
- 23rd October 2012, 21:53
Thank you Henrik for explaining it well and giving me ideas how to trace the steps the codes is doing.
and thank you Robert for sharing your code...I will try them out.

regards,
tacbanon

Ioannis
- 24th October 2012, 10:19
For sending a string of keystrokes instead of typing and having a delay, as Henrik spoted, try this terminal program:

https://sites.google.com/site/terminalbpp/Terminal20111230.zip?attredirects=0

It can accept a string of characters and then you hit send to send it as it would your GSM device.

Ioannis

tacbanon
- 25th October 2012, 12:38
Finally we got the power back today...we've been battered by the typhoon 'OFEL'...
@Ioannis
Thanks for the link..I will try and let you know...later.

tacbanon