principal.txt 11 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
; É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 <- 0x76
    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