I have a very odd behaviour in a 16F1827, it is a simple 3 digit countdown clock (seconds).
I set up the TMR1 values and create an interrupt routine that decrements a variable from 59 to 0.
So far so good, but, and this is the strange thing, when i program the chip works OK, but if y disconect the PicKit3 and cycle the power suply all the display routines work OK, but it doesn't start to count down.
Any ideas?
Thanks!!!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The Great Carnac says that the MCLR, PGD, PGC lines are going to have weak pullups when the Pickit3 is attached and not when removed. So, remove any input or logic conditions from these lines if possible.
Show the code, because the great Karnac is not a good guesser :)
edit: spelling
Last edit: kent_twt4 2017-10-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
TMR1H = TempTime_h 'saca el byte superior y deja el byte inferior
TMR1L = TempTime
gie=0
ClearTimer 1
segundos =0
On Interrupt Timer1Overflow Call TICKS
Main:
SEGUNDOS=59
TONE 3000,20
'StartTimer 1
'IntOn
GIE=1
T1CON.0=1
do
NUMBER=segundos
'if minutos<=0 then number=segundos
CALL CONVERT
if blinker = 1 then num3=31
if blinker =0 then num3=16
'flag.0=0'lefmostCH Off
PausaRepeat=1
saca
Loop
END
'--------------SUBRUTINAS
SUB TICKS
TempTime=15536' 100 ms
TMR1H = TempTime_h
TMR1L = TempTime '
TMR1IF=0
milis=milis+1
' 1pulso por cada 100 ms
IF MILIS= 10 THEN
MILIS=0
SEGUNDOS=SEGUNDOS-1
blinker=!blinker
START_frame=1
IF SEGUNDOS<=0 THEN
SEGUNDOS=59
minutos=minutos-1
END IF
END IF
END SUB
;------------------SUB LECTURA TENSION
;--------------------SUB CONVERT
Sub convert' convierte el valor saca NUM 1,2,3 (BCD)
Num2 = 0
Num3 = 0
If number >= 100 Then
Num3 = number / 100
number = SysCalcTempX
End if
If number >= 10 Then
Num2 = number / 10
number = SysCalcTempX
end if
Num1 = number
end sub
;------------------------------------------------
sub SACA
DIR PORTB OUT
'wait 10 ms
Repeat PausaRepeat
ReadTable DIGITOS,Num1+1 , Temp
latb= temp
set Sel_1 OFF
wait 7 ms
set Sel_1 ON
temp=0
ReadTable DIGITOS,Num2+1 , Temp
if flag.1=1 then temp.7=0' goto sinpunto 'bit 1 de FLAG selecciona punto (1=si 0=no)
'sinpunto:
latb= temp
set Sel_2 OFF
wait 7 ms
set Sel_2 ON
temp=0
if flag.0=1 then goto Nocl 'bit 0 de FLAG selecciona borrado 1er digito (1=si 0=no)
if Num3 <= 0 then num3=23
Nocl:
ReadTable DIGITOS,Num3+1 , Temp
if flag.2=1 then temp.7=0 ' goto sinpuntoD1 'bit 1 de FLAG selecciona punto (1=si 0=no)
latb= temp
set Sel_3 OFF
wait 7 ms
set Sel_3 ON
temp=0
end Repeat
it is working properly, and I've tried all the obvious solutions like, MCLR on and off, pull ups (10K) on RB6, RB7 and MCLR, so I'm kind of lost!
I'LL appreciate any help!!!!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
NEWS FLASH!!, I've found that TMR1 actually works(changed my var SEGUNDOS by TMR1L), my problem is the interrupt!!!
Tried INT init just as the datasheet says, but no luck. There's something that I can't see...
Last edit: Leonardo Cei 2017-10-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It took me a bit to figure this out. But basically your "milis" variable in Ticks was dimensioned as a Word and it was not initialized at the beginning like secundos was, so it could possibly take a very long time for the milis variable to overflow and get back on schedule!
Trust GCB to correctly set the gie, pie, pir registers correctly in most cases. Also can use the GCB syntax like in Help to set up the Timer1 interrupt. Lots of housekeeping can be done to clean up the rest of the code.
Here is the shorthand Timer1 setup code:
dim milis as Byte '<<==== not required unless using Option Explicit
dim temptime as Word
InitTimer1 OSC, PS1_8
ClearTimer 1
TempTime=15536' 100 ms
TMR1H = TempTime_h 'saca el byte superior y deja el byte inferior
TMR1L = TempTime
StartTimer 1
'initialize variable in Ticks
milis = 0 '<<======
segundos =0
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you Kent, I'll try it tomorrow, sounds correct and hope I can work it out, because this is the only part of a bigger program which doesn't work!
Milis as word is heritage from another TICKS Sub, where counted to 10000!!!
I will follow your advice and give a try of setting TMR1 with SetTimer, ClearTimer and StartTimer.
By the way, if I use several interrupts, IntOn and IntOff are like GIE=1 and GIE=0? So, must use a specific event control for everyone of the INTs? Best Regards.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes the IntOn and IntOff controls the GIE bit, so you will still have to manually control the individual peripheral interrupt enable bits if so needed.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have a very odd behaviour in a 16F1827, it is a simple 3 digit countdown clock (seconds).
I set up the TMR1 values and create an interrupt routine that decrements a variable from 59 to 0.
So far so good, but, and this is the strange thing, when i program the chip works OK, but if y disconect the PicKit3 and cycle the power suply all the display routines work OK, but it doesn't start to count down.
Any ideas?
Thanks!!!
The Great Carnac says that the MCLR, PGD, PGC lines are going to have weak pullups when the Pickit3 is attached and not when removed. So, remove any input or logic conditions from these lines if possible.
Show the code, because the great Karnac is not a good guesser :)
edit: spelling
Last edit: kent_twt4 2017-10-02
Need to see your code. (All of it.)
here is the code:
'Chip model
chip 16f1827,16
config INTOSC_OSC_NOCLKOUT'
config CPD = On
config CP = On
'#config BOREN = On
config MCLRE = ON
config PWRTE = ON
config WDTE = OFF
ADCON0=0''' b'00001001'
'CMCON = 7
OPTION_REG.7=0
define SoundOut PORTA.3
define Sel_1 LATA.0
define Sel_2 LATA.7
define Sel_3 LATA.6
Dir PORTA.0 out
Dir PORTA.1 OUT
Dir PORTA.2 In
Dir PORTA.5 In
dim count as WORD
dim number as word
DIR PORTB OUT
flag=b'00000011'
dim trabajo as Word
define START_STOP FLAG2.0
define ST_STP_KEY FLAG2.1
define salida FLAG2.2
define APAGADO FLAG2.3
define BLINKER FLAG2.4
define START_frame flag2.5
DIM MILIS AS Word
dim temptime as Word
T1CON.T1CKPS1=1 'PRESC 1/8
T1CON.T1CKPS0=1
T1CON.T1OSCEN=0 'CLK DIS'T1CON.T1SYNC=1 'CLK SYNC DIS
T1CON.6=0 :T1CON.7=0 'SOURCE INTERNAL CLK
T1CON.0=0 ' 1 ENCIENDE 0 APAGA
'usar TMR1, PRESCALER 1/8
'6250080.2=1.00000 S
TempTime=15536' 100 ms
TMR1H = TempTime_h 'saca el byte superior y deja el byte inferior
TMR1L = TempTime
gie=0
ClearTimer 1
segundos =0
On Interrupt Timer1Overflow Call TICKS
Main:
SEGUNDOS=59
TONE 3000,20
'StartTimer 1
'IntOn
GIE=1
T1CON.0=1
do
Loop
END
'--------------SUBRUTINAS
SUB TICKS
TempTime=15536' 100 ms
TMR1H = TempTime_h
TMR1L = TempTime '
TMR1IF=0
milis=milis+1
' 1pulso por cada 100 ms
IF MILIS= 10 THEN
MILIS=0
SEGUNDOS=SEGUNDOS-1
blinker=!blinker
START_frame=1
END IF
END SUB
;------------------SUB LECTURA TENSION
;--------------------SUB CONVERT
Sub convert' convierte el valor saca NUM 1,2,3 (BCD)
end sub
;------------------------------------------------
sub SACA
DIR PORTB OUT
'wait 10 ms
end sub
'FIN DE SUBRUTINAS
'pCDEBAFG
'TABLA DE DEFINICION DE DIGITOS
Table DIGITOS
b'10000001' ;0
b'10110111' ;1
b'11000010' ;2
b'10010010' ;3
b'10110100' ;4
b'10011000' ;5
b'10001000' ;6
b'10110011' ;7
b'10000000' ;8
b'10010000' ;9
b'11001001' ;C 10
b'10100000' ;A 11
b'10101110' ;n 12
b'11001000' ;e 13
b'11101110' ;r 14
b'10001100' ;b 15
b'10001110' ;o 16
b'11001100' ;t 17
b'10001111' ;u 18
b'11100000' ;P 19
b'11001110' ;[ 20
b'10011110' ;]'21
b'11011010' ;TRIGUAL 22 'pCDEBAFG
b'11111111' ;BL 23
b'11001101' ;L 24
b'11101111' ;i 25
b'10100100' ;H 26
b'10001100' ;b 27
b'10000111' ;J 28
b'11101000' ;F 29
b'11001000' ;E 30
b'11110000' ;* 31
End Table
it is working properly, and I've tried all the obvious solutions like, MCLR on and off, pull ups (10K) on RB6, RB7 and MCLR, so I'm kind of lost!
I'LL appreciate any help!!!!
NEWS FLASH!!, I've found that TMR1 actually works(changed my var SEGUNDOS by TMR1L), my problem is the interrupt!!!
Tried INT init just as the datasheet says, but no luck. There's something that I can't see...
Last edit: Leonardo Cei 2017-10-02
It took me a bit to figure this out. But basically your "milis" variable in Ticks was dimensioned as a Word and it was not initialized at the beginning like secundos was, so it could possibly take a very long time for the milis variable to overflow and get back on schedule!
Trust GCB to correctly set the gie, pie, pir registers correctly in most cases. Also can use the GCB syntax like in Help to set up the Timer1 interrupt. Lots of housekeeping can be done to clean up the rest of the code.
Here is the shorthand Timer1 setup code:
Thank you Kent, I'll try it tomorrow, sounds correct and hope I can work it out, because this is the only part of a bigger program which doesn't work!
Milis as word is heritage from another TICKS Sub, where counted to 10000!!!
I will follow your advice and give a try of setting TMR1 with SetTimer, ClearTimer and StartTimer.
By the way, if I use several interrupts, IntOn and IntOff are like GIE=1 and GIE=0? So, must use a specific event control for everyone of the INTs? Best Regards.
Yes the IntOn and IntOff controls the GIE bit, so you will still have to manually control the individual peripheral interrupt enable bits if so needed.
It worked!!!! I can't be more happy and gratefull about GCbasic and this amazing comunity, and specially to Kent who helped me, A LOT!!