Tom Gonser
- 30th March 2005, 15:30
Can LCDout break interrupts for some reason?
My project runs fine with an interrupt on RB0 leading to a menu system. In the menu system, it displays a menu choice and then waits to see if RB1 is brought HIGH indicating a selection. If selected, it returns to the main program loop. This is working fine.
THEN, I went to add an LCD using LCDout, the interrupt gets somehow tripped without pressing the button, and the RB1 button does nothing!! Adding just one "LCDout $FE, XXX" command does this. Remove it, and it goes back to normal!!! (It does the same thing wth the LCD physically connected or not)
Can anyone think why adding the "LCDout" stuff would mess up my interrupt routine, and eliminate the operation of B1 on a totally different port than the LCD is even on?
Here is the environment:
PIC 18F2525
8 Mhz internal Osc
External EEPROM
Serial data in, processed, and displayed or stored on EEPROM
LCD is on RA.0-RA.3, RA.4,RA.5.
Interrupt line is on RB.0, second button is on RB.1
I2C is on RC3,RC4
Seral data I/O is on RB4,RB5, and RC
Program setup includes:
' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines
'Define loader_used 1 Used for bootloader only
OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend
DEFINE LCD_DREG PORTA ' Set data pin of LCD to
DEFINE LCD_DBIT 0 ' PORTA.0-PORTA.3
DEFINE LCD_RSREG PORTA ' Set RS bit of LCD to
DEFINE LCD_RSBIT 4 ' PORTA.5
DEFINE LCD_EREG PORTA ' Set E bit of LCD to
DEFINE LCD_EBIT 5 ' PORTA.4
DEFINE LCD_LINES 4 ' 4 Lines LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.
' --------------------------------------------------------------------------------
ADCON0 = %00110000 ' turn off - select port AN12 (nothing)
ADCON1 = %00001111 ' turn portA to digital I/O (same as dec 15)
CMCON = $07 ' turn off
HLVDCON = %00000000 ' turn off
CVRCON = $00000000 ' turn off
SSPCON1 = %11011100 ' supposed to be turning on I2C
SSPCON2 = %01111000 ' supposed to be turning on I2C
INTCON = %11110000 ' TG guess at 2525 interrups for all INT pins
INTCON2= %01110100 ' rising edge of INT0,1,2 RB0,1,2
RCON = %10000000 ' no priority interrups
T1CON = %11000000 'Timer1 1:1 prescale??
Init:
PORTA = %00000000 'Initialize PortA to all zeros - all output
TRISA = %00000000 'All port A output
PORTB = %00010001 'Initialize PortB - port 5 for data, port 0 for button interrupt
TRISB = %00010001 'Port 2 inputs are 0 and 5
PORTC = %00010000 '
TRISC = %00010000 ' SCL I2C clock out
On Interrupt Goto INT_handle
Bmenu = 1
Smenu = 0
ReStart:
TMR1H = 0 ' Clear time counts before Timer1 re-start
TMR1L = 0 ' Clear time counts before Timer1 re-start
PIR1.0 = 0 ' CLear over-flow flag before enable
T1CON.0 = 1 ' Turn Timer1 back on before entry into MainProcedure
Main:' ****** [Main Program Loop] *
PROGRAM LOOP
Goto Main
' Interrupt handler at end of program
NextStage: ' timer routine
Mnu = 0
T1CON.0 = 0 ' Turn off Timer1
Timer = 0 ' Clear Timer var on entry here
TMR1H = 0
TMR1L = 0 ' CLear timer count registers as required
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Timer Ran Out"]
pause 1000
GOTO ReStart ' When you're ready to start all over
' Interrupt handler stuff here
Disable ' Disable interrupts in handler
INT_handle:
Timer = 0 ' Clear Timer var on entry here
TMR1H = 0
TMR1L = 0 ' CLear timer count registers as required
Selectit=0
While selectit = 0
Mnu=1 ' we are in the menu system
If Mmenu = 0 then
While Mmenu = 0 ' waiting until
wend ' push-button is release
pause 100 ' debounce time
Bmenu=Bmenu+1
endif ' bo pressed – go to next menu
Select Case Bmenu
Case 1
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Sensors & Sats"]
pause 10
Case 2
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Lat/Long"]
pause 10
Case 3
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Speed/Volts"]
pause 10
Case 4
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Altitude"]
pause 10
Bmenu=1
end select
If PortB.1 = 1 then ' select button is pressed
While MMenu = 0 ' waiting until
wend ' push-button is release
pause 100 ' debounce time
selectit = 1 ' b1 pressed get out of the loop!
endif
Wend
Mnu=0 ' turn off menu flag
Here:
While MMenu = 0 ' waiting until
wend ' push-button is release
pause 100 ' debounce time
If MMenu = 0 then here
PIR1.0 = 0 ' Clear Timer1 over-flow flag
Timer = 0 ' Clear Timer counts before return
INTCON.1=0 ' reset RB0 interrupt flag
Resume ' Return to main program
Enable ' Enable interrupts after
' handler
end
My project runs fine with an interrupt on RB0 leading to a menu system. In the menu system, it displays a menu choice and then waits to see if RB1 is brought HIGH indicating a selection. If selected, it returns to the main program loop. This is working fine.
THEN, I went to add an LCD using LCDout, the interrupt gets somehow tripped without pressing the button, and the RB1 button does nothing!! Adding just one "LCDout $FE, XXX" command does this. Remove it, and it goes back to normal!!! (It does the same thing wth the LCD physically connected or not)
Can anyone think why adding the "LCDout" stuff would mess up my interrupt routine, and eliminate the operation of B1 on a totally different port than the LCD is even on?
Here is the environment:
PIC 18F2525
8 Mhz internal Osc
External EEPROM
Serial data in, processed, and displayed or stored on EEPROM
LCD is on RA.0-RA.3, RA.4,RA.5.
Interrupt line is on RB.0, second button is on RB.1
I2C is on RC3,RC4
Seral data I/O is on RB4,RB5, and RC
Program setup includes:
' -----[ Fuses ]------------------------------------------------
@ __CONFIG _CONFIG1H, _OSC_INTIO67_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & 0bfh ;_XINST_OFF_4L
'
' -----[ Includes/Defines ]---------------------------------------------------------
include "modedefs.bas" 'include serout defines
'Define loader_used 1 Used for bootloader only
OSCCON=%01111000
DEFINE OSC 8
While OSCCON.2=0:Wend
DEFINE LCD_DREG PORTA ' Set data pin of LCD to
DEFINE LCD_DBIT 0 ' PORTA.0-PORTA.3
DEFINE LCD_RSREG PORTA ' Set RS bit of LCD to
DEFINE LCD_RSBIT 4 ' PORTA.5
DEFINE LCD_EREG PORTA ' Set E bit of LCD to
DEFINE LCD_EBIT 5 ' PORTA.4
DEFINE LCD_LINES 4 ' 4 Lines LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.
' --------------------------------------------------------------------------------
ADCON0 = %00110000 ' turn off - select port AN12 (nothing)
ADCON1 = %00001111 ' turn portA to digital I/O (same as dec 15)
CMCON = $07 ' turn off
HLVDCON = %00000000 ' turn off
CVRCON = $00000000 ' turn off
SSPCON1 = %11011100 ' supposed to be turning on I2C
SSPCON2 = %01111000 ' supposed to be turning on I2C
INTCON = %11110000 ' TG guess at 2525 interrups for all INT pins
INTCON2= %01110100 ' rising edge of INT0,1,2 RB0,1,2
RCON = %10000000 ' no priority interrups
T1CON = %11000000 'Timer1 1:1 prescale??
Init:
PORTA = %00000000 'Initialize PortA to all zeros - all output
TRISA = %00000000 'All port A output
PORTB = %00010001 'Initialize PortB - port 5 for data, port 0 for button interrupt
TRISB = %00010001 'Port 2 inputs are 0 and 5
PORTC = %00010000 '
TRISC = %00010000 ' SCL I2C clock out
On Interrupt Goto INT_handle
Bmenu = 1
Smenu = 0
ReStart:
TMR1H = 0 ' Clear time counts before Timer1 re-start
TMR1L = 0 ' Clear time counts before Timer1 re-start
PIR1.0 = 0 ' CLear over-flow flag before enable
T1CON.0 = 1 ' Turn Timer1 back on before entry into MainProcedure
Main:' ****** [Main Program Loop] *
PROGRAM LOOP
Goto Main
' Interrupt handler at end of program
NextStage: ' timer routine
Mnu = 0
T1CON.0 = 0 ' Turn off Timer1
Timer = 0 ' Clear Timer var on entry here
TMR1H = 0
TMR1L = 0 ' CLear timer count registers as required
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Timer Ran Out"]
pause 1000
GOTO ReStart ' When you're ready to start all over
' Interrupt handler stuff here
Disable ' Disable interrupts in handler
INT_handle:
Timer = 0 ' Clear Timer var on entry here
TMR1H = 0
TMR1L = 0 ' CLear timer count registers as required
Selectit=0
While selectit = 0
Mnu=1 ' we are in the menu system
If Mmenu = 0 then
While Mmenu = 0 ' waiting until
wend ' push-button is release
pause 100 ' debounce time
Bmenu=Bmenu+1
endif ' bo pressed – go to next menu
Select Case Bmenu
Case 1
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Sensors & Sats"]
pause 10
Case 2
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Lat/Long"]
pause 10
Case 3
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Speed/Volts"]
pause 10
Case 4
serout2 ALCDout, LCDbd, [I,CLR]
serout2 ALCDout, LCDbd,[I,L1_C1]
serout2 ALCDout, LCDbd, ["Altitude"]
pause 10
Bmenu=1
end select
If PortB.1 = 1 then ' select button is pressed
While MMenu = 0 ' waiting until
wend ' push-button is release
pause 100 ' debounce time
selectit = 1 ' b1 pressed get out of the loop!
endif
Wend
Mnu=0 ' turn off menu flag
Here:
While MMenu = 0 ' waiting until
wend ' push-button is release
pause 100 ' debounce time
If MMenu = 0 then here
PIR1.0 = 0 ' Clear Timer1 over-flow flag
Timer = 0 ' Clear Timer counts before return
INTCON.1=0 ' reset RB0 interrupt flag
Resume ' Return to main program
Enable ' Enable interrupts after
' handler
end