PDA

View Full Version : Timer1 Problem



fnovau
- 5th March 2008, 15:00
I try to measure time elapsed between two events using Timer1 : (when variable Estatus remains =1) I use Pic 16F677
I understand that overflow time of counter TM1 using 4 Mhz and Prescalers of 1, 2, 4, 8 should be 65, 131,262 and 524 msec but I always get a tick time of 76 msec in spite of using diferent prescalers through T1COM.4 and T1COM.5 settings
Can someone suggest any hint to explain and avoid it?
Regards
-Francesc

Here is my code:
DEFINE LCD_DREG PORTC 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portc connected to LCD DC4
DEFINE LCD_RSREG PORTC 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 3 'Define Portc pin used for RS connection
DEFINE LCD_EREG PORTC 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 2 'Define PortC pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.

@ DEVICE pic16F677, INTRC_OSC_NOCLKOUT
@ DEVICE pic16F677, WDT_ON
@ DEVICE pic16F677, BOD_ON
@ DEVICE pic16F677, PROTECT_OFF
@ DEVICE pic16F677, PWRT_ON
@ DEVICE pic16F677, MCLR_OFF

TRISA=%11111111 ' A Register as input
TRISB=%11111111 ' B Register as input
TRISC=%00000000 ' C Register as output
CM1CON0=0 ' Comparator disabled
CM2CON0=0 ' Comparator disabled
ANSEL=%00001111 ' analogic=1 digital=0
ANSELH=%1110100 ' analogic=1 digital=0
T1CON.3=1 ' Timer1 oscilator enable
T1CON.1=0 ' Internal clock Fosc/4

OT var PORTB.5 ' Entrada Obrir/Tancar diafragma
OShutter var PORTC.0 ' Sortida obrir shutter
TShutter Var PORTC.1 ' Sortida tancar shutter
Estatus var bit ' Estatus=1 diafragma obert
ShTemps var Word

INICI:
Pause 1000
lcdout $fe, 1 ' Clear LCD

Convertidor:
on interrupt goto tickcount
lcdout $FE, $80,"Test Timer1" ' Position cursor at home 1ª linea
Pause 300

SwitchOT:
while OT=1
goto convertidor
wend
Pause 20
If estatus=0 then
GOTO OpenShutter
Else
GOTO CloseShutter
endif
goto Convertidor

OpenShutter:
Oshutter=1
pause 50
Oshutter=0
Estatus=1 ' Shutter obert
INTCON.6=1 ' Enable all mask interrupts
INTCON.7=1 ' Enable global interrupts
T1CON.4=1 ' Prescaler timer=1:8
T1CON.5=1 ' Prescaler timer=1:8
PIE1.0=1 ' Enables TM1 overflow interrupt
T1CON.0=1 ' start TM1 clock
PIR1.0=0 ' Reset TM1 interrupt flag
LCDOUT $fe,$C0+13,40,32,41 '32=Tot Blanc
ShTemps=0
LCDOUT $fe,$C0," "
goto convertidor
CloseShutter:
TShutter=1
Pause 50
Tshutter=0
Estatus=0 ' Shutter tancat
T1CON.0=0 ' Stop Tm1 clock
INTCON.6=0 ' Disable all mask interrupts
INTCON.7=0 ' Disable global interrupts
LCDOUT $fe,$C0+13,40,255,41 '255=Tot Negre
goto convertidor

disable
Tickcount:
ShTemps=ShTemps+1
LCDOUT $fe,$C0,#ShTemps
resume
enable

end

skimask
- 5th March 2008, 15:13
My suggestion...
Get rid of the shutter code stuff...
Make TMR1 work for you first! Make an LED blink at the rates you want according to how you set up the prescaler. That way you'll know the interrupt functions are functioning as they should...
Then start adding things for measuring time and running a shutter.
What about ADCON0?
Turn off the WDT

fnovau
- 7th March 2008, 10:38
My suggestion...
Get rid of the shutter code stuff...
Make TMR1 work for you first! Make an LED blink at the rates you want according to how you set up the prescaler. That way you'll know the interrupt functions are functioning as they should...
Then start adding things for measuring time and running a shutter.
What about ADCON0?
Turn off the WDT

I wrote this new code trying to follow your hints but it does'nt work . I get a tick every 2.2 msec with a Prescaler (1:8) and the same value for prescaler (1:1)
Inputs and outputs and LCD work OK
The overflow time of TMR1 is always the same because the time externally controlled through leds is 27284 ticks every 60 sec -2.2 msec- and according to my numbers it should be about 524 msec for 4MHz and PS=1:8 so, I can not understand what happens.
Any hint?
-Francesc

Here is new code:
DEFINE LCD_DREG PORTC 'Define PIC port used for LCD Data lines
DEFINE LCD_DBIT 4 'Define first pin of portc connected to LCD DC4
DEFINE LCD_RSREG PORTC 'Define PIC port used for RS line of LCD
DEFINE LCD_RSBIT 3 'Define Portc pin used for RS connection
DEFINE LCD_EREG PORTC 'Define PIC prot used for E line of LCD
DEFINE LCD_EBIT 2 'Define PortC pin used for E connection
DEFINE LCD_BITS 4 'Define the 4 bit communication mode to LCD
DEFINE LCD_LINES 2 'Define using a 2 line LCD
DEFINE LCD_COMMANDUS 2000 'Define delay time between sending LCD commands
DEFINE LCD_DATAUS 50 'Define delay time between data sent.

@ DEVICE pic16F677, INTRC_OSC_NOCLKOUT
@ DEVICE pic16F677, WDT_ON
@ DEVICE pic16F677, BOD_ON
@ DEVICE pic16F677, PROTECT_OFF
@ DEVICE pic16F677, PWRT_ON
@ DEVICE pic16F677, MCLR_OFF

TRISA=%11111111 ' A Register as input
TRISB=%11111111 ' B Register as input
TRISC=%00000000 ' C Register as output
CM1CON0=0 ' Comparator disabled
CM2CON0=0 ' Comparator disabled
ANSEL=%00001111 ' analogic=1 digital=0
ANSELH=%1110100 ' analogic=1 digital=0
T1CON.3=1 ' Timer1 oscilator enable
T1CON.1=0 ' Internal clock Fosc/4

O var PORTB.5 ' Entrada Obrir diafragma
OShutter var PORTC.0 ' Sortida obrir shutter
TShutter Var PORTC.1 ' Sortida tancar shutter
Estatus var bit ' Estatus=1 diafragma obert
ShTemps var Word
T var PortB.6 'entrada tancar diafragma
INICI:
Pause 1000
lcdout $fe, 1 ' Clear LCD
TShutter=1
Pause 10
Tshutter=0
Estatus=0 ' diafragma tancat
lcdout $FE, $80,"Test Timer1" ' Position cursor at home 1ª linea
Convertidor:
on interrupt goto tickcount
If Estatus=0 then
GOTO SwitchO
else
Goto SwitchT
endif

SwitchO: 'switch for start timer
while O=1
goto convertidor
wend
Pause 20
If estatus=0 then
GOTO OpenShutter

endif
goto Convertidor

SwitchT: 'switch for stop timer
while T=1
goto convertidor
wend
Pause 20
If estatus=1 then
GOto CloseShutter
endif
goto Convertidor
OpenShutter:
Oshutter=1 ' Blink led for external control
pause 20 ' Blink led for external control
Oshutter=0 ' Blink led for external control
Estatus=1 ' Shutter obert
LCDOUT $fe,$C0," "
LCDOUT $fe,$C0+13,40,32,41 '32=Tot Blanc
ShTemps=0
TMR1L=0
TMR1H=0
INTCON.6=1 ' Enable all mask interrupts
INTCON.7=1 ' Enable global interrupts
T1CON.4=1 ' Prescaler timer=1:8
T1CON.5=1 ' Prescaler timer=1:8
T1CON.3=0 '
PIE1.0=1 ' Enables TM1 overflow interrupt
T1CON.0=1 ' start TM1 clock
PIR1.0=0 ' Reset TM1 interrupt flag
goto convertidor
CloseShutter:
TShutter=1 ' Blink led for external control
Pause 10 ' Blink led for external control
Tshutter=0 ' Blink led for external control
Estatus=0 ' Shutter tancat
T1CON.0=0 ' Stop Tm1 clock
INTCON.6=0 ' Disable all mask interrupts
INTCON.7=0 ' Disable global interrupts
LCDOUT $fe,$C0+13,40,255,41 '255=Tot Negre
LCDOUT $fe,$C0,#ShTemps ' display
goto convertidor

disable
Tickcount:
ShTemps=ShTemps+1
LCDOUT $fe,$C0,#ShTemps ' display
resume
enable

end

skimask
- 7th March 2008, 14:13
I wrote this new code trying to follow your hints but it does'nt work
Turn off the WDT.

fnovau
- 8th March 2008, 10:39
Turn off the WDT.

I get the same results ¡¡

fnovau
- 8th March 2008, 17:15
At last program begins to work when I place
PIR1.0=0 ' Reset TM1 interrupt flag
into Tickcount ISR giving overflow times of 65.8/132/263.6 and 524.7 msec according with Prescaler.
WDT_ON or WDT_OFF apparently does not change results

Tickcount:
ShTemps=ShTemps+1
LCDOUT $fe,$C0,#ShTemps ' display
resume
enable

Thank you Skimask for your help
-Francesc