here is what i have, I left out the extra subs that are unrelated to the problem, it only sends out zero values and never increments the count.
#chip 12F683, 18
#config MCLRE=off, WDT=off
Ser_Init
on interrupt Timer1Overflow call IncCounter
dim serun as byte
dim serdec as byte
dim sercen as byte
dim sermil as byte
dim serdecimil as byte
InitTimer1 ExtOsc, PS1_8
dim full as byte
dim min as byte
dim sec as byte
dim hr as byte
full = 0
sec=0
min=0
hr=0
wait 1 s
ClearTimer 1
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 36
TMR1L = 13 'should be 10hz
StartTimer 1
main:
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
bin2ascii (hr)
xmit_print (":")
bin2ascii (min)
xmit_print (":")
bin2ascii (sec)
wait 250 ms
xmit_rs232 12
xmit_rs232 13
goto main
Sub IncCounter
TMR1L = 0
TMR1H = 255
TMR1L = 82
full=full+1
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The Main routine takes too long to run.
The interrupts will occur 10 times a second, which is every 100 ms
but the main routine takes 250 ms+ to run.
It will never see full get to 10.
Either get rid of the wait 250 ms line in the main routine , or reduce the interrupt rate so that the interrupts occur slower.
If you are trying to build a clock, why not simply interrupt once a second.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
1) You must place second , minutes and hours calculations in your Sub IncCounter :
After full=full+1
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
because if your main program is too long because a too long data transmission your calculations aren't taken into account !
2) If loop is too long and PIC doesn't transmits anything , errors may be in differents subs as Ser_init ,xmit_print or bin2ascii
GC
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Also, where is the clock for the PIC coming from.
There doesnt appear to be any clock definition in the code.
To make a clock that keeps time , you must use an external crystal
as the internal RC oscillator isnt stable enough.
Its only 1% accurate.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I still only get "00:00:00" transmitted to the pc over and over never incriments?
here is the whole code:
#chip 12F683, 18
#config MCLRE=off, WDT=off
Ser_Init
on interrupt Timer1Overflow call IncCounter
dim serun as byte
dim serdec as byte
dim sercen as byte
dim sermil as byte
dim serdecimil as byte
InitTimer1 ExtOsc, PS1_8
dim full as byte
dim min as byte
dim sec as byte
dim hr as byte
full = 0
sec=0
min=0
hr=0
wait 1 s
ClearTimer 1
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 36
TMR1L = 13 'should be 10hz
StartTimer 1
main:
bin2ascii (hr)
xmit_print (":")
bin2ascii (min)
xmit_print (":")
bin2ascii (sec)
wait 10 ms
xmit_rs232 12
xmit_rs232 13
goto main
Sub IncCounter
ClearTimer 1
TMR1L = 0
TMR1H = 36
TMR1L = 13
StartTimer 1
full=full+1
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
end sub
Sub Ser_Init
;slight adjustment was required for 9600bps delay value
#define baud 103 ;expressed as frequency in us
#define halfbaud 52 ;place Read of SerRx in middle of bit
#define SerTxHigh Set GPIO.0 On
#define SerTxLow Set GPIO.0 Off
#define SerRx GPIO.1
dir GPIO.0 out ;Tx
dir GPIO.1 in ;Rx
SerTxHigh ;Initial RS232 idle state
end sub
sub XMIT_PRINT (PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
XMIT_RS232(PrintData(SysPrintTemp))
next
end sub
Sub XMIT_RS232(Xmit_Byte)#NR
SerTxLow
wait baud us
For cntr = 1 to 8
Rotate Xmit_Byte Right
If Status.C ON Then SerTxHigh
If Status.C Off Then SerTxLow
wait baud us
Next
SerTxHigh
wait baud us
end sub
sub bin2ascii (LCDValue as word ) #NR
Dim SysCalcTempX As Word
LCDValueTemp = 0
LCDShowChar = 0
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
If LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000
LCDValue = SysCalcTempX
SERDECMIL = LCDValueTemp + 48
Xmit_RS232 (SERDECMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 1000 then
LCDValueTemp = LCDValue / 1000
LCDValue = SysCalcTempX
SERMIL = LCDValueTemp + 48
Xmit_RS232 (SERMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 100 then
LCDValueTemp = LCDValue / 100
LCDValue = SysCalcTempX
SERCEN = LCDValueTemp + 48
Xmit_RS232 (SERCEN)
LCDShowChar = TRUE
End If
'If LCDShowChar > 0 or LCDValue >= 10 then
LCDValueTemp = LCDValue / 10
LCDValue = SysCalcTempX
SERDEC = LCDValueTemp + 48
Xmit_RS232 (SERDEC)
'End If
SERUN = LCDValue + 48
Xmit_RS232 (SERUN)
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In order to get glitch free output, I think the main program should also be in the isr (no wait states here). Just output every sec (i.e. when "full " rolls over). If the Uart routine is also going to be used in main then their will be glitches.
so I made the changes you suggested above and have the following code, but i get no output at all, so my guess is the timer1 is not running and full is never reaching 10 and tx never happens.
#chip 12F683, 18
#config MCLRE=off, WDT=off
Ser_Init
on interrupt Timer1Overflow call IncCounter
dim serun as byte
dim serdec as byte
dim sercen as byte
dim sermil as byte
dim serdecimil as byte
InitTimer1 ExtOsc, PS1_8
dim full as byte
dim min as byte
dim sec as byte
dim hr as byte
full = 0
sec=0
min=0
hr=0
wait 1 s
ClearTimer 1
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 36
TMR1L = 13 'should be 10hz
StartTimer 1
main:
goto main
Sub IncCounter
ClearTimer 1
TMR1L = 0
TMR1H = 36
TMR1L = 13
StartTimer 1
full=full+1
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
if full = 0 then
'if hr < 10 then xmit_print ("0")
bin2ascii (hr)
xmit_print (":")
'if min < 10 then xmit_print ("0")
bin2ascii (min)
xmit_print (":")
'if sec < 10 then xmit_print ("0")
bin2ascii (sec)
xmit_rs232 10
xmit_rs232 13
end if
end sub
Sub Ser_Init
;slight adjustment was required for 9600bps delay value
#define baud 103 ;expressed as frequency in us
#define halfbaud 52 ;place Read of SerRx in middle of bit
#define SerTxHigh Set GPIO.0 On
#define SerTxLow Set GPIO.0 Off
#define SerRx GPIO.1
dir GPIO.0 out ;Tx
dir GPIO.1 in ;Rx
SerTxHigh ;Initial RS232 idle state
end sub
sub XMIT_PRINT (PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
XMIT_RS232(PrintData(SysPrintTemp))
next
end sub
Sub XMIT_RS232(Xmit_Byte)#NR
SerTxLow
wait baud us
For cntr = 1 to 8
Rotate Xmit_Byte Right
If Status.C ON Then SerTxHigh
If Status.C Off Then SerTxLow
wait baud us
Next
SerTxHigh
wait baud us
end sub
sub bin2ascii (LCDValue as word ) #NR
Dim SysCalcTempX As Word
LCDValueTemp = 0
LCDShowChar = 0
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
If LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000
LCDValue = SysCalcTempX
SERDECMIL = LCDValueTemp + 48
Xmit_RS232 (SERDECMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 1000 then
LCDValueTemp = LCDValue / 1000
LCDValue = SysCalcTempX
SERMIL = LCDValueTemp + 48
Xmit_RS232 (SERMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 100 then
LCDValueTemp = LCDValue / 100
LCDValue = SysCalcTempX
SERCEN = LCDValueTemp + 48
Xmit_RS232 (SERCEN)
LCDShowChar = TRUE
End If
'If LCDShowChar > 0 or LCDValue >= 10 then
LCDValueTemp = LCDValue / 10
LCDValue = SysCalcTempX
SERDEC = LCDValueTemp + 48
Xmit_RS232 (SERDEC)
'End If
SERUN = LCDValue + 48
Xmit_RS232 (SERUN)
End Sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Really should use the code tags. Copy and pasting native text is in some sort of weird format, and doesn't seem to compile.
You could try the internal 4Mhz osc as a test, just to see if there's output.
I became frustrated with the results from the TMR1 register, and interrupts. Moved over to CCP1, in the software interrupt mode, so everything is Main now. The results seem much better, although not great. For an accurate clock I've used the ds1307 in the past.
Good luck.
Kent.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Ive made several clocks using 16F88 with a low frequency clock crystal (2 Mhz)
which allows you to use a 1 hz tick interrupt to do the counting.
Ideally also, if you want to use a serial output for the data its best to use a chip
with a hardware uart, so that the interrupts dont glitch the output characters.
The timer overflow concept to interrupt should work ok as long as you keep the code within
the interrupt routine at a minimum.
There is a simple example that comes with the GCbasic install called interrupt that explains
how to use the timer overflow to count .
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I think you configured Timer1 to use external clock:
InitTimer1 ExtOsc, PS1_8
Exists that external clock??
That's not the clock you use for PIC, its a dedicated ext. clock, ussually 32.768 KHz for real time, that should be connected to T1OSI and T1OSO pins.
If you want to use the same clock the cpu, then configure this way:
InitTimer1 Osc, PS1_8
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
here is what i have, I left out the extra subs that are unrelated to the problem, it only sends out zero values and never increments the count.
#chip 12F683, 18
#config MCLRE=off, WDT=off
Ser_Init
on interrupt Timer1Overflow call IncCounter
dim serun as byte
dim serdec as byte
dim sercen as byte
dim sermil as byte
dim serdecimil as byte
InitTimer1 ExtOsc, PS1_8
dim full as byte
dim min as byte
dim sec as byte
dim hr as byte
full = 0
sec=0
min=0
hr=0
wait 1 s
ClearTimer 1
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 36
TMR1L = 13 'should be 10hz
StartTimer 1
main:
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
bin2ascii (hr)
xmit_print (":")
bin2ascii (min)
xmit_print (":")
bin2ascii (sec)
wait 250 ms
xmit_rs232 12
xmit_rs232 13
goto main
Sub IncCounter
TMR1L = 0
TMR1H = 255
TMR1L = 82
full=full+1
end sub
The Main routine takes too long to run.
The interrupts will occur 10 times a second, which is every 100 ms
but the main routine takes 250 ms+ to run.
It will never see full get to 10.
Either get rid of the wait 250 ms line in the main routine , or reduce the interrupt rate so that the interrupts occur slower.
If you are trying to build a clock, why not simply interrupt once a second.
i can't get get it down to 1hz speed, the lowest it will go is 8.xxhz
1) You must place second , minutes and hours calculations in your Sub IncCounter :
After full=full+1
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
because if your main program is too long because a too long data transmission your calculations aren't taken into account !
2) If loop is too long and PIC doesn't transmits anything , errors may be in differents subs as Ser_init ,xmit_print or bin2ascii
GC
Also, where is the clock for the PIC coming from.
There doesnt appear to be any clock definition in the code.
To make a clock that keeps time , you must use an external crystal
as the internal RC oscillator isnt stable enough.
Its only 1% accurate.
how fast is your external osc running?
"#chip 12F683, 18 "
is it a 18 mhz crystal?
If your doing RTC things a 32khz clock crystal is usually used. Run on internal osc for the main.
Also where are you reseting the Timer1 ovrflow flag?
I still only get "00:00:00" transmitted to the pc over and over never incriments?
here is the whole code:
#chip 12F683, 18
#config MCLRE=off, WDT=off
Ser_Init
on interrupt Timer1Overflow call IncCounter
dim serun as byte
dim serdec as byte
dim sercen as byte
dim sermil as byte
dim serdecimil as byte
InitTimer1 ExtOsc, PS1_8
dim full as byte
dim min as byte
dim sec as byte
dim hr as byte
full = 0
sec=0
min=0
hr=0
wait 1 s
ClearTimer 1
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 36
TMR1L = 13 'should be 10hz
StartTimer 1
main:
bin2ascii (hr)
xmit_print (":")
bin2ascii (min)
xmit_print (":")
bin2ascii (sec)
wait 10 ms
xmit_rs232 12
xmit_rs232 13
goto main
Sub IncCounter
ClearTimer 1
TMR1L = 0
TMR1H = 36
TMR1L = 13
StartTimer 1
full=full+1
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
end sub
Sub Ser_Init
;slight adjustment was required for 9600bps delay value
#define baud 103 ;expressed as frequency in us
#define halfbaud 52 ;place Read of SerRx in middle of bit
#define SerTxHigh Set GPIO.0 On
#define SerTxLow Set GPIO.0 Off
#define SerRx GPIO.1
dir GPIO.0 out ;Tx
dir GPIO.1 in ;Rx
SerTxHigh ;Initial RS232 idle state
end sub
sub XMIT_PRINT (PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
XMIT_RS232(PrintData(SysPrintTemp))
next
end sub
Sub XMIT_RS232(Xmit_Byte)#NR
SerTxLow
wait baud us
For cntr = 1 to 8
Rotate Xmit_Byte Right
If Status.C ON Then SerTxHigh
If Status.C Off Then SerTxLow
wait baud us
Next
SerTxHigh
wait baud us
end sub
sub bin2ascii (LCDValue as word ) #NR
Dim SysCalcTempX As Word
LCDValueTemp = 0
LCDShowChar = 0
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
If LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000
LCDValue = SysCalcTempX
SERDECMIL = LCDValueTemp + 48
Xmit_RS232 (SERDECMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 1000 then
LCDValueTemp = LCDValue / 1000
LCDValue = SysCalcTempX
SERMIL = LCDValueTemp + 48
Xmit_RS232 (SERMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 100 then
LCDValueTemp = LCDValue / 100
LCDValue = SysCalcTempX
SERCEN = LCDValueTemp + 48
Xmit_RS232 (SERCEN)
LCDShowChar = TRUE
End If
'If LCDShowChar > 0 or LCDValue >= 10 then
LCDValueTemp = LCDValue / 10
LCDValue = SysCalcTempX
SERDEC = LCDValueTemp + 48
Xmit_RS232 (SERDEC)
'End If
SERUN = LCDValue + 48
Xmit_RS232 (SERUN)
End Sub
In order to get glitch free output, I think the main program should also be in the isr (no wait states here). Just output every sec (i.e. when "full " rolls over). If the Uart routine is also going to be used in main then their will be glitches.
Kent
so I made the changes you suggested above and have the following code, but i get no output at all, so my guess is the timer1 is not running and full is never reaching 10 and tx never happens.
#chip 12F683, 18
#config MCLRE=off, WDT=off
Ser_Init
on interrupt Timer1Overflow call IncCounter
dim serun as byte
dim serdec as byte
dim sercen as byte
dim sermil as byte
dim serdecimil as byte
InitTimer1 ExtOsc, PS1_8
dim full as byte
dim min as byte
dim sec as byte
dim hr as byte
full = 0
sec=0
min=0
hr=0
wait 1 s
ClearTimer 1
TMR1L = 0 'Need to do this according to the PIC datasheet
TMR1H = 36
TMR1L = 13 'should be 10hz
StartTimer 1
main:
goto main
Sub IncCounter
ClearTimer 1
TMR1L = 0
TMR1H = 36
TMR1L = 13
StartTimer 1
full=full+1
if full = 10 then
sec=sec+1
full=0
end if
if sec = 60 then
min= min+1
sec=0
end if
if min= 60 then
hr=hr+1
min=0
end if
if hr=25 then hr=0
if full = 0 then
'if hr < 10 then xmit_print ("0")
bin2ascii (hr)
xmit_print (":")
'if min < 10 then xmit_print ("0")
bin2ascii (min)
xmit_print (":")
'if sec < 10 then xmit_print ("0")
bin2ascii (sec)
xmit_rs232 10
xmit_rs232 13
end if
end sub
Sub Ser_Init
;slight adjustment was required for 9600bps delay value
#define baud 103 ;expressed as frequency in us
#define halfbaud 52 ;place Read of SerRx in middle of bit
#define SerTxHigh Set GPIO.0 On
#define SerTxLow Set GPIO.0 Off
#define SerRx GPIO.1
dir GPIO.0 out ;Tx
dir GPIO.1 in ;Rx
SerTxHigh ;Initial RS232 idle state
end sub
sub XMIT_PRINT (PrintData$)
PrintLen = PrintData(0)
if PrintLen = 0 then exit sub
'Write Data
for SysPrintTemp = 1 to PrintLen
XMIT_RS232(PrintData(SysPrintTemp))
next
end sub
Sub XMIT_RS232(Xmit_Byte)#NR
SerTxLow
wait baud us
For cntr = 1 to 8
Rotate Xmit_Byte Right
If Status.C ON Then SerTxHigh
If Status.C Off Then SerTxLow
wait baud us
Next
SerTxHigh
wait baud us
end sub
sub bin2ascii (LCDValue as word ) #NR
Dim SysCalcTempX As Word
LCDValueTemp = 0
LCDShowChar = 0
SERDECMIL = 0
SERMIL = 0
SERCEN = 0
SERDEC = 0
SERUN = 0
If LCDValue >= 10000 then
LCDValueTemp = LCDValue / 10000
LCDValue = SysCalcTempX
SERDECMIL = LCDValueTemp + 48
Xmit_RS232 (SERDECMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 1000 then
LCDValueTemp = LCDValue / 1000
LCDValue = SysCalcTempX
SERMIL = LCDValueTemp + 48
Xmit_RS232 (SERMIL)
LCDShowChar = TRUE
End If
If LCDShowChar > 0 or LCDValue >= 100 then
LCDValueTemp = LCDValue / 100
LCDValue = SysCalcTempX
SERCEN = LCDValueTemp + 48
Xmit_RS232 (SERCEN)
LCDShowChar = TRUE
End If
'If LCDShowChar > 0 or LCDValue >= 10 then
LCDValueTemp = LCDValue / 10
LCDValue = SysCalcTempX
SERDEC = LCDValueTemp + 48
Xmit_RS232 (SERDEC)
'End If
SERUN = LCDValue + 48
Xmit_RS232 (SERUN)
End Sub
Really should use the code tags. Copy and pasting native text is in some sort of weird format, and doesn't seem to compile.
You could try the internal 4Mhz osc as a test, just to see if there's output.
I became frustrated with the results from the TMR1 register, and interrupts. Moved over to CCP1, in the software interrupt mode, so everything is Main now. The results seem much better, although not great. For an accurate clock I've used the ds1307 in the past.
Good luck.
Kent.
Ive made several clocks using 16F88 with a low frequency clock crystal (2 Mhz)
which allows you to use a 1 hz tick interrupt to do the counting.
Ideally also, if you want to use a serial output for the data its best to use a chip
with a hardware uart, so that the interrupts dont glitch the output characters.
The timer overflow concept to interrupt should work ok as long as you keep the code within
the interrupt routine at a minimum.
There is a simple example that comes with the GCbasic install called interrupt that explains
how to use the timer overflow to count .
I think you configured Timer1 to use external clock:
InitTimer1 ExtOsc, PS1_8
Exists that external clock??
That's not the clock you use for PIC, its a dedicated ext. clock, ussually 32.768 KHz for real time, that should be connected to T1OSI and T1OSO pins.
If you want to use the same clock the cpu, then configure this way:
InitTimer1 Osc, PS1_8
Closed due to spam bot.