PDA

View Full Version : 18F26K42 TMR1 Interrupt troubles



SecaRider
- 7th March 2018, 15:13
Hello, I am a first-time caller, long time listener. You folks and this forum have been a wealth of knowledge over the years and I just wanted to say thank you. I currently have a problem that I haven’t been able to crack, I am sure I am missing something but just don’t know what.

I am trying to get a TMR1 overflow interrupt (no vectors, I turned them off, I think) to work on a 18F26K42. I tried using the DT_INTS-18K42b.bas routine by MPGMike but kept getting a compile error, specifically on the SaveFSR (0), (1), and (2) lines. Based on an earlier post I went into the DT_INTS-18K42b.bas file and replaced the “movff”with “movffl” but that didn’t seem to help either. The test code is below:



#CONFIG
CONFIG FEXTOSC = OFF
CONFIG RSTOSC = HFINTOSC_64MHZ
CONFIG CLKOUTEN = OFF
CONFIG PR1WAY = OFF
CONFIG CSWEN = ON
CONFIG FCMEN = OFF
CONFIG MCLRE = INTMCLR
CONFIG PWRTS = PWRT_OFF
CONFIG MVECEN = OFF ;disable vector table
CONFIG IVT1WAY = OFF
CONFIG LPBOREN = OFF
CONFIG BOREN = OFF
CONFIG BORV = VBOR_245
CONFIG ZCD = OFF
CONFIG PPS1WAY = OFF
CONFIG STVREN = OFF
CONFIG DEBUG = OFF
CONFIG XINST = OFF
CONFIG WDTCPS = WDTCPS_31
CONFIG WDTE = OFF
CONFIG WDTCWS = WDTCWS_7
CONFIG WDTCCS = LFINTOSC
CONFIG BBSIZE = BBSIZE_512
CONFIG BBEN = OFF
CONFIG SAFEN = OFF
CONFIG WRTAPP = OFF
CONFIG WRTB = OFF
CONFIG WRTC = OFF
CONFIG WRTD = OFF
CONFIG WRTSAF = OFF
CONFIG LVP = OFF
CONFIG CP = OFF
#ENDCONFIG

'Defines, Includes, and Constants-----------------------------------------------

DEFINE OSC 64 ' Calibrate PBP to 64MHz clock
OSCFRQ = 001000 ' Set system clock to 64MHz internal

INCLUDE "DT_INTS-18_k42b.bas" ; Base Interrupt System
include "ReEnterPBP.bas"

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _INC_TICK, PBP, YES
ENDM
INT_CREATE
ENDASM

'Direction----------------------------------------------------------------------

TRISA = 000000
TRISB = 000000
TRISC = 000000

'Alias---------------------------------------------------------------------------

LED var PORTA.1

'Variables----------------------------------------------------------------------

'Initialize Registers----------------------------------------------------------------------

Initialize:
ANSELA = 000000 ' Set digital
ANSELB = 000000 ' Set digital
ANSELC = 000000 ' Set digital
ADCON0 = 000000 ' Disable ADC

CM1CON0.7 = 0 : CM2CON0.7 = 0 'Disable comparators
PMD0=$FF : PMD1=$FF : PMD2=$FF 'Turning off all Peripheral-
PMD3=$FF : PMD4=$FF : PMD5=$FF '-Modules, not sure if this is nessesary
PMD6=$FF : PMD7 = $FF
PMD1.bit1 = 0 'Enable the TMR1 module

T1CON = 110000 'Prescale 1:8; Disable the TMR1
T1GCON.bit7 = 0 'Disable gate, TMR1 always counting
T1CLK = 000001 'Clock Source Fosc/4

TMR1H = $00 : TMR1L = $00

@ INT_ENABLE TMR1_INT

LED = 0

'Code---------------------------------------------------------------------------

Main:
pause 1
Goto Main

'----- INTERRUPT CODE -------------------
INC_TICK:
toggle LED
TMR1L = $00 : TMR1H = $00
PIR4.bit0 = 0
@ INT_RETURN
'------ END OF INTERRUPTS CODE ----------



Next, I tried the simple old “ON INTERRUPT GOTO” function of PBP3. The code below seems to compile, it just doesn't work. I can confirm that the TMR1H and TMR1L registers increase to 65535 and then wrap around to 0 and increase again, etc. The interrupt just never occurs. I am using an oscilloscope to monitor the LED pin.




#CONFIG
CONFIG FEXTOSC = OFF
CONFIG RSTOSC = HFINTOSC_64MHZ
CONFIG CLKOUTEN = OFF
CONFIG PR1WAY = OFF
CONFIG CSWEN = ON
CONFIG FCMEN = OFF
CONFIG MCLRE = INTMCLR
CONFIG PWRTS = PWRT_OFF
CONFIG MVECEN = OFF
CONFIG IVT1WAY = OFF
CONFIG LPBOREN = OFF
CONFIG BOREN = OFF
CONFIG BORV = VBOR_245
CONFIG ZCD = OFF
CONFIG PPS1WAY = OFF
CONFIG STVREN = OFF
CONFIG DEBUG = OFF
CONFIG XINST = OFF
CONFIG WDTCPS = WDTCPS_31
CONFIG WDTE = OFF
CONFIG WDTCWS = WDTCWS_7
CONFIG WDTCCS = LFINTOSC
CONFIG BBSIZE = BBSIZE_512
CONFIG BBEN = OFF
CONFIG SAFEN = OFF
CONFIG WRTAPP = OFF
CONFIG WRTB = OFF
CONFIG WRTC = OFF
CONFIG WRTD = OFF
CONFIG WRTSAF = OFF
CONFIG LVP = OFF
CONFIG CP = OFF
#ENDCONFIG

'Defines, Includes, and Constants-----------------------------------------------

DEFINE OSC 64 ' Calibrate PBP to 64MHz clock
OSCFRQ = 001000 ' Set system clock to 64MHz internal

on interrupt goto INC_TICK

'Direction----------------------------------------------------------------------

TRISA = 000000
TRISB = 000000
TRISC = 000000

'Alias---------------------------------------------------------------------------

LED VAr PORTA.1

'Variables----------------------------------------------------------------------

'Initialize Registers----------------------------------------------------------------------

Initilize:
ANSELA = 000000 ' Set digital
ANSELB = 000000 ' Set digital
ANSELC = 000000 ' Set digital
ADCON0 = 000000 ' Disable ADC

CM1CON0.7 = 0 : CM2CON0.7 = 0 'Disable comparators
PMD0=$FF : PMD1=$FF : PMD2=$FF
PMD3=$FF : PMD4=$FF : PMD5=$FF
PMD6=$FF : PMD7 = $FF
PMD1.bit1 = 0 'Turning on the TMR1 peripheral module

T1CON = 110000 'Prescale 1:8; Disable the TMR1
T1GCON.bit7 = 0 'Disable gate, TMR1 always counting
T1CLK = 000001 'Clock Source Fosc/4

TMR1H = $00 : TMR1L = $00

PIR4.bit0 = 0 'Clear the Int flag
PIE4.bit0 = 1 'Enable timer int
INTCON0.bit7 = 1 'Enable global int
T1CON.bit0 = 1 'Start the timer

LED = 0

'Code---------------------------------------------------------------------------

Main:
pause 1
Goto Main

'----- INTERRUPT CODE -------------------
Disable
INC_TICK:
toggle LED
TMR1L = $00 : TMR1H = $00
PIR4.bit0 = 0
Resume
enable
'------ END OF INTERRUPTS CODE ----------




I apologize for throwing two sets of code at you. I would be very happy if I could get either method to work. Software particulars: PBP 3.1.1.4; MPASM 5.0.0.5; MPLABX 5.76; Microcode Studio Plus 4.05. I am guessing I missed something or forgot to turn something on. I would love to learn more about "DEFINE INTHAND" but would be very happy to get any timer interrupt to work with any method possible at this point.

Any advice would be appreciated.

-Jon

HenrikOlsson
- 8th March 2018, 07:47
Hi,
I don't have a definitive answer for you but here's a couple of things.

First, if you haven't already, make SURE that you have Control of the pin where you have the LED connected. Make it blink a couple of times at startup or whatever.

In case there's something weird with the .BIT modifier I'd try the "standard" PIR4.0 syntax. I'm not sure it's even any difference under the hood but just to make sure.

In your main code, do:

IF PIR4.0 = 1 THEN
TOGGLE LED
PIR4.0 = 0
ENDIF
That'll tell you if the interrupt flag gets set or not.

/Henrik.

richard
- 8th March 2018, 09:48
your code would toggle led @32mS intervals , its a bit hard to see .
I can't compile pbp3 for this chip but can say that these settings work in xc8


#CONFIG
CONFIG FEXTOSC = OFF
CONFIG RSTOSC = HFINTOSC_64MHZ
CONFIG CLKOUTEN = OFF
CONFIG PR1WAY = OFF
CONFIG CSWEN = ON
CONFIG FCMEN = OFF
CONFIG MCLRE = INTMCLR
CONFIG PWRTS = PWRT_OFF
CONFIG MVECEN = OFF
CONFIG IVT1WAY = OFF
CONFIG LPBOREN = OFF
CONFIG BOREN = OFF
CONFIG BORV = VBOR_245
CONFIG ZCD = OFF
CONFIG PPS1WAY = OFF
CONFIG STVREN = OFF
CONFIG DEBUG = OFF
CONFIG XINST = OFF
CONFIG WDTCPS = WDTCPS_31
CONFIG WDTE = OFF
CONFIG WDTCWS = WDTCWS_7
CONFIG WDTCCS = LFINTOSC
CONFIG BBSIZE = BBSIZE_512
CONFIG BBEN = OFF
CONFIG SAFEN = OFF
CONFIG WRTAPP = OFF
CONFIG WRTB = OFF
CONFIG WRTC = OFF
CONFIG WRTD = OFF
CONFIG WRTSAF = OFF
CONFIG LVP = OFF
CONFIG CP = OFF
#ENDCONFIG

'Defines, Includes, and Constants-----------------------------------------------
DEFINE OSC 64 ' Calibrate PBP to 64MHz clock
OSCFRQ = 8 ' Set system clock to 64MHz internal
OSCCON1 = $60
on interrupt goto INC_TICK
'Direction----------------------------------------------------------------------
TRISA.1 = 0
'Alias---------------------------------------------------------------------------
LED VAR LATA.1
'Variables----------------------------------------------------------------------
'Initialize Registers----------------------------------------------------------------------
Initilize:
ANSELA = 0 ' Set digital

LED = 0

INTCON0.7 = 1 'Enable global int
T1CON = $35 'Prescale 1:8; enable the TMR1

T1CLK = 1 'Clock Source Fosc/4


PIR4.0 = 0 'Clear the Int flag
PIE4.0 = 1 'Enable timer int

'Start the timer
C0UNTER VAR BYTE

'Code---------------------------------------------------------------------------
Main:
pause 1
Goto Main
'----- INTERRUPT CODE -------------------
Disable
INC_TICK:
COUNTER=COUNTER+1
IF COUNTER==31 THEN
LED=!LED ;TOGGLE LED ONCE PER SEC
COUNTER=0
ENDIF

PIR4.0 = 0

Resume
enable

SecaRider
- 15th March 2018, 18:42
Sorry for the delay. I responded a week ago, but maybe I responded to the wrong post? Thank you for your feedback.

Henrik- As far as I know I have control of the LED pin, I made a simple blinky light to prove it to myself on that pin. I also implemented the startup blink as you’ve suggested just to make sure I didn’t change anything. I changed the bit syntax (which I like better) but no luck.

I also modified my code as you suggested, no luck. This must mean I didn’t set the interrupt, but I’m not sure what I am missing. I remember there used to be 3 int register bits that need to be set the peripheral, unmasked peripherals, and a global. Here I am only setting 2. Feels weird.

Richard- I agree the light blink is a bit quick. I have an oscilloscope I’m using on the pin to help me out. Originally, I was trying to interrupt on TMR0 with a prescale of 1:32768 and a TMR0H and TMR0L of $FE17 or about (if I did my math right) 1 second. No luck there either.

Thanks again for your feedback.

mpgmike
- 15th March 2018, 22:45
I would love to learn more about "DEFINE INTHAND" but would be very happy to get any timer interrupt to work with any method possible at this point.

SecaRider, my hat is off and a knee is bent to respect your tenacity tackling the new K42. For starters, practically all of the latest PIC offerings responded to the tweaks in the PIR/PIE listings for the DT_INTS-xx.bas routines. It was discussed previously that due to the extended memory range, the DT_INTS would require a much more intensive revamp to work with the K42 PICs.

With that said, "DEFINE INTHAND" is a DEFINE that directs the compiler to send the PC (Program Counter) to whatever you specify as your Interrupt Handler. Ultimately, with Vectored Interrupts turned off, that address will be 0x08. Universally agreed upon is the practice of placing your Interrupt Handler as close to the top of your Code Page as possible, with a command, "GOTO MAIN" (or START, or INIT) above your Interrupt Handler Label. DEFINE INTHAND is used only for Assembly Code interrupts. I don't know how proficient you are at ASM. There are work-arounds with w-save variables for "W", "BSR", "STATUS" and maybe some variables. Theoretically you could use INTHAND to go to an Interrupt Handler that uses PBP. The variables probably won't survive the RETURN intact (suggested by more skilled programmers in previous topics). If nothing else, you could INTHAND with your Interrupt Handler to "CALL" (ASM version of GOSUB) another PBP scripted subroutine.

The K42s are different enough from anything else ever created in the PIC 8-bit lineup that they must be treated carefully. I hope this helps point you in a better direction.

SecaRider
- 16th March 2018, 12:57
SecaRider, my hat is off and a knee is bent to respect your tenacity tackling the new K42.

mpgmike - I fear it is less about tenacity and more about stubbornness and a little bit of self loathing. :smile: Thank you for the synopsis on the "DEFINE INTHAND," this is very useful information. I have a working knowledge of ASM. To me, it is easier to read than write. Your post did indeed help me decide a newer direction...K40's! :smile: Thanks again.