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