PDA

View Full Version : TMR1 issue



Lestat
- 19th July 2012, 23:56
I'm trying to write a sample piece of code to explore the use of TMR1, I have TMR1 overflowing and triggering an interrupt which works. Though I appear to have an issue with setting up the Preload of the register. The TMR1 preload should be set up from the analogue input and then transferred later in the program to the TMR1 register. I have put an IF statement in the code to make the time that the LED, that is triggered by TMR1, stay on and off 10 times longer so any change in length caused by the preload is more noticeable.

The issue is, no matter how much I vary the voltage divider on the analogue input it doesn't appear to adjust how long it takes to turn the LED output on and off.

If anybody can give me some help with my code it would be highly appreciated.



clear
DEFINE OSC 8

'GP0 LED OUT
'GP1 AD1 FOR POT INPUT
'GP2 LED STATUS

'REGISTERS
OPTION_REG = %11000000
INTCON = %11000000
PIE1 = %01000001
PIR1 = %00000000
OSCCON = %01110001
TRISIO = %00000001
ANSEL = %01010001
'T1CON = %00110001
CCP1CON = %00000000
CMCON0 = %00000100

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

;---------------------------------------------------------------------------
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
'wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

'OUTPUT PINS
LEDOut VAR GPIO.0
LEDStatus VAR GPIO.2

T1CON = %00110001

'VARIABLES
LENGTH VAR WORD
PauseA var byte
PASS var byte

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _StateChange, PBP, yes
INT_Handler AD_INT, _PulseLength, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

ADCON0 = %00000111

'MAIN PROGRAM
MAIN:
pausea = 0
WHILE PauseA <= 100
PAUSEA = PAUSEA + 1
pause 1
wend
toggle ledstatus
GOTO MAIN

'SUB PROGRAMS
PulseLength:
LENGTH.highbyte = ADRESH 'SET UP THE TIMER SET UP VARIABLES
LENGTH.lowbyte = ADRESL
ADCON0 = %00000111
@ INT_RETURN ;RETURN

StateChange:
if pass=10 then
TOGGLE lEDOUT
pass = 0
else
pass = pass + 1
endif

TMR1H = LENGTH.highbyte 'Transfer the timer variables to the timer register
TMR1L = LENGTH.lowbyte
T1CON = %00010101
@ INT_RETURN ;RETURN
END

HenrikOlsson
- 20th July 2012, 06:12
I'm a bit surprised you're getting any interrupts tripped at all because I don't see anything that actually enables them. Well, I do see the setting of PIE1 and that might do it but with DT-INTS you usually do

@ INT_ENABLE TMR1_INT
@ INT_ENABLE AD_INT

Is your voltage divider connected to AN0?

Which chip are you using?

/Henrik.

Lestat
- 20th July 2012, 17:03
I am using a PIC12F683. Initially I had the voltage divider attached to AN0 but it is now connected AN1 and I changed the code to allow it to function while connected to that pin.

I didn't realise that I had to include the @ INT_ENABLE TMR1_INT and @ INT_ENABLE AD_INT lines as my previous code that included the DT-INTS didn't have those lines in. Please see: http://www.picbasic.co.uk/forum/showthread.php?t=16433

For Reference these pins are the inputs and the outputs:
'GP0 LED OUT
'GP1 AD1 FOR POT INPUT
'GP2 LED STATUS

I'll try adding the enable lines to the code, I'm also going to put the status LED on the analogue interrupt routine so I know that is triggering.

Thank you for your help

Lestat
- 20th July 2012, 19:32
I have put an extra LED into the circuit to monitor whether the Analogue Interrupt is being triggered, this LEDstatus1 (analogue interrupt sub program) does not seem to toggle. This leads to believe that the issue maybe to do with the analogue input not being read.



clear
DEFINE OSC 8

'GP0 LED OUT
'GP1 AD1 FOR POT INPUT
'GP2 LED STATUS
'GP5 LED STATUS 1

'REGISTERS
OPTION_REG = %11000000
INTCON = %11000000
PIE1 = %01000001
PIR1 = %00000000
OSCCON = %01110001
TRISIO = %00000001
ANSEL = %00100001
CCP1CON = %00000000
CMCON0 = %00000100

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

;---------------------------------------------------------------------------
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
'wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

'OUTPUT PINS
LEDOut VAR GPIO.0
LEDStatus VAR GPIO.2
LEDStatus1 var GPIO.5

high ledstatus
pause 500
low ledstatus
pause 1000
high ledstatus
pause 500
low ledstatus
T1CON = %00110001

'VARIABLES
LENGTH VAR WORD
PauseA var byte
PASS var byte

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _StateChange, PBP, yes
INT_Handler AD_INT, _PulseLength, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

@ INT_ENABLE TMR1_INT
@ INT_ENABLE AD_INT

ADCON0 = %00000111

'MAIN PROGRAM
MAIN:
pausea = 0
WHILE PauseA <= 10
PAUSEA = PAUSEA + 1
pause 1
wend
toggle ledstatus
GOTO MAIN

'SUB PROGRAMS
PulseLength:
LENGTH.highbyte = ADRESH 'SET UP THE TIMER SET UP VARIABLES
LENGTH.lowbyte = ADRESL
ADCON0 = %00000111
toggle ledstatus1
@ INT_RETURN ;RETURN

StateChange:
if pass = 10 then
TOGGLE lEDOUT
pass = 0
else
pass = pass + 1
endif

TMR1H = LENGTH.highbyte 'Transfer the timer variables to the timer register
TMR1L = LENGTH.lowbyte
T1CON = %00010101
@ INT_RETURN ;RETURN

END


If anybody can see any issues I would appreciate it

Thank you

HenrikOlsson
- 21st July 2012, 07:08
Hi,
The datasheet says not to set ADON and GO/DONE bits at the same time. I don't know why and I'd guess it's got nothing to do with the problem but you never know. First set up and turn on the ADC in your initialisation, then flip the GO/DONE bit (ADCON0.1 = 1) when you want to start a conversion.

Your comments in the code says the pot input is on GP1. The code does not set GP1 to input and does not set GP1 to analog. In a previous message though you said you had moved the pot input from GP1 to GP0 (which matches the TRIS and ANSEL setting) but if so it looks like your trying to sample the wrong input because ADCON0=%00000111 would sample GP1.

You also seams to have CM-/GP1/AN1 configured as input to the comparator - don't know if that may present a problem.

Well, not much concrete but atleast something to look into. I'd probably try getting the ADC running outside the interrupts to begin with it. Start it, poll the interrupt flag, get the result (or even use ADCIN for that matter). Then, when that works move it to interrupts.

BTW, you're currently trying to sample as fast as it can possible go. As soon as one conversion is done and serviced you start the next. You'll spend a lot of time jumping in and out of the AD interrupt routine that way and the value doesn't get used untill the timer overflows. Since the timer is only reloaded when it overflows why not sample the pot in the timer interrupt as well?

/Henrik.

Lestat
- 21st July 2012, 23:06
Success!

Henrik Thank you very much for your assistance. It looks like I need to spend more time and effort looking at and analysing my configuration registers. Though as you suggested it appears that if I set the various interrupt registers (INTCON and PIE1) you do not need the @ INT_ENABLE TMR1_INT and @ INT_ENABLE AD_INT lines (commented out below), maybe Darrel could shed some light on this? Though I must thank him for the DT-Ints code as it does appear to be excellent piece of code.

To confirm I initially intended to have the analogue attached to AN0 but moved it to AN1 due to realising that I could not have CMCON0 (bits 2-0) set that AN0 as an analogue input and GPIO.1 as a digital input and output. so I swapped them around and unfortunately didn't swap all of the settings in the configuration registers that I should have done.

I have attached the working code below for anyone to reference in the future.



clear
DEFINE OSC 8

'GP0 LED OUT
'GP1 AD1 FOR POT INPUT
'GP2 LED STATUS
'GP5 LED STATUS 1

'REGISTERS
OPTION_REG = %11000000
INTCON = %11000000
PIE1 = %01000001
PIR1 = %00000000
OSCCON = %01110001
TRISIO = %00000010
ANSEL = %00100010
CCP1CON = %00000000
CMCON0 = %00000100
ADCON0 = %00000101

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

;---------------------------------------------------------------------------
wsave VAR BYTE $20 SYSTEM ' location for W if in bank0
;wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
' Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using --
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
'wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
'wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
' --------------------------------------------------------------------------

'OUTPUT PINS
LEDOut VAR GPIO.0
LEDStatus VAR GPIO.2
LEDStatus1 var GPIO.5

high ledstatus
pause 500
low ledstatus
pause 1000
high ledstatus
pause 500
low ledstatus
T1CON = %00110001

'VARIABLES
LENGTH VAR WORD
PauseA var byte
PASS var byte

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _StateChange, PBP, yes
INT_Handler AD_INT, _PulseLength, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

'@ INT_ENABLE TMR1_INT
'@ INT_ENABLE AD_INT

ADCON0 = %00000111

'MAIN PROGRAM
MAIN:
pausea = 0
WHILE PauseA <= 100
PAUSEA = PAUSEA + 1
pause 1
wend
toggle ledstatus
GOTO MAIN

'SUB PROGRAMS
PulseLength:
LENGTH.highbyte = ADRESH 'SET UP THE TIMER SET UP VARIABLES
LENGTH.lowbyte = ADRESL
toggle ledstatus1
@ INT_RETURN ;RETURN

StateChange:
if pass = 5 then
TOGGLE lEDOUT
pass = 0
else
pass = pass + 1
endif

TMR1H = LENGTH.highbyte 'Transfer the timer variables to the timer register
TMR1L = LENGTH.lowbyte
T1CON = %00010101
ADCON0 = %00000111
@ INT_RETURN ;RETURN

END


Thank you again for your assistance, you have been a real help.

Andrew

aliciaDJones
- 29th August 2012, 15:41
I like the HTML coding and now a little bit about this but want to learn more abut HTML IS this tag is about HTML?