Revision: 1411 Author: robhamerling Date: Sat Oct 24 05:57:20 2009 Log: Temporary fix for rtc_isr_tmr0 library to make it oscillator frequency independent
http://code.google.com/p/jallib/source/detail?r=1411 Modified: /trunk/CHANGELOG /trunk/include/jal/rtc_isr_tmr0.jal ======================================= --- /trunk/CHANGELOG Tue Oct 20 10:56:56 2009 +++ /trunk/CHANGELOG Sat Oct 24 05:57:20 2009 @@ -27,11 +27,12 @@ 18F2550, 18F4550, 18F4455, 18F2455 (except 12-bits resolution channels) jal extension: - - added delay_1s + - added delay_1s to delay library + - provisional fix to make rtc_int_tmr0 library independent of ocsillator frequency samples: - seven_segment samples - - over 50 new blink-an-LED samples + - over 50 blink-an-LED samples released - 2 samples for multi-channel dimmers (combined use of PWM and ADC) - eeprom samples for 18Fs - added sample files for PIC16f723 ======================================= --- /trunk/include/jal/rtc_isr_tmr0.jal Tue Dec 30 22:43:59 2008 +++ /trunk/include/jal/rtc_isr_tmr0.jal Sat Oct 24 05:57:20 2009 @@ -1,79 +1,82 @@ -- Title: Real Time Clock running from ISR on TMR0 -- Author: Eur van Andel, Copyright (c) 2003..2008, all rights reserved. --- Adapted-by: --- Compiler: >=2.4h --- +-- Adapted-by: Rob Hamerling +-- Compiler: 2.4l +-- -- This file is part of jallib (http://jallib.googlecode.com) -- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html) -- --- Sources: http://www.romanblack.com/one_sec.htm, http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm --- --- Description: This Interrupt Service Routine updates the variable seconds about once per second. --- The precision is 0.2 ppm, the accuracy depends on the Xtal used. +-- Sources: http://www.romanblack.com/one_sec.htm +-- http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm -- --- Notes: This is the Bresenham Line Algorithm, invented at IBM in 1962, which gets an accurate end result --- by summing the small errors resulting of taking discrete steps and correcting when the error gets too large. --- This means that individual second lengths may show some jitter, but that long-term timekeeping is accurate. --- Original assembler by Roman Black. --- - --- 20 MHz, so 200ns/clock, so 5 000 000 clocks/second --- the RTC has three bytes: bres_hi, bres_mid, bres_lo +-- Description: This Interrupt Service Routine updates the variable seconds +-- about once per second. -- The precision is 0.2 ppm, the accuracy depends +-- on the Xtal used. +-- -- +-- Notes: This is the Bresenham Line Algorithm, invented at IBM in 1962, +-- which gets an accurate end result by summing the small errors resulting of +-- taking discrete steps and correcting when the error gets too large. This +-- means that individual second lengths may show some jitter, but that long-term +-- timekeeping is accurate. Original assembler by Roman Black. +-- -- +-- At 20 MHz, so 200ns/clock, so 5 000 000 clocks/second +-- Rhe RTC has three bytes: bres_hi, bres_mid, bres_lo -- timer 0 runs on internal clock speed and interrupts on overflow -- every timer 0 interrupt decreases bres_mid by one. --- the 2 000 000 value is added when bres_hi en bres_mid are zero --- note that remainder is added to bres_lo, which cab overflow in bres_mid --- this keeps clock count accurate, although interrupts happen every 256 clock counts --- the ISR subtracts 1 from the mid byte. It first checks --- the mid byte for zero and borrows a bit from bres_hi if needed +-- The 2 000 000 value is added when bres_hi en bres_mid are zero +-- note that remainder is added to bres_lo, which can overflow in bres_mid +-- this keeps clock count accurate, although interrupts happen every 256 clock +-- counts the ISR subtracts 1 from the mid byte. It first checks +-- the mid byte for zero and borrows a bit from bres_hi if needed. +-- +-- Required PIC settings: OPTION_REG_PSA = 0 +-- OPTION_REG_PS = 0 +-- -var volatile byte seconds -- updated by ISR - --- RTC ISR constants: --- 0x4C 0x4B 0x40 5 000 000 20 MZz xtal --- 0x0F 0x42 0x40 1 000 000 4 MHz int osc --- 0x12 0x13 0xD0 1 250 000 20 MHz, prescaler = 4 - -const hi = 0x4C -- 2 000 000 for 20 MHz xtal and prescaler = 4 -const mid = 0x4B -const lo = 0x40 -- ideally modified in timeset too, to adjust clock - -var volatile byte bres_hi = hi -var volatile byte bres_mid = mid -var volatile byte bres_lo = lo +var volatile byte seconds -- global variable updated by ISR + +const _cycles_per_second = (target_clock / 4) + +const byte hi = _cycles_per_second / 65536 +const byte mid = _cycles_per_second % 65536 / 256 +const byte lo = _cycles_per_second % 256 + +var volatile byte bres_hi = hi -- \ +var volatile byte bres_mid = mid -- > init 3-byte counter +var volatile byte bres_lo = lo -- / procedure RTC() is - pragma interrupt - assembler -- ISR should be as small as possible, so assembler - local int_exit -- labels for jumping - - bcf INTCON_TMR0IF -- clear the timer 0 interrupt flag - movf bres_mid,f -- mid == 0 ? - btfsc STATUS_Z -- not zero? - decf bres_hi, f -- zero, borrow one from high byte - decfsz bres_mid, f -- this is the count of the interrupts - goto int_exit -- mid byte is not zero, so exit - movf bres_hi, f -- mid == 0, might hi == 0 too ? + pragma interrupt + assembler -- fast ISR: so assembler + local int_exit -- labels for jumping + + bcf INTCON_TMR0IF -- clear the timer 0 interrupt flag + movf bres_mid,f -- mid == 0 ? + btfsc STATUS_Z -- not zero? + decf bres_hi, f -- zero, borrow one from high byte + decfsz bres_mid, f -- this is the count of the interrupts + goto int_exit -- mid byte is not zero, so exit + movf bres_hi, f -- mid == 0, might hi == 0 too ? btfss STATUS_Z - goto int_exit -- high byte not zero, so exit - -- high byte zero, mid also zero - -- we need to load the one-second timer - - movlw hi -- add 2 000 000 to hi-mid-lo - movwf bres_hi -- hi & mid are both zero + goto int_exit -- high byte not zero, so exit + -- high byte zero, mid also zero + -- we need to load the one-second timer + + movlw hi -- add cycles_per_second to hi-mid-lo + movwf bres_hi -- hi & mid are both zero movlw mid movwf bres_mid - movlw lo -- lo is not zero, and must be added - addwf bres_lo, f -- bres_lo can overflow - btfsc STATUS_C -- does it? - incf bres_mid, f -- yes, but mid was 0x4B, so will not overflow - incf seconds, f -- main routine should check seconds - -- and call calendar when seconds > 59 - -- and take care of minutes, etc. + movlw lo -- lo is not zero, and must be added + addwf bres_lo, f -- bres_lo can overflow + btfsc STATUS_C -- does it? + incf bres_mid, f -- yes, but mid was 0x4B, so will not overflow + incf seconds, f -- main routine should check seconds + -- and call calendar when seconds > 59 + -- and take care of minutes, etc. int_exit: end assembler -end procedure -- end of ISR +end procedure -- end of ISR --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jallib" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/jallib?hl=en -~----------~----~----~----~------~----~------~--~---
