; Équivalences .equ PINA = 0x00 .equ DDRA = 0x01 .equ PORTA = 0x02 .equ PINC = 0x06 .equ DDRC = 0x07 .equ PORTC = 0x08 .equ WDTCSR = 0x60 .equ TTCR0A = 0x24 .equ TTCR0B = 0x25 .equ TMSK0 = 0x6e .equ EIMSK = 0x3D .equ EICRA = 0x69 .equ EICRB = 0x6A .equ ADMUX = 0x7C .equ ADCSRB = 0x7B .equ ADCSRA = 0x7A .equ ADCH = 0x79 .equ SPH = 0x3E .equ SPL = 0x3D ; Nommage des registres utilisés .def etat = r12 .def reference = r13 ; Température de référence actuelle .def d3 = r2 ; Digit 3 (tout à gauche) .def d2 = r3 ; Digit 2 .def d1 = r4 ; Digit 1 .def d0 = r5 ; Digit 0 (tout à droite) .def compteur = r6 ; Utilisé pour modifier des valeurs dans le menu .def temp = r7 ; Utilisé pour différentes choses mais très brièvement .def t2 = r8 ; Jour (3 premiers bits) et Heure (5 derniers bits) .def t1 = r9 ; Minutes .def t0 = r10 ; Secondes / 2 .def selaff = r11 ; Digit en cours d'affichage ; Vecteurs d'interruptions .org 0x000 ; Vecteur RESET jmp debut .org 0x0002 ; INT0 jmp valider .org 0x0004 ; INT1 jmp retour .org 0x0006 ; INT2 jmp incrementer .org 0x0008 ; INT3 jmp decrementer .org 0x0018 ; Watchdog jmp watchdog .org 0x002E ; Timer jmp timer .org 0x003A ; ADC jmp adc .org 0x0080 ; Tableaux de la mémoire du programme afficheur: .DB 0x3F, 0x30, 0x6D, 0x79, 0x72, 0x5B, 0x5F, 0x31, 0x7F, 0x7B ; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ; Programme debut: ; Configuration des composants ; Ports parallèles DDRA@IO <- 0xFF DDRC@IO <- 0xFF ; Watchdog WDTCSR <- 0b00010000 WDTCSR <- 0b01000111 ; Timer TTCR0A@IO <- 0b00000001 TTCR0B@IO <- 0b00000011 TMSK0 <- 0b00000001 ; Interruptions externes EIMSK <- 0b00001111 EICRA <- 0b11111111 ; TODO Oscillations annulables ? EICRB <- 0b00000000 ; ADC ADMUX <- 0b01110000 ADCSRB <- 0b00001011 ADCSRA <- 0b10011101 ; TODO Auto-trigger ? sei ; Initialisation des valeurs ; Mercredi 12h34'56 t2 <- 0b01001100 t1 <- 34 t0 <- 28 selaff <- 0b00000001 etat <- 0 call afficherHorloge boucle: sleep jmp boucle ; Fonctions ; Affichages afficherHorloge: ; Affiche l'heure actuelle temp <- t2 & 0b00011111 d3 <- 0x00 si temp > 10 alors d3 <- afficheur@ROM[temp/10] d2 <- afficheur@ROM[temp%10] | 0b10000000 d1 <- afficheur@ROM[t2/10] d0 <- afficheur@ROM[t2%10] ret afficherTemperature: ; Considère le registre compteur comme une température et l'affiche d0 <- 0x63 d1 <- afficheur@ROM[compteur%10] temp <- compteur + 50 d2 <- afficheur@ROM[(temp/10)%10] | 0b10000000 d3 <- afficheur@ROM[temp/100] ret afficherHeur: ; Considère le registre compteur comme une heure et l'affiche d3 <- afficheur@ROM[compteur/10] d2 <- afficheur@ROM[compteur%10] | 0b10000000 d1 <- 0x00 d0 <- 0x00 ret afficherMinu: ; Considère le registre compteur comme une minute et l'affiche d3 <- 0x00 d2 <- 0b10000000 d1 <- afficheur@ROM[compteur/10] d0 <- afficheur@ROM[compteur%10] ret afficherJour: ; Considère le registre compteur comme un jour et l'affiche d1 <- 0x00; d0 <- 0x00; si compteur = 0 saut afficherLu si compteur = 1 saut afficherMa si compteur = 2 saut afficherMe si compteur = 3 saut afficherJe si compteur = 4 saut afficherVe si compteur = 5 saut afficherSa si compteur = 6 saut afficherDi afficherLu: d3 <- 0x0E d2 <- 0x1c ret afficherMa: d3 <- 0x37 d2 <- 0x77 ret afficherMe: d3 <- 0x37 d2 <- 0xcf ret afficherJe: d3 <- 0x3c d2 <- 0xcf ret afficherVe: d3 <- 0x1c d2 <- 0xcf ret afficherSa: d3 <- 0x5b d2 <- 0x77 ret afficherDi: d3 <- 0xfc d2 <- 0x04 ret ; Logique agir10s: ; Initialise une lecture ADC ; Met à jour l'état de veille (si on est en état veille) ret agirHeur: ; Recharge la température de référence ; TODO ret ; Recadrage boundHeur: si compteur = 255 alors compteur <- 23 si compteur >= 24 alors compteur <- 0 ret boundMinu: si compteur = 255 alors compteur <- 59 si compteur >= 60 alors compteur <- 0 ret boundJour: si compteur = 255 alors compteur <- 6 si compteur >= 7 alors compteur <- 0 ret boundTemperature: si compteur < 5 alors compteur <- 5 si compteur > 200 alors compteur <- 200 ret reti: reti ; États ; × : Arrivée à l'état par un niveau supérieur ; R : Arrivée à l'état par un niveau inférieur ; U : Mise à jour de l'affichage ; C : Changement de l'état etatVeilleHeur: etat <- 0 call afficherHorloge reti etatVeilleTemp: etat <- 0 compteur <- ADCH call afficherTemperature reti etatMenuAssoc: etat <- 2 d3 <- 0x77 d2 <- 0x5b d1 <- 0x5b d0 <- 0x5c reti etatMenuJours: compteur <- 0 etatMenuJoursU: etat <- 3 + compteur call afficherJour reti etatMenuJoursR: compteur <- etat - 7 - 3 jmp etatMenuJoursU etatMenuJoursC: call boundJour jmp etatMenuJoursU etatMenuJoursS: ; TODO Switch mode nuit ↔ mode jour reti etatParaJours: etat <- etat + 7 compteur <- 12 etatParaJoursU: d3 <- afficheur@ROM[compteur/10] d2 <- afficheur@ROM[compteur%10] d1 <- 0x00 d0 <- 0xFF ; TODO Récupérer le mode reti etatParaJoursC: call boundHeur jmp etatParaJoursU etatParaJoursS: ; Switch ; TODO Sauvegarde jmp etatParaJoursU etatMenuTJour: etat <- 17 d3 <- 0x3c d2 <- 0x5c d1 <- 0x1c d0 <- 0x44 reti etatParaTJour: etat <- 18 compteur <- 0 ; TODO Récupérer la température etatParaTJourU: call afficherTemperature reti etatParaTJourC: call boundTemperature ; TODO Sauvegarde jmp etatParaTJourU etatMenuTNuit: etat <- 19 d3 <- 0x54 d2 <- 0x1c d1 <- 0x04 d0 <- 0x4e reti etatParaTNuit: etat <- 20 compteur <- 0 ; TODO Récupérer la température etatParaTNuitU: call afficherTemperature reti etatParaTNuitC: call boundTemperature ; TODO Sauvegarde jmp etatParaTNuitU etatMenuHorloge: etat <- 21 d3 <- 0xf6 d2 <- 0x5c d1 <- 0x44 d0 <- 0x0E reti etatMenuHJour: etat <- 22 d3 <- 0x3c d2 <- 0x5c d1 <- 0x1c d0 <- 0x44 reti etatMenuHHeur: etat <- 23 d3 <- 0xf6 d2 <- 0xcf d1 <- 0x1c d0 <- 0x44 reti etatMenuHMinu: etat <- 24 d3 <- 0x37 d2 <- 0x04 d1 <- 0x54 d0 <- 0x1c reti etatParaHJour: etat <- 25 compteur <- 0 ; TODO Récupérer le jour call afficherJour reti etatParaHJourC: call boundJour ; TODO Sauvegarde call afficherJour reti etatParaHHeur: etat <- 26 compteur <- 0 ; TODO Récupérer le temps call afficherHeur reti etatParaHHeurC: call boundHeur ; TODO Sauvegarde call afficherHeur reti etatParaHMinu: etat <- 27 compteur <- 0 ; TODO Récupérer la minute call afficherMinu reti etatParaHMinuC: call boundMinu ; TODO Sauvegarde call afficherMinu reti ; Interruption boutons incrementer: inc compteur si etat = 0 saut etatVeilleTemp si etat = 1 saut etatVeilleHeur si etat = 2 saut etatMenuTJour si etat <= 9 saut etatMenuJoursC si etat <= 16 saut etatParaJoursC si etat = 17 saut etatMenuTNuit si etat = 18 saut etatParaTJourC si etat = 19 saut etatMenuHorloge si etat = 20 saut etatParaTNuitC si etat = 21 saut etatMenuAssoc si etat = 22 saut etatMenuHHeur si etat = 23 saut etatMenuHMinu si etat = 24 saut etatMenuHJour si etat = 25 saut etatParaHJourC si etat = 26 saut etatParaHHeurC si etat = 27 saut etatParaHMinuC reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts decrementer: dec compteur si etat = 0 saut etatVeilleTemp si etat = 1 saut etatVeilleHeur si etat = 2 saut etatMenuHorloge si etat <= 9 saut etatMenuJoursC si etat <= 16 saut etatParaJoursC si etat = 17 saut etatMenuAssoc si etat = 18 saut etatParaTJourC si etat = 19 saut etatMenuTJour si etat = 20 saut etatParaTNuitC si etat = 21 saut etatMenuTNuit si etat = 22 saut etatMenuHMinu si etat = 23 saut etatMenuHJour si etat = 24 saut etatMenuHHeur si etat = 25 saut etatParaHJourC si etat = 26 saut etatParaHHeurC si etat = 27 saut etatParaHMinuC reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts valider: si etat <= 1 saut etatMenuAssoc si etat = 2 saut etatMenuJours si etat <= 9 saut etatParaJours si etat <= 16 saut etatMenuJoursS si etat = 17 saut etatParaTJour si etat = 18 saut etatMenuTJour si etat = 19 saut etatParaTNuit si etat = 20 saut etatMenuTNuit si etat = 21 saut etatMenuHJour si etat = 22 saut etatParaHJour si etat = 23 saut etatMenuHJour si etat = 24 saut etatParaHHeur si etat = 25 saut etatMenuHHeur si etat = 26 saut etatParaHMinu si etat = 27 saut etatMenuHMinu reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts retour: si etat <= 1 saut reti si etat = 2 saut etatVeilleHeur si etat <= 9 saut etatMenuAssoc si etat <= 16 saut etatMenuJoursR si etat = 17 saut etatVeilleHeur si etat = 18 saut etatMenuTJour si etat = 19 saut etatVeilleHeur si etat = 20 saut etatMenuTNuit si etat = 21 saut etatVeilleHeur si etat <= 24 saut etatMenuHorloge si etat = 25 saut etatMenuHJour si etat = 26 saut etatMenuHHeur si etat = 27 saut etatMenuHMinu reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts ; Interruption Watchdog watchdog: ; Met à jour les registres de temps, active agir10s ou agirHeur si nécessaire inc t0 si t0 % 5 != 0 saut reti ; Continue si on est sur un multiple de 10 secondes call agir10s si t0 < 30 saut reti ; Continue si on est sur un multiple de 60 secondes t0 <- 0 inc t1 si t1 < 60 saut reti ; Continue si on est sur un multiple de 60 minutes t1 <- 0 inc t2 si t2 & 0b00011111 >= 7 saut watchdogHeure ; Continue si il est minuit t2 <- t2 + 0b00100000 ; Jour suivant t2 <- t2 & 0b11100000 ; Heure à minuit si t2 >= 0b11100000 alors t2 <- 0b00000000 ; Si on est dimanche soir, on revient à lundi matin watchdogHeure: call agirHeur reti ; Interruption ADC adc: si ADCH > reference + 5 saut eteindreChaudiere si ADCH < reference - 5 saut allumerChaudiere reti allumerChaudiere: PORTC <- 0x01 reti eteindreChaudiere: PORTC <- 0x00 reti ; Interruption timer timer: ; Affiche le digit suivant sur l'afficheur 7seg lsl selaff si selaff > 0b00001000 alors selaff <- 0b00000001 PORTC@IO <- 0xff - selaff si selaff = 0b00000001 alors PORTA@IO <- d0 si selaff = 0b00000010 alors PORTA@IO <- d1 si selaff = 0b00000100 alors PORTA@IO <- d2 si selaff = 0b00001000 alors PORTA@IO <- d3 reti