program HORLOGE
'
'  16F88  /  @4MHz / FUSES = HS, _ALL_OFF  / ANODES COMMUNES
'
symbol COM_HD = PORTA.0    ' commun afficheur dizaines heures
symbol COM_HU = PORTA.1    ' commun afficheur unités heures
symbol COM_MD = PORTA.2    ' commun afficheur dizaines minutes
symbol COM_MU = PORTA.3    ' commun afficheur unités minutes
symbol BP_HEU = PORTA.4    ' bp réglage heures
symbol BP_MIN = PORTA.5    ' bp réglage minutes        
symbol FR_OUT = PORTB.7    ' sortie 100Hz 
'                                         
const chiffres as byte[10] = (%1000000, ' 0
                              %1111001, ' 1
                              %0100100, ' 2
                              %0110000, ' 3
                              %0011001, ' 4
                              %0010010, ' 5
                              %0000010, ' 6
                              %1111000, ' 7
                              %0000000, ' 8
                              %0010000) ' 9
'
dim secondes,
    minutes,
    heures,
    heures_diz, 
    heures_uni, 
    minutes_diz, 
    minutes_uni,
    compteur,
    etat as byte           
'    
sub procedure interrupt
      TMR1H = 236     ' définit une période de 5000µs (=5ms)        
      TMR1L = 130     ' valeur théorique de 120, (236 * 256) + 120 = 65536 - 5000         
      etat = not etat ' inverse l'état
      FR_OUT = etat   ' 100Hz (un front haut toutes les 10ms)
      inc(compteur)
      if compteur > 199 then   ' 1 seconde = 200x5ms = 1000ms
         compteur = 0
         inc(secondes)
         if secondes > 59 then         
            secondes = 0  
            inc(minutes)
         end if
         if minutes > 59 then   
                minutes = 0
                inc(heures)
         end if
         if heures > 23 then
                heures = 0
         end if   
      end if  
      PIR1.TMR1IF = 0   ' réactive interrupt TMR1 cas efface le flag...
end sub
'           
main:
    ANSEL    = %00000000  ' ADC OFF sur un 16F88
    TrisA    = %00000000  ' tous les ports en sorties
    TrisB    = %00000000  ' tous les ports en sorties    
    TrisA.4  = 1          ' port BP_HEU en entrée
    TrisA.5  = 1          ' port BP_MIN en entrée                                  
    T1CON    =   %000001  ' activation du TMR1, avec PreScaler = 1   
    INTCON   = %11000000  ' activation interruptions sur peripheriques
    PIE1     = %00000001  ' activation de l'interruption du TMR1
    '           
    etat     =  0 
    heures   =  1
    minutes  =  2     ' 1 heure et 2 minutes, à la mise sous tension...
    '
    while true                              
              heures_diz = heures div 10     
              PortB = chiffres[heures_diz]
              COM_MU = 1
              COM_MD = 1 
              COM_HU = 1         
              COM_HD = 0               
              delay_ms(1)              
              if BP_HEU = 1 then gosub reglage_heures end if  
              '
              heures_uni = heures mod 10    
              PortB = chiffres[heures_uni]             
              COM_HD = 1  
              COM_MU = 1
              COM_MD = 1 
              COM_HU = 0             
              delay_ms(1)               
              if BP_MIN = 1 then gosub reglage_minutes end if    
              '
              minutes_diz = minutes div 10      
              PortB = chiffres[minutes_diz] 
              COM_HU = 1             
              COM_HD = 1  
              COM_MU = 1
              COM_MD = 0         
              delay_ms(1)           
              if BP_HEU = 1 then gosub reglage_heures end if   
              '
              minutes_uni = minutes mod 10  
              PortB = chiffres[minutes_uni]      
              COM_MD = 1    
              COM_HU = 1             
              COM_HD = 1  
              COM_MU = 0     
              delay_ms(1)           
              if BP_MIN = 1 then gosub reglage_minutes end if 
    wend
    '
    reglage_heures:                   
        inc(heures)
        if heures > 23 then heures = 0 end if
        delay_ms(50)           
        secondes = 0
    return
    '
    reglage_minutes:                   
        inc(minutes)
        if minutes > 59 then minutes = 0 end if
        delay_ms(50)           
        secondes = 0
    return
'
end.