I re-re-re-read all the topics on this forum (searching for "timer") and I found one code (Josepino's code) for HIGH-accuracy clock.
I try to compile them, but I have errors. What I do wrong ?
Code:
DEFINE NO_CLRWDT
Define OSC 4
DEFINE LCD_DREG PORTB ' LCD Data Port
DEFINE LCD_DBIT 4 ' Starting Data Bit
DEFINE LCD_RSREG PORTA ' Register Select Port
DEFINE LCD_RSBIT 1 ' Register Select Bit
DEFINE LCD_EREG PORTA ' Enable Port
DEFINE LCD_EBIT 0 ' Enable Bit
DEFINE LCD_BITS 4 ' Data Bus Size
DEFINE LCD_LINES 2 ' Number of Lines on LCD
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
TRISA= %11111000 ' RA0..3=Outputs RA4=Input
TRISB= %00001111 ' RB0..RB2=Inputs, RB3..RB7=Outputs
CMCON = 7
pushButton1 var portb.0 'switch
pushButton2 var portb.1
pushButton3 Var portb.2
pushButton4 Var portb.3
pressed con 0 ;value of button pressed
notPressed con 1 ;value of button not pressed
dhour var byte ' Define display hour variable
i var byte ' Debounce loop variable
ticks var byte ' Define pieces of seconds variable
Seconds var byte
Minutes var byte
Hours var byte
Days var byte
Months var BYTE
TempC var word
Float var word
Sign var bit ' +/- sign
DQ var PORTA.4 ' One-wire data pin
TempC2 var word
Float2 var word
Sign2 var bit ' +/- sign
DQ2 var PORTA.3 ' One-wire data pin
semn var word
semn2 var word
DS18B20_1 CON %01011111
DS18B20_2 CON %01011111
;DS18B20_9bit CON %00011111 ; 93.75ms, 0.5°C
;DS18B20_10bit CON %00111111 ; 187.5ms, 0.25°C
;DS18B20_11bit CON %01011111 ; 375ms, 0.125°C
SecondsChanged var bit
MinutesChanged var bit
HoursChanged var bit
DaysChanged var bit
SecondsChanged = 1
MinutesChanged = 1
Seconds = 0
Minutes = 0
Hours = 12
Days = 1
Months = 1
SecondsChanged = 1
MinutesChanged = 1
HoursChanged = 1
DaysChanged = 1
include "timp.pbp.txt"
Pause 200 ' Wait for LCD to Initialize
' Init Sensor 1
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_1]
OWOut DQ, 1, [$CC, $48]
OWOut DQ, 1, [$CC, $B8]
OWOut DQ, 1, [$CC, $BE]
Pause 50
OWIn DQ, 2, [TempC.byte0, TempC.byte1]
Pause 50
' Init Sensor 2
OWOUT DQ2, 1, [$CC, $4E, 0, 0, DS18B20_2]
OWOut DQ2, 1, [$CC, $48]
OWOut DQ2, 1, [$CC, $B8]
OWOut DQ2, 1, [$CC, $BE]
Pause 50
OWIn DQ2, 2, [TempC2.byte0, TempC2.byte1]
Pause 50
mainloop:
if tick.0=1 then
tick.0=0
Seconds = Seconds + 1
SecondsChanged = 1
if Seconds = 60 then
Minutes = Minutes + 1
MinutesChanged = 1
Seconds = 0
endif
if Minutes = 60 then
Hours = Hours + 1
HoursChanged = 1
Minutes = 0
endif
if Hours = 24 then
Days = Days + 1
DaysChanged = 1
Hours = 0
endif
if Days = 32 then
Months = Months + 1
Days = 1
endif
if months = 13 then
months = 1
endif
endif
' Check button pressed to set time
if pushbutton1 = pressed Then
gosub set_minutes
endif
if pushbutton2 = pressed then
gosub set_hours
endif
if pushbutton4 = pressed then
gosub set_days
endif
if pushbutton3 = pressed then
gosub set_Months
endif
' Check for time to update screen
If SecondsChanged = 1 Then
SecondsChanged = 0 ' Display time as hh:mm:ss
LCDout $FE, $80, dec2 Hours,":",dec2 Minutes,":",dec2 Seconds," ",DEC2 Days,"/",DEC2 Months
LCDOUT $FE, $C0, semn,DEC ABS TempC/100,".", DEC1 ABS TempC/10, 223,"C ", $FE, $C0 + 9, semn2,DEC ABS TempC2/100,".", DEC1 ABS TempC2/10, 223,"C "
' pauseus 1386
Endif
Goto mainloop ' Do it all forever
set_minutes:
Minutes = Minutes + 1
if Minutes = 60 then
Minutes = 0
endif
gosub debounce
return
set_hours:
Hours = Hours + 1
if Hours = 24 then
Hours = 0
endif
gosub debounce
return
set_days:
Days = Days + 1
if Days = 32 then
Days = 1
endif
gosub debounce
return
set_months:
Months = Months +1
if Months = 13 then
Months = 1
endif
gosub debounce
return
debounce:
For i = 1 To 100 ' Debounce and delay for 100ms
Pause 1 ' 1ms at a time so no interrupts are lost
Next i
SecondsChanged = 1
return
;===================================================
Read_Temp:
' Skip ROM search & do temp conversion
OWOut DQ, 1, [$CC, $BE]
OWIn DQ, 2, [TempC.byte0, TempC.byte1]
Sign = TempC.15
TempC = ABS(TempC)
TempC = ((TempC >> 4)*100) + ((TempC & $F)*100 >> 4)
IF Sign THEN TempC = -TempC
IF TempC.15 THEN
Semn="-"
else
Semn="+"
endif
OWOut DQ2, 1, [$CC, $BE]
OWIn DQ2, 2, [TempC2.byte0, TempC2.byte1]
Sign2 = TempC2.15
TempC2 = ABS(TempC2)
TempC2 = ((TempC2 >> 4)*100) + ((TempC2 & $F)*100 >> 4)
IF Sign2 THEN TempC2 = -TempC2
IF TempC2.15 THEN
Semn2="-"
else
Semn2="+"
endif
Return
;===================================================
End
and timp.pbp.txt
Code:
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, int_handler, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
INT_ENABLE TMR0_INT ; Enable Timer 1 Interrupts
ENDASM
OPTION_REG = %00001000 ' Set TMR0 configuration
INTCON = %10100000 ' Enable TMR0 interrupts
bres_hi VAR BYTE bank0 system ' hi byte of our 24bit variable
bres_mid VAR BYTE bank0 system ' ; mid byte
bres_lo VAR BYTE bank0 system '; lo byte
'; (we only need 3 bytes for this system)
bres_hi = $0F
bres_mid= $42
bres_lo= $40
tick VAR BYTE bank0 system
ASM
;******************************************************************************
; INTERRUPT HANDLER (runs this code each timer0 interrupt)
;******************************************************************************
;
;------------------
int_handler ;
;------------------
;-------------------------------------------------
;-------------------------------------------------
; Note! we get here every 256 instructions, we
; can now do our special one second timing system.
; This consists of three main steps;
; * subtract 256 counts from our 24bit variable
; * test if we reached the setpoint
; * if so, add 1,000,000 counts to 24bit variable and generate event.
;-------------------------------------------------
; * optimised 24 bit subtract here
; This is done with the minimum instructions.
; We subtract 256 from the 24bit variable
; by just decrementing the mid byte.
tstf bres_mid ; first test for mid==0
skpnz ; nz = no underflow needed
decf bres_hi,f ; z, so is underflow, so dec the msb
decfsz bres_mid,f ; dec the mid byte (subtract 256)
; now the full 24bit optimised subtract is done!
; this is about 4 times faster than a "proper"
; 24bit subtract.
goto int_exit ; nz, so definitely not one second yet.
; in most cases the entire 'fake" int takes
; only 9 instructions.
;------------------------
; * test if we have reached one second.
; only gets here when mid==0, it MAY be one second.
; only gets to here 1 in every 256 times.
; (this is our best optimised test)
; it gets here when bres_mid ==0.
tstf bres_hi ; test hi for zero too
skpz ; z = both hi and mid are zero, is one second!
goto int_exit ; nz, so not one second yet.
;-------------------------------------------------
; Only gets to here if we have reached one second.
; now we can generate our one second event, like add
; one second to our clock or whatever.
; (in this example we toggle a led)
; The other thing we need to do is add 1,000,000 counts
; to our 24bit variable and start all over again.
;-------------------------------------------------
; Add the 1,000,000 counts first.
; One second = 1,000,000 = 0F 42 40 (in hex)
; As we know hi==0 and mid==0 this makes it very fast.
; This is an optimised 24bit add, because we can
; just load the top two bytes and only need to do
; a real add on the bottom byte. This is much quicker
; than a "proper" 24bit add.
movlw 0x0F ; get msb value
movwf bres_hi ; load in msb
movlw 0x42 ; get mid value
movwf bres_mid ; load in mid
movlw 0x40 ; lsb value to add
addwf bres_lo,f ; add it to the remainder already in lsb
skpnc ; nc = no overflow, so mid is still ok
incf bres_mid,f ; c, so lsb overflowed, so inc mid
; this is optimised and relies on mid being known
; and that mid won't overflow from one inc.
; that's it! Our optimised 24bit add is done,
; this is roughly twice as quick as a "proper"
; 24bit add.
;-------------------------
; now we do the "event" that we do every one second.
; Note! for this example we toggle a led, which
; will give a flashing led which is on for a second
; and off for a second.
; Add your own code here for your one second event.
; Note! My led is on porta,3
; your led may be on a different pin.
movlw b'00000001' ; mask for bit 3
xorwf tick,f ; toggle PORTA,bit3 (toggle the led)
;-------------------------------------------------
; now our one second event is all done, we can exit the
; interrupt handler.
;-------------------------------------------------
; finally we restore w and status registers.
; also clears TMRO int flag now we are finished.
int_exit
INT_RETURN
ENDASM
Bookmarks