'JP Duval le 08/10/2004 ' interruption timer1 sur le M8 '7 exemples d'utilisation du timer1 sur interruption ou sur Gosub. 'Timer 'compteur 'capture 'PWM 'compare 'Timer1 est un des 3 timers du M8, c'est un timer sur 16 bits 'utilisable en Timer pour déclencher un événement aprés x périodes 'ou utilisable en compteur d'événements Counter 'ou en comparateur 'ou encore en générateur PWM 'avec le timer1 on peut faire appel aux broches (entrée du timing) 'les broches utilisées portD.5 "T1" pour le compteur (entrée) ' portB.0 "ICP1" pour le mode capture (entrée) ' portB.1 "OC1A" pour compareA (sortie) ' portB.2 "OC1B" pour compareB (sortie) ' ______ push-button or relay ' portd.5-o---------^ ^--------gnd ' | ' vcc------|^^^^-------------------gnd pull up 10K ' ' ______ push button or relay ' portb.0-----------^ ^--------gnd ' | ' vcc------|^^^^------------------gnd pull up 10K '--------[variable]---------------------------------- Dim J As Word , K As Long ' -------[ config ]----------------------------------- ' les config doivent être écrites sans retour à la ligne. Config Lcdmode = Port ' config 4 bit Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5 Config Lcd = 16 * 2 ' -------[1° exemple Timer sur Subroutine]-------------------------------------- 'mettre en REM pour les autres exemples Config Timer1 = Timer , Prescale = 256 'choix diviseur 1,8,64,256,1024 Stop Timer1 'on bloque le timer car il démarre immédiatement . Cls J = 0 Do Start Timer1 'démarrage du timer Locate 1 , 1 : Lcd "timer1:" ; Timer1 'nombre de rotation If Tifr.2 = 1 Then 'flag de l'overflow Gosub Suite End If Loop End 'end program Suite: Stop Timer1 J = J + 1 Set Tifr.1 'remise à 0 de l'overflow Locate 2 , 1 : Lcd "overflow:" ; J Waitms 100 Timer1 = 0 ''important Return ' -------[2° exemple Timer sur interruption]-------------------------------------- 'mettre en REM pour les autres exemples '( Cls Config Timer1 = Timer , Prescale = 64 '1-8-64-256-1024 Enable Interrupts Enable Timer1 Enable Ovf1 On Ovf1 Suite1 'overflow Do Locate 1 , 1 : Lcd "overflow:" ; K 'vos instructions....... Loop End 'end program Suite1: K = K + 1 If K = 10 Then K = 0 Return ' sur interruption, il est préférable de mettre le moins d'instructions possible dans 'le saut (Suite1:), ne pas oublier que l'interruption tourne toujours... ') ' -------[3° exemple simple compteur]-------------------------------------- 'mettre en REM pour les autres exemples '( 'portD.5 pour le compteur "T1" (entrée/input) Config Pind.5 = Input Cls Config Timer1 = Counter , Edge = Rising , Capture Edge = Rising , Noice Cancel = 1 Tcnt1l = 0 'ce compteur posséde 2 bytes TCNT1L et TCNTH qui sont les LSB et MSB Enable Interrupts Enable Counter1 Do Locate 1 , 1 : Lcd "register:" ; Tcnt1l 'nombre de rotation If Tcnt1l <> 0 Then Gosub Suite2 ' ou : on ovf0 suite Loop End 'end program Suite2: Disable Counter1 'on arrête le compteur si le nombre d'instructions est 'important sinon on risque un débordement de pile (stack). K = K + 1 Locate 2 , 1 : Lcd "counter:" ; K Tcnt1l = 0 'pour la condition TCNT1L<>0 Tcnt1h = 0 ' non nécessaire ici. Waitms 100 Enable Counter1 Return ') ' -------[4° exemple PWM]------------------------------------------------ 'mettre en REM pour les autres exemples '( Cls Locate 1 , 1 : Lcd "wait 5S" 'petit attente pas obligatoire Wait 5 Config Pinb.1 = Output 'important de préparer OC1A and OC1B en output Config Pinb.2 = Output Config Timer1 = Pwm , Pwm = 10 , Prescale = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down Pwm1a = 768 Pwm1b = 768 Start Timer1 Locate 2 , 1 : Lcd "pwm=10 ps=1" End '---------[remarques sur PWM]--------------------------- 'le PWM est un générateur de signaux carrés modulables :Pulse Wide Modulator '-------- ' si on n'utilise qu'un seul canal, il n'est pas nécessaire de définir les 2 'Ex: 'Config Timer1 = Pwm , Pwm = 10 , Prescale = 1 , Compare A Pwm = Clear Up 'Pwm1A=variable 'variable peut être sur 8/9/or 10bits aussi pensez à bien TYPER ( byte ou Word) '-------- ' qu'est-ce que Clear up ? clear down ? ' regardez l'exemple sur un scope, le résultat est inversé 'ici 1024 est la résolution Pwm=10 bits rien a voir avec le prescaler ' "Clear-up" met à 1 la différence entre 1024-(1024-768) ' "clear down" met à 0 la différence entre 1024-768 '---------- 'avec la Main clock frequency= internal 8MHz 'Les valeurs ci-dessous sont lues au scope , mon scope à 30 ans!(1974) 'mais les résultats sont proches des valeurs calculées. 'Prescale est un facteur de division de la fréquence d'horloge 1,8,64,256,1024 'avec PS=1 et facteur Pwm=10=4166 Hz ' ------------------------------=9-=8333 Hz '-- ----------------------------=8-=16666 Hz 'avec PS=8 et facteur Pwm=10=520 Hz '-------------------------------=9=1041 Hz '-------------------------------=8=2082 Hz 'avec PS=64 et facteur Pwm=10=65 Hz '--------------------------------=9=130 Hz '--------------------------------=8=260 Hz 'avec PS=256 et facteur Pwm =10=16.25 Hz '-----------------------------------=9=32.5 Hz '-----------------------------------=8=65 Hz 'avec PS=1024 et facteur Pwm =10=4.06 Hz '-------------------------------------=9=8.12 Hz '-------------------------------------=8=16.25 Hz '------------- ' le pprogramme fonctionne même s'il rencontre un END parce que 'Il n'a pas rencontré de Stop Timer1 ' vous pouvez ajouter votre boucle.exemple : ') '( J = 10 Do ' version amusante (sur le scope) Pwm1a = J J = J + 1 Locate 2 , 1 : Lcd "PWM:" If J = 1024 Then J = 10 Loop End ') ' -------[5° exemple Capture sur interruption]------------------------------------------- 'mettre en REM pour les autres exemples 'ICP1 est en pinB.0 (input) '( Cls Config Pinb.0 = Input Locate 1 , 1 : Lcd "wait 5S" 'une petite attente Wait 5 Config Timer1 = Timer , Prescale = 1024 , Capture Edge = Rising , Noise Cancel = 1 Enable Interrupts Enable Capture1 Start Timer1 Do Locate 1 , 1 : Lcd "capture:" ; Timer1 If Timer1 = 65535 Then 'ceci à supprimer un bug inexplicable Timer1 = 0 'n'est pas indispensable Cls End If On Icp1 Suite5 Loop End Suite5: K = Capture1 Stop Timer1 Disable Capture1 Locate 2 , 1 : Lcd "capture" ; K Wait 1 Cls Start Timer1 Enable Capture1 Capture1 = 0 Timer1 = 0 Return '---------[ remarques sur capture]----------------- 'Comme le nom l'indique Capture est fait pour stopper des événements ' à un moment précis. ') ' -------[6° exemple Compare sur gosub]------------------------------------------------- 'mettre en REM pour les autres exemples 'ICP1 est en pinB.0 (input) '( Cls Config Pinb.2 = Output Locate 1 , 1 : Lcd "wait 5S" 'une petite attente Wait 5 Config Timer1 = Timer , Prescale = 1024 , Compare B = Disconnect , Noise Cancel = 1 Stop Timer1 Compare1b = 10000 Start Timer1 Do Locate 1 , 1 : Lcd "timer1: " ; Timer1 If Tifr.3 = 1 Then 'flag de compare Gosub Suite6 End If Loop End 'end program Suite6: K = Timer1 - 1 Stop Timer1 Locate 2 , 1 : Lcd "compare" ; K Wait 1 Cls Set Tifr.1 'remise à 0 de l'overflow Start Timer1 Timer1 = 0 Return '2 retour sur interruption ') ' -------[7° exemple Compare sur interruption]---------------------------------------- 'mettre en REM pour les autres exemples 'ICP1 est en pinB.0 (input) '( Cls Config Pinb.2 = Output Locate 1 , 1 : Lcd "compare inter" 'une petite attente Wait 2 Enable Interrupts Config Timer1 = Timer , Prescale = 64 , Compare B = Disconnect , Noise Cancel = 1 Compare1b = 9999 Enable Compare1b On Compare1b Suite7 Enable Timer1 K = 0 Do 'Locate 1 , 1 : Lcd "compare inter" Locate 2 , 1 : Lcd "compare:" ; K Waitms 200 Cls Loop End 'end program Suite7: K = Timer1 - 1 Compare1b = Compare1b - 1 If Compare1b = 0 Then Compare1b = 9999 Return ') '