Hallo,

Ich möchte hier meine Software-Timer Library vorstellen, ich verwende sie bei fast allen Projekten, vielleicht kann jemand etwas damit anfangen.

Die Lib verwendet einen HW-Timer und verwaltet bis zu 256 voneinander unabhängige Software-Timer. Die Parameter für den HW-Timer werden aus der gewünschten Timer-Frequenz berechnet.

Der Code ist ansich gut dokumentiert und selbsterklärend:
(tickers.bas)
Code:
$nocompile
'###############################################################################
'##                                                                           ##
'##            U N I V E R S A L   S O F T W A R E   T I M E R                ##
'##            ===============================================                ##
'##                                                                           ##
'##  Description: This is an easy-to-use universal software timer library,    ##
'##               for use with any hardware timer, featuring automatic        ##
'##               determination of needed timer parameters on precompile,     ##
'##               up to 256 independant software timers, each can be          ##
'##               enabled/disabled and an interrupt queue if more than one    ##
'##               sw interrupt occured at once.                               ##
'##                                                                           ##
'##  Author:      Matthias (at) Braunecker (.at)                              ##
'##  Version:     1.0                                        Date: July 2009  ##
'##                                                                           ##
'##  Free for personal use, credits and a short mail with your project info   ##
'##  and/or comments, improvements etc. to this library would be nice.        ##
'##                                                                           ##
'###############################################################################

' How to use this (the values are just for example):
' --------------------------------------------------

' Initialisation:
'    $crystal = 16000000
'    [...]                                                       ' your Code
'    Const False = 0: Const True = 1                             ' for better reading

'    Const Ticker_hwtimer = 0                                    ' Choose which hardware timer to use
'    Const Ticker_frequency = 10000                              ' set the timer resolution
'    Const Tickers = 2                                           ' # of software timers to use
'    $include "tickers.bas"
'    Ticker_time(1) = 25                                         ' Interrupt Ticks to trigger SW-Timer 1
'    Ticker_time(2) = 500                                        ' SW-Timer 2 and so on...
'    Ticker_enabled(1) = True                                    ' Enable/Disable SW-Timer
'    Ticker_enabled(2) = False
'    [...]
'    Enable Interrupts

' Main Loop:
'    Do
'       [...]
'       Select Case Ticker_get_interrupt()                       ' make sure that this function is called at least once per
                                                                 ' hw timer overflow, so don't make the µC hanging around
'       Case 1:                                                  ' Ticker 1 triggered an interrupt
'          [...]
'       Case 2:                                                  ' Ticker 2 interrupt
'          [...]
'       End Select
'       [...]
'    Loop


Declare Function Ticker_get_interrupt() As Byte
Declare Sub Ticker_enable(byval Tickernr As Byte)


'###############################################################################
'##      T I M E R   S E T T I N G S   C A L C U L A T I O N                  ##
'###############################################################################
' calculation based on a work by "Walter", MCS Forum, added prescaler calculation
Const Ticker_cyclespertick = _xtal / Ticker_frequency       ' clock cycles needed for desired frequency
#if Ticker_hwtimer = 0                                      ' Set the timer register size
   Const Ticker_register = 256
#endif
#if Ticker_hwtimer = 1
   Const Ticker_register = 65536
#endif
#if Ticker_hwtimer = 2
   Const Ticker_register = 256
#endif

#if(ticker_cyclespertick / 1) < Ticker_register             ' calculate the right prescale value
   Const Ticker_prescale = 1
#else
   #if(ticker_cyclespertick / 8) < Ticker_register
      Const Ticker_prescale = 8
   #else
      #if(ticker_cyclespertick / 64) < Ticker_register
         Const Ticker_prescale = 64
      #else
         #if(ticker_cyclespertick / 256) < Ticker_register
            Const Ticker_prescale = 256
         #else
            #if(ticker_cyclespertick / 1024) < Ticker_register
               Const Ticker_prescale = 1024
            #endif
         #endif
      #endif
   #endif
#endif

Const Ticker_tickfrequency = _xtal / Ticker_prescale        ' frequency of Timer-Ticks
Const Ticker_ticktime = 1 / Ticker_tickfrequency            ' time of one Timer-Tick in sec
Const Ticker_desiredtime = 1 / Ticker_frequency             ' desired time in sec
Const Ticker_count = Ticker_desiredtime / Ticker_ticktime   ' number of Ticks for desired time
Const Ticker_preload = Ticker_register - Ticker_count       ' start-value for the timer


'###############################################################################
'##      V A R I A B L E S                                                    ##
'###############################################################################
Dim Ticker_counter(tickers) As Word                         ' tick counter
Dim Ticker_time(tickers) As Word                            ' desired intervall time
Dim Ticker_interrupt(10) As Byte                            ' interrupt stack
Dim Ticker_pointer As Byte                                  ' interrupt stack pointer
Dim Ticker_tmp As Byte                                      ' internal temp variable
Dim Ticker_enabled(tickers) As Byte                         ' enable/disable ticker
Dim Ticker_newtick As Bit                                   ' hw timer interrupt flag


'###############################################################################
'##      S E T T I N G   U P   H W - T I M E R                                ##
'###############################################################################
#if Ticker_hwtimer = 0
   Ticker_timer Alias Timer0
   Config Ticker_timer = Timer , Prescale = Ticker_prescale
   On Timer0 Ticker_isr Nosave
   Enable Timer0
#endif
#if Ticker_hwtimer = 1
   Ticker_timer Alias Timer1
   Config Ticker_timer = Timer , Prescale = Ticker_prescale
   On Timer1 Ticker_isr Nosave
   Enable Timer1
#endif
#if Ticker_hwtimer = 2
   Ticker_timer Alias Timer2
   Config Ticker_timer = Timer , Prescale = Ticker_prescale
   On Timer2 Ticker_isr Nosave
   Enable Timer2
#endif

Ticker_timer = Ticker_preload
Goto Ticker_runprog                                         ' don't execute the functions


'###############################################################################
'##      F U N C T I O N S                                                    ##
'###############################################################################
Sub Ticker_enable(byval Tickernr As Byte)                   ' enables and resets a sw-timer
   Ticker_enabled(tickernr) = True
   Ticker_counter(tickernr) = 0
End Sub

'-------------------------------------------------------------------------------
Function Ticker_get_interrupt() As Byte                     ' Main function
   If Ticker_newtick = True Then                            ' hw timer interrupt occured
      Ticker_newtick = False                                ' reset the flag
      For Ticker_tmp = 1 To Tickers                         ' check all sw tickers
         If Ticker_enabled(ticker_tmp) = 1 Then Incr Ticker_counter(ticker_tmp)       ' if ticker enabled, increment tick count
         If Ticker_counter(ticker_tmp) = Ticker_time(ticker_tmp) Then       ' tick count has reached desired time
            Incr Ticker_pointer
            Ticker_interrupt(ticker_pointer) = Ticker_tmp   ' store the interrupt in queue
            Ticker_counter(ticker_tmp) = 0                  ' reset ticker counter
         End If
      Next
   End If
   If 0 < Ticker_pointer Then                               ' interrupt is waiting in queue
      Ticker_get_interrupt = Ticker_interrupt(ticker_pointer)
      Ticker_interrupt(ticker_pointer) = 0                  ' interrupt processed, delete it
      Decr Ticker_pointer
   Else
      Ticker_get_interrupt = False                          ' no interrupt waiting
   End If
End Function

'-------------------------------------------------------------------------------
Ticker_isr:                                                 ' hw timer interrupt service routine
$asm
   push R25
   push R24
   IN R24, SREG
   PUSH R24
$end Asm
   Ticker_timer = Ticker_preload                            ' reset the timer register with calculated preload value
   Ticker_newtick = True                                    ' set flag
$asm
   pop R24
   Out Sreg , R24
   POP R24
   pop R25
$end Asm
Return

Ticker_runprog:
mfg