CR TP2
This commit is contained in:
parent
b0e0a8d9a4
commit
c8ada584c2
4
Makefile
4
Makefile
|
@ -5,10 +5,10 @@ default: $(subst md,pdf,$(wildcard *.md))
|
||||||
SOURCES=$(wildcard *.asm) $(wildcard *.txt)
|
SOURCES=$(wildcard *.asm) $(wildcard *.txt)
|
||||||
|
|
||||||
%.pdf: %.html
|
%.pdf: %.html
|
||||||
wkhtmltopdf --title "$* - DJERABA Taky PREUD'HOMME Geoffrey" "$<" "$@"
|
html2pdf -i "$<" -o "$@" -t "$* - DJERABA Taky PREUD'HOMME Geoffrey"
|
||||||
|
|
||||||
%.html: %.tmp ../template.html
|
%.html: %.tmp ../template.html
|
||||||
pandoc -f markdown+hard_line_breaks "$<" --template ../template.html -o "$@"
|
md2html -i "$<" -o "$@" -t ../template.html
|
||||||
|
|
||||||
%.tmp: %.md $(SOURCES)
|
%.tmp: %.md $(SOURCES)
|
||||||
markedpp "$<" > "$@"
|
markedpp "$<" > "$@"
|
||||||
|
|
40
TP1/TP1.md
40
TP1/TP1.md
|
@ -1,12 +1,10 @@
|
||||||
% Compte-rendu TP1
|
# Compte-rendu TP1
|
||||||
% DJERABA Taky PREUD'HOMME Geoffrey
|
## DJERABA Taky PREUD'HOMME Geoffrey
|
||||||
% 02/05/2017
|
|
||||||
|
|
||||||
# TP1
|
|
||||||
Ce TP est une introduction à la programmation de l'ATMEGA 2560 et à la simulation du microcontrôleur tout en rappelant les bases de la programmation en assembleur AVR8.
|
Ce TP est une introduction à la programmation de l'ATMEGA 2560 et à la simulation du microcontrôleur tout en rappelant les bases de la programmation en assembleur AVR8.
|
||||||
|
|
||||||
## Un bouton / une LED (TP10)
|
# Un bouton / une LED (TP10)
|
||||||
!include (TP10.asm lang=asm)
|
!include (TP10.asm lang=avrasm)
|
||||||
|
|
||||||
Ce programme permet d'allumer la LED située sur PA0 lorsque le bouton situé sur PA1 est appuyé.
|
Ce programme permet d'allumer la LED située sur PA0 lorsque le bouton situé sur PA1 est appuyé.
|
||||||
|
|
||||||
|
@ -15,12 +13,12 @@ Le programme fait les initialisations habituelles et celles de la configuration
|
||||||
Étant donné que PA1, normalement connecté sur un bouton (une entrée) dans l'algorithme, est connecté à une LED (une sortie) ne pouvant donc pas être controlée, le programme ne peut fonctionner qu'en mode simulation, donc pour tester que l'envoi du programme sur la carte fonctionne bien, on écrasera la valeur de r16 avec 0x01 avant l'envoi pour tester si la LED s'allume correctement.
|
Étant donné que PA1, normalement connecté sur un bouton (une entrée) dans l'algorithme, est connecté à une LED (une sortie) ne pouvant donc pas être controlée, le programme ne peut fonctionner qu'en mode simulation, donc pour tester que l'envoi du programme sur la carte fonctionne bien, on écrasera la valeur de r16 avec 0x01 avant l'envoi pour tester si la LED s'allume correctement.
|
||||||
|
|
||||||
|
|
||||||
## Chenillard (TP11)
|
# Chenillard (TP11)
|
||||||
On nous demande ici d'allumer des LED à la suite dans un ordre donné. On ne considérera que dans un premier temps une séquence allant de PA0 jusque PA7.
|
On nous demande ici d'allumer des LED à la suite dans un ordre donné. On ne considérera que dans un premier temps une séquence allant de PA0 jusque PA7.
|
||||||
|
|
||||||
Une approche typique en algorithmique serait de procéder de cette façon :
|
Une approche typique en algorithmique serait de procéder de cette façon :
|
||||||
|
|
||||||
```pseudo
|
```avrpseudo
|
||||||
TantQue vrai
|
TantQue vrai
|
||||||
Pour i allant de 0 à 8
|
Pour i allant de 0 à 8
|
||||||
PortA ← 0x00
|
PortA ← 0x00
|
||||||
|
@ -36,13 +34,13 @@ Pour que les LED ne clignotent pas trop vite, on utilisera les instructions que
|
||||||
|
|
||||||
On aurait donc un programme de ce type :
|
On aurait donc un programme de ce type :
|
||||||
|
|
||||||
```pseudo
|
```avrpseudo
|
||||||
debut: r17 ← 0b00000001
|
debut: r17 ← 0b00000001
|
||||||
|
|
||||||
boucle: Sortir r17 sur portA
|
boucle: Sortir r17 sur portA
|
||||||
Appeler pause
|
Appeler pause
|
||||||
|
|
||||||
DecalerGauche r17
|
DecalerGauche r17
|
||||||
Si r17 != 0
|
Si r17 != 0
|
||||||
Saut boucle
|
Saut boucle
|
||||||
FinSi
|
FinSi
|
||||||
|
@ -52,7 +50,7 @@ Saut debut
|
||||||
|
|
||||||
Enfin, pour faire un chenillard sur le port A et le port B (l'ordre d'allumage des LED du port B étant l'inverse de celui du port A), on duppliquera le code en le modifiant afin d'utiliser le port B, un décalage vers la droite et faire commencer le bit "volant" sur le registre de l'autre coté. Il suffit de faire en sorte qu'à la fin de la première partie on arrive à la deuxième partie et qu'on revienne à la première partie à la fin de la deuxième. On peut d'ailleurs utiliser le même registre, étant donné qu'il n'y a pas besoin de transferer d'autres données d'une partie à l'autre.
|
Enfin, pour faire un chenillard sur le port A et le port B (l'ordre d'allumage des LED du port B étant l'inverse de celui du port A), on duppliquera le code en le modifiant afin d'utiliser le port B, un décalage vers la droite et faire commencer le bit "volant" sur le registre de l'autre coté. Il suffit de faire en sorte qu'à la fin de la première partie on arrive à la deuxième partie et qu'on revienne à la première partie à la fin de la deuxième. On peut d'ailleurs utiliser le même registre, étant donné qu'il n'y a pas besoin de transferer d'autres données d'une partie à l'autre.
|
||||||
|
|
||||||
```pseudo
|
```avrpseudo
|
||||||
debutA: r17 ← 0b00000001
|
debutA: r17 ← 0b00000001
|
||||||
Sortir 0x00 sur portB
|
Sortir 0x00 sur portB
|
||||||
|
|
||||||
|
@ -75,20 +73,19 @@ Si r17 != 0
|
||||||
Saut boucleB
|
Saut boucleB
|
||||||
FinSi
|
FinSi
|
||||||
Saut debutA
|
Saut debutA
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Ce qui donne, en assembleur étendu :
|
Ce qui donne, en assembleur étendu :
|
||||||
|
|
||||||
!include (TP11.txt lang=asmplus)
|
!include (TP11.txt lang=avrasmplus)
|
||||||
|
|
||||||
De même, le port B de la carte étant utilisée par autre chose que des LED, on pourra contempler le chenillard complet avec la simulation, mais qu'un demi chenillard sur la carte.
|
De même, le port B de la carte étant utilisée par autre chose que des LED, on pourra contempler le chenillard complet avec la simulation, mais qu'un demi chenillard sur la carte.
|
||||||
|
|
||||||
## Compteur (TP12)
|
# Compteur (TP12)
|
||||||
|
|
||||||
On nous demande d'afficher ici un compteur allant de 0 à 9 sur un afficheur 7 segments. Sur la carte, le port A est relié à un afficheur 7 segments, avec chaque sortie correspondant à un segment (sans compter le point). Pour afficher un chiffre, il faut afficher allumer certains segments, donc configurer le port A d'une certaine manière. On associera à chaque chiffre sa représentation sur l'afficheur (donc une configuration du port A) dans un tableau que l'on stockera sur la mémoire du programme. À chaque fois que l'on voudra afficher un chiffre, on récupèrera sa configuration associée dans le tableau que l'on enverra sur A.
|
On nous demande d'afficher ici un compteur allant de 0 à 9 sur un afficheur 7 segments. Sur la carte, le port A est relié à un afficheur 7 segments, avec chaque sortie correspondant à un segment (sans compter le point). Pour afficher un chiffre, il faut afficher allumer certains segments, donc configurer le port A d'une certaine manière. On associera à chaque chiffre sa représentation sur l'afficheur (donc une configuration du port A) dans un tableau que l'on stockera sur la mémoire du programme. À chaque fois que l'on voudra afficher un chiffre, on récupèrera sa configuration associée dans le tableau que l'on enverra sur A.
|
||||||
|
|
||||||
```pseudo
|
```avrpseudo
|
||||||
Pour i allant de 0 à 9
|
Pour i allant de 0 à 9
|
||||||
PortA ← afficheur[i]
|
PortA ← afficheur[i]
|
||||||
FinPour
|
FinPour
|
||||||
|
@ -98,15 +95,15 @@ La carte ayant plusieurs afficheurs 7 segments, il faut sélectionner celui sur
|
||||||
|
|
||||||
Ce qui donne, en assembleur étendu :
|
Ce qui donne, en assembleur étendu :
|
||||||
|
|
||||||
!include (TP12.txt lang=asmplus)
|
!include (TP12.txt lang=avrasmplus)
|
||||||
|
|
||||||
## Afficheur numérique (TP13)
|
# Afficheur numérique (TP13)
|
||||||
|
|
||||||
On veut ici afficher sur l'affichage numérique le chiffre que l'on vient de taper sur le clavier. La partie afficheur 7 segments ayant déjà été traitée et ne nécessitant aucune modification, on se concentrera sur la partie clavier. Ce dernier de manière à ce qu'à 8 fils correspondent 16 boutons. Les fils de PC0 à PC3 sont des sorties, où l'on envoie un ou plusieur signal qui "reviennent" sur les entrées PC4 à PC7 en fonction des boutons appuyés.
|
On veut ici afficher sur l'affichage numérique le chiffre que l'on vient de taper sur le clavier. La partie afficheur 7 segments ayant déjà été traitée et ne nécessitant aucune modification, on se concentrera sur la partie clavier. Ce dernier de manière à ce qu'à 8 fils correspondent 16 boutons. Les fils de PC0 à PC3 sont des sorties, où l'on envoie un ou plusieur signal qui "reviennent" sur les entrées PC4 à PC7 en fonction des boutons appuyés.
|
||||||
|
|
||||||
On peut donc penser à deux manières différentes de tester si un bouton est appuyé. La première étant d'envoyer un signal pour chacune des entrées et de vérifier lesquelles des sorties sont activées. Cela donnerait un algorithme de ce type (on utilise un registre io pour stocker temporairement les données qui viennent d'être lues ou vont être écrites sur un port) :
|
On peut donc penser à deux manières différentes de tester si un bouton est appuyé. La première étant d'envoyer un signal pour chacune des entrées et de vérifier lesquelles des sorties sont activées. Cela donnerait un algorithme de ce type (on utilise un registre io pour stocker temporairement les données qui viennent d'être lues ou vont être écrites sur un port) :
|
||||||
|
|
||||||
```pseudo
|
```avrpseudo
|
||||||
Pour i allant de 0 à 2
|
Pour i allant de 0 à 2
|
||||||
io ← 0x00
|
io ← 0x00
|
||||||
io[3-i] ← 1
|
io[3-i] ← 1
|
||||||
|
@ -127,7 +124,7 @@ Cette méthode est certainement la plus efficace car n'effectue que 3 envois et
|
||||||
|
|
||||||
On préfèrera utiliser une autre méthode, vue en TD, qui consiste à stocker dans un tableau la configuration du port C pour chaque bouton. Par exemple, pour le bouton 7, on stockera 0b10000010, ce qui correspond à un signal sur PC1 et PC7 qui consituent les deux extrémités du bouton. On testera alors les boutons un par un en envoyant la configuration stockée dans le tableau sur le port, ce qui aura pour effet d'activer le signal de sortie correspondant (les fils PC7 à PC4 étant configurés en entrée aucun signal ne sera envoyé dessus), puis de relire la configuration du port pour vérifier si le signal d'entrée correspondant au bouton testé a bien été activé. Les fils configurés en sortie ont la particularité de garder en mémoire s'ils envoient un signal ou non, et lorsqu'on les lits il renvoient cet état mémoire, on peut donc comparer ce qu'on lit à l'élément du tableau entier (et non forcément la partie entrée).
|
On préfèrera utiliser une autre méthode, vue en TD, qui consiste à stocker dans un tableau la configuration du port C pour chaque bouton. Par exemple, pour le bouton 7, on stockera 0b10000010, ce qui correspond à un signal sur PC1 et PC7 qui consituent les deux extrémités du bouton. On testera alors les boutons un par un en envoyant la configuration stockée dans le tableau sur le port, ce qui aura pour effet d'activer le signal de sortie correspondant (les fils PC7 à PC4 étant configurés en entrée aucun signal ne sera envoyé dessus), puis de relire la configuration du port pour vérifier si le signal d'entrée correspondant au bouton testé a bien été activé. Les fils configurés en sortie ont la particularité de garder en mémoire s'ils envoient un signal ou non, et lorsqu'on les lits il renvoient cet état mémoire, on peut donc comparer ce qu'on lit à l'élément du tableau entier (et non forcément la partie entrée).
|
||||||
|
|
||||||
```pseudo
|
```avrpseudo
|
||||||
Tableau touches 0x41, 0x88, 0x48, 0x28, 0x84, 0x44, 0x24, 0x82, 0x42, 0x22
|
Tableau touches 0x41, 0x88, 0x48, 0x28, 0x84, 0x44, 0x24, 0x82, 0x42, 0x22
|
||||||
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||||
Pour test allant de 0 à 9
|
Pour test allant de 0 à 9
|
||||||
|
@ -143,11 +140,10 @@ Cette méthode est probablement plus lente, mais elle reste suffisament rapide p
|
||||||
|
|
||||||
On aura donc ceci comme code final, en assembleur étendu :
|
On aura donc ceci comme code final, en assembleur étendu :
|
||||||
|
|
||||||
!include (TP13.txt lang=asmplus)
|
!include (TP13.txt lang=avrasmplus)
|
||||||
|
|
||||||
Cependant, bien que cette méthode fonctionne sur simulateur, on a rencontré un problème lors du test du carte. En effet, les appuis des boutons n'est pas récupéré par le programme, bien que les boutons fonctionnent quand testés individuellement. On soupçone un problème de synchronisation qui fait que la lecture du port ne renvoie pas les valeurs attendues. En ajoutant une temporisation entre l'écriture et la lecture du port rien n'y fait, en restant appuyé sur le bouton non plus.
|
Cependant, bien que cette méthode fonctionne sur simulateur, on a rencontré un problème lors du test du carte. En effet, les appuis des boutons n'est pas récupéré par le programme, bien que les boutons fonctionnent quand testés individuellement. On soupçone un problème de synchronisation qui fait que la lecture du port ne renvoie pas les valeurs attendues. En ajoutant une temporisation entre l'écriture et la lecture du port rien n'y fait, en restant appuyé sur le bouton non plus.
|
||||||
|
|
||||||
<!-- TODO -->
|
Nous n'avons pas pu tester la version 2, mais il aurait certainement fallu de procéder de la façon suivante : étant donné que les port PC7 à PC5 sont utilisés à la fois pour la sélection de l'afficheur, et pour les entrées du claviers, il faut donc alterner son mode de fonctionnement. Il faut donc configurer les fils de ce port en entrée lorsque l'on utilise le clavier et en sortie quand on veut afficher. Cependant sans modification supplémentaire, on devrait se rendre compte que le microcontrôleur passe plus de temps sur la partie clavier que sur la partie affichage, et en conséquence l'afficheur 7 segment désiré reste très peu de temps allumé. Il suffirait de rajouter une temporisation dans la partie affichage du programme pour que l'afficheur 7 segment désiré soit activé majoritairement. Cela rajouterait un peu de latence au programme, mais cela devrait rester toujours acceptable pour l'utilisateur.
|
||||||
Nous n'avons pas pu tester la version 2, mais il aurait certainement fallu de procéder de la façon suivante : étant donné que les port PCX à PCX sont utilisés à la fois pour la sélection de l'afficheur, et pour les entrées du claviers, il faut donc alterner son mode de fonctionnement. Il faut donc configurer les fils de ce port en entrée lorsque l'on utilise le clavier et en sortie quand on veut afficher. Cependant sans modification supplémentaire, on devrait se rendre compte que le microcontrôleur passe plus de temps sur la partie clavier que sur la partie affichage, et en conséquence l'afficheur 7 segment désiré reste très peu de temps allumé. Il suffirait de rajouter une temporisation dans la partie affichage du programme pour que l'afficheur 7 segment désiré soit activé majoritairement. Cela rajouterait un peu de latence au programme, mais cela devrait rester toujours acceptable pour l'utilisateur.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
211
TP2/TP2.md
211
TP2/TP2.md
|
@ -1,101 +1,194 @@
|
||||||
% Compte-rendu TP2
|
# Compte-rendu TP1
|
||||||
% DJERABA Taky PREUD'HOMME Geoffrey
|
## DJERABA Taky PREUD'HOMME Geoffrey
|
||||||
% 03/05/2017
|
|
||||||
|
|
||||||
# TP2
|
|
||||||
Ce TP a pour but de nous familiariser avec la gestion des interruptions et du watchdog sur l'Atmega 2560.
|
Ce TP a pour but de nous familiariser avec la gestion des interruptions et du watchdog sur l'Atmega 2560.
|
||||||
|
|
||||||
## Un bouton/une LED et un chien de garde (TP20)
|
## Un bouton/une LED et un chien de garde (TP20)
|
||||||
|
|
||||||
!include(TP20.txt lang=asmplus)
|
!include(TP20.txt lang=avrasmplus)
|
||||||
|
|
||||||
Ce programme allume la LED lors de l'appui sur un bouton, et ce jusqu'à une seconde après l'avoir relâché. Si on rappuie sur le bouton pendant l'intervalle des 1s, le compteur est remis à zéro.
|
Ce programme allume la LED lors de l'appui sur un bouton, et ce jusqu'à une seconde après l'avoir relâché. Si on rappuie sur le bouton pendant l'intervalle des 1s, le compteur est remis à zéro.
|
||||||
|
|
||||||
## Chenillard par interruption (TP21)
|
## Chenillard par interruption (TP21)
|
||||||
|
|
||||||
```pseudo
|
On nous demande ici la même chose qu'au TP11, les différence étant :
|
||||||
|
|
||||||
|
- Les changement doivent se faire sur une interruption et non plus dans une boucle
|
||||||
|
- On peut tourner dans les deux sens et non plus dans un seul
|
||||||
|
|
||||||
|
On écrira alors notre code dans des parties d'interruption, et se contentera de duppliquer le code en "changeant le sens" pour gérer le sens inverse. La seule partie commune étant l'actualisation de la valeur des ports, on créera une fonction pour cette dernière.
|
||||||
|
|
||||||
|
On utilise le registre `port` comme un booléen. On considère qu'une valeur paire correspond à vrai, et une valeur impaire correspond à faux. On peut donc vérifier si le port est vrai ou faux en comparant son bit de point faible avec 0 ou 1. L'intérêt réside surtout dans le fait qu'on peut inverser l'état du booléen avec une simple incrémentation ou décrémentation.
|
||||||
|
|
||||||
|
La boucle principale du code reste sur l'instruction sleep, ce qui permet au microprocesseur de ne rien faire tant qu'il n'y a pas d'interruption, et ainsi économiser de l'énergie.
|
||||||
|
|
||||||
|
```avrpseudo
|
||||||
chen ← 0b00000001
|
chen ← 0b00000001
|
||||||
port ← 0x00 ; pair : port A, impair : port B
|
port ← 0x00 ; pair : chenillard sur le port A, impair : port B
|
||||||
boucle: jump boucle ; On attend là si rien ne se passe
|
|
||||||
|
boucle:
|
||||||
|
sleep ; On attend là si rien ne se passe
|
||||||
|
jmp boucle
|
||||||
|
|
||||||
horaire:
|
horaire:
|
||||||
Si (port & 0x01) == 0 alors DecalerGauche chen
|
Si (port & 0x01) == 0 alors DecalerGauche chen
|
||||||
Si (port & 0x01) == 1 alors DecalerDroite chen
|
Si (port & 0x01) == 1 alors DecalerDroite chen
|
||||||
Si chen != 0 saut boucle
|
Si chen != 0 saut boucle
|
||||||
Si (port & 0x01) == 0 alors chen ← 0b00000001
|
Si (port & 0x01) == 0 alors chen ← 0b00000001
|
||||||
Si (port & 0x01) == 1 alors chen ← 0b10000000
|
Si (port & 0x01) == 1 alors chen ← 0b10000000
|
||||||
Incrementer port ; On change de port
|
Incrementer port ; On change de port
|
||||||
call afficher
|
call afficher
|
||||||
Retourner
|
Retourner
|
||||||
|
|
||||||
antihoraire:
|
antihoraire:
|
||||||
Si (port & 0x01) == 0 alors DecalerDroite chen
|
Si (port & 0x01) == 0 alors DecalerDroite chen
|
||||||
Si (port & 0x01) == 1 alors DecalerGauche chen
|
Si (port & 0x01) == 1 alors DecalerGauche chen
|
||||||
Si chen != 0 saut boucle
|
Si chen != 0 saut boucle
|
||||||
Si (port & 0x01) == 0 alors chen ← 0b10000000
|
Si (port & 0x01) == 0 alors chen ← 0b10000000
|
||||||
Si (port & 0x01) == 1 alors chen ← 0b00000001
|
Si (port & 0x01) == 1 alors chen ← 0b00000001
|
||||||
Incrementer port ; On change de port
|
Incrementer port ; On change de port
|
||||||
call afficher
|
call afficher
|
||||||
Retourner
|
Retourner
|
||||||
|
|
||||||
afficher:
|
afficher:
|
||||||
Si (port & 0x01) == 0 alors PortB@IO ← 0x00
|
Si (port & 0x01) == 0 alors PortB@IO ← 0x00
|
||||||
Si (port & 0x01) == 1 alors PortA@IO ← 0x00
|
Si (port & 0x01) == 1 alors PortA@IO ← 0x00
|
||||||
Si (port & 0x01) == 0 alors PortA@IO ← chen
|
Si (port & 0x01) == 0 alors PortA@IO ← chen
|
||||||
Si (port & 0x01) == 1 alors PortB@IO ← chen
|
Si (port & 0x01) == 1 alors PortB@IO ← chen
|
||||||
Retourner
|
Retourner
|
||||||
```
|
```
|
||||||
|
|
||||||
|
On a pu constater qu'éxecuter une instruction de décalage en tant qu'instruction conditionelle (j'entend par là ce qui est éxécuté lorsque la condition d'un `si` est vraie) n'est pas possible avec l'assembleur étendu (bien que tout à fait réalisable en assembleur standard). On a donc triché un peu et utilisé le fait que multiplier ou diviser un nombre par sa base (ici 2) permet de décaler ses chiffres vers la gauche ou vers la droite repectivement.
|
||||||
|
|
||||||
|
!include(TP21.txt lang=avrasmplus)
|
||||||
|
|
||||||
## Compteur (TP22)
|
## Compteur (TP22)
|
||||||
|
|
||||||
1)
|
On nous demande de faire l'affichage d'un compteur qui s'incrémente toutes les secondes.
|
||||||
|
|
||||||
```pseudo
|
L'affichage sur un afficheur 7 segments avait déjà été réalisé au TP précédent, on peut reprendre le tableau de correspondances nombre ↔ représentation sur les 7 segments.
|
||||||
|
|
||||||
|
Pour les différentes étapes proposées, voici ce qu'il faut faire :
|
||||||
|
|
||||||
|
## Comptage de 1 digit sur le simulateur
|
||||||
|
|
||||||
|
On considère un registre d0 stockant ce digit (et non sa représentation sur le 7 segment). On configure le Watchdog de façon à ce qu'il effectue une interruption toutes les secondes. L'interruption se chargera d'incrémenter ce registre et de le remettre à 0 au cas où il viendrait à dépasser 9, puis d'envoyer sa représentation sur le port A.
|
||||||
|
|
||||||
|
|
||||||
|
```avrpseudo
|
||||||
d0 ← 0
|
d0 ← 0
|
||||||
|
|
||||||
Configurer Watchdog: Interruption toutes les secondes sur wd
|
Configurer Watchdog: Interruption toutes les secondes sur wd
|
||||||
|
|
||||||
boucle: jump boucle
|
boucle:
|
||||||
|
sleep
|
||||||
|
jmp boucle
|
||||||
|
|
||||||
wd:
|
wd:
|
||||||
Incrementer d0
|
; Logique
|
||||||
Si d0 > 10 jump d0 ← 0:
|
Incrementer d0
|
||||||
|
Si d0 > 10 saut d0 ← 0:
|
||||||
|
; Affichage
|
||||||
|
Sortir afficheur[d0] sur portA
|
||||||
|
Retourner
|
||||||
```
|
```
|
||||||
4)
|
|
||||||
|
|
||||||
```pseudo
|
## Comptage de 1 digit sur la maquette
|
||||||
|
|
||||||
|
Le code ne doit à priori pas changer, il faut juste s'assurer qu'un bit parmi PC5 à PC7 soit à un afin que le digit soit bien affihé sur l'un des trois segments.
|
||||||
|
|
||||||
|
Cependant, on se rend compte que le Watchdog sur la carte se comporte bizarrement : en effet il compte approximativement 100 fois plus vite que sur le simulateur, pour exactement le même code. Nous n'avons pas réussi à résoudre ce problème, cependant nous aurions pu utiliser le timer (qui lui semble fonctionner) qui incrémente un registre, et éxecuter le code de l'interruption dès que ce registre dépasse une certaine valeur ($\frac{1}{\text{periode du timer}}$) correspondant à une seconde.
|
||||||
|
|
||||||
|
## Comptage de 3 digits sur le simulateur
|
||||||
|
|
||||||
|
À d0 viennent s'ajouter d1 et d2, correspondant aux digit de poids plus élevés. Ici, dès qu'un digit dépasse 9, il se remet à 0 et incrémente le suivant.
|
||||||
|
Il suffit ensuite d'afficher chaque digit sur son port correspondant.
|
||||||
|
|
||||||
|
```avrpseudo
|
||||||
d2 ← 0
|
d2 ← 0
|
||||||
d1 ← 0
|
d1 ← 0
|
||||||
d0 ← 0
|
d0 ← 0
|
||||||
select ← 0x01
|
|
||||||
io ← 0x00
|
|
||||||
|
|
||||||
Configurer Watchdog: Interruption toutes les secondes sur wd
|
Configurer Watchdog: Interruption toutes les secondes sur wd
|
||||||
Configurer timer0: Interruption toutes les 8-16 ms sur tm
|
|
||||||
|
|
||||||
boucle: jump boucle
|
boucle:
|
||||||
|
sleep
|
||||||
|
jmp boucle
|
||||||
|
|
||||||
wd:
|
wd:
|
||||||
Incrementer d0
|
Incrementer d0
|
||||||
Si d0 < 10 Retourner
|
Si d0 < 10 Saut afficher
|
||||||
d0 ← 0
|
d0 ← 0
|
||||||
Incrementer d1
|
Incrementer d1
|
||||||
Si d1 < 10 Retourner
|
Si d1 < 10 Saut afficher
|
||||||
d1 ← 0
|
d1 ← 0
|
||||||
Incrementer d2
|
Incrementer d2
|
||||||
Si d2 < 10 Retourner
|
Si d2 < 10 Saut afficher
|
||||||
d2 ← 0
|
d2 ← 0
|
||||||
Retourner ; Comportement si >999 : on revient à 000
|
; Comportement si >999 : on revient à 000
|
||||||
|
|
||||||
tm:
|
afficher:
|
||||||
PortC@IO ← select
|
Sortir afficheur[d2] sur portC
|
||||||
Si select = 0x01 alors io ← afficheur@ROM[d0]
|
Sortir afficheur[d1] sur portB
|
||||||
Si select = 0x02 alors io ← afficheur@ROM[d1]
|
Sortir afficheur[d0] sur portA
|
||||||
Si select = 0x03 alors io ← afficheur@ROM[d2]
|
Retourner
|
||||||
DecalerGauche io
|
|
||||||
Si io > 0x04 alors io ← 0x01
|
|
||||||
Retourner
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Comptage de 3 digits sur la maquette
|
||||||
|
|
||||||
|
C'est ici un peu plus compliqué, en effet le port A est utilisé pour chacun des afficheurs 7 segments. On peut cependant sélectionner l'afficheur avec le port C (PC5 à PC7). L'astuce consiste à afficher un afficheur à la suite et ce suffisament rapidement (un affichage peut se faire entre 8 et 16 ms) pour que l'œil ait l'impression qu'ils soient tous affichés en même temps. On utilisera pour ça un timer, qui toutes les 4 ms ($<\frac{16}{3}$) changera le digit affiché.
|
||||||
|
|
||||||
|
On stockera le digit en cours d'affichage dans un registre `select`. Il contiendra en réalité la configuration du PortC à envoyer pour prendre l'afficheur voulu. Il suffit ensuite de le décaler vers la droite ou vers la gauche et de recommencer (tel un chenillard) à chauque interruption de timer.
|
||||||
|
|
||||||
|
```avrpseudo
|
||||||
|
d2 ← 0
|
||||||
|
d1 ← 0
|
||||||
|
d0 ← 0
|
||||||
|
select ← 0x80
|
||||||
|
|
||||||
|
Configurer Watchdog: Interruption toutes les secondes sur wd
|
||||||
|
Configurer timer0: Interruption toutes les 4 ms sur tm
|
||||||
|
|
||||||
|
boucle:
|
||||||
|
sleep
|
||||||
|
jmp boucle
|
||||||
|
|
||||||
|
wd:
|
||||||
|
Incrementer d0
|
||||||
|
Si d0 < 10 Retourner
|
||||||
|
d0 ← 0
|
||||||
|
Incrementer d1
|
||||||
|
Si d1 < 10 Retourner
|
||||||
|
d1 ← 0
|
||||||
|
Incrementer d2
|
||||||
|
Si d2 < 10 Retourner
|
||||||
|
d2 ← 0
|
||||||
|
Retourner ; Comportement si >999 : on revient à 000
|
||||||
|
|
||||||
|
tm:
|
||||||
|
PortC@IO ← select
|
||||||
|
Si select = 0x80 alors PortA ← afficheur[d0]
|
||||||
|
Si select = 0x40 alors PortA ← afficheur[d1]
|
||||||
|
Si select = 0x20 alors PortA ← afficheur[d2]
|
||||||
|
DecalerGauche select
|
||||||
|
Si select = 0 alors select ← 0x80
|
||||||
|
Retourner
|
||||||
|
```
|
||||||
|
|
||||||
|
En assembleur étendu, cela donne :
|
||||||
|
|
||||||
|
!include(TP23.txt lang=avrasmplus)
|
||||||
|
|
||||||
## Minuteur d'un four (TP23)
|
## Minuteur d'un four (TP23)
|
||||||
|
|
||||||
|
Cet exercice nous propose de rassembler ce que l'on a appris dans ce TP dans un seul programme. L'algorithme étant plutôt simple, il sera décrit en commentaire du programme.
|
||||||
|
|
||||||
|
Quelques notes cependant :
|
||||||
|
|
||||||
|
- On utilise le fait qu'une décrémentation d'un registre déjà à 0 provoque un dépassement et sa valeur repasse à 255, et le flag du dépassement est mis à 1. Pour savoir si un nombre était à 0 avant de faire une décrémentation, on vérifiera si le nombre n'est plus dans son intervalle de définition "normal" (0-9 pour un chiffre). Il aurait été plus "propre" de vérifier le drapeau, mais plus coûteux (utilise un masque et une comparaison).
|
||||||
|
- Le watchdog est initialisé au début du programme et n'est plus réinitialisé après, son interruption associée a un effet en fonction de si le four est en route ou non. Cela a deux désavantages : le four compte entre 0 et 1 seconde de moins que nécessaire en fonction de quand a été appuyé le bouton marche par rapport à l'état du watchdog, et une interruption est effectuée chaque seconde même si le four est en mode veille (ce qui n'est pas une bonne idée d'un point de vue énergétique). Il aurait été plus judicieux d'activer le watchdog lorsque de l'appui sur le bouton marche et de l'arrêter lors de la fin de décompte.
|
||||||
|
- Notre four affiche 0 pendant une seconde alors que la plupart des fours affichent 1 pendant une seconde et puis s'arrêtent. Ce comportement n'a pas été spécifié dans le cahier des charges, on en a donc profité pour simplifier notre logique.
|
||||||
|
|
||||||
|
!include (TP23.txt lang=avrasmplus)
|
||||||
|
|
||||||
|
|
||||||
|
|
17
TP2/TP21.txt
17
TP2/TP21.txt
|
@ -1,14 +1,10 @@
|
||||||
.equ PINA = 0x00 ; définition des adresses des ports
|
.equ PINA = 0x00 ; définition des adresses des ports
|
||||||
.equ DDRA = 0x01
|
.equ DDRA = 0x01
|
||||||
.equ PORTA = 0x02
|
.equ PORTA = 0x02
|
||||||
.equ PINB = 0x03
|
|
||||||
.equ DDRB = 0x04
|
|
||||||
.equ PORTB = 0x05
|
|
||||||
|
|
||||||
.equ EIMSK = 0x3D
|
.equ EIMSK = 0x3D
|
||||||
.equ EICRA = 0x69
|
.equ EICRA = 0x69
|
||||||
.equ EICRB = 0x6A
|
.equ EICRB = 0x6A
|
||||||
.equ SREG = 0x3F
|
|
||||||
|
|
||||||
.equ WDTCSR = 0x60
|
.equ WDTCSR = 0x60
|
||||||
|
|
||||||
|
@ -23,10 +19,10 @@
|
||||||
; Vecteur RESET
|
; Vecteur RESET
|
||||||
jmp debut
|
jmp debut
|
||||||
|
|
||||||
.org 0x0002 ; Définition du code à éxecuter lors des interruption
|
.org 0x0002 ; Définition du code à éxecuter lors des interruption
|
||||||
jmp horaire
|
jmp horaire
|
||||||
|
|
||||||
.org 0x0004 ; Définition du code à éxecuter lors des interruption
|
.org 0x0004 ; Définition du code à éxecuter lors des interruption
|
||||||
jmp antihoraire
|
jmp antihoraire
|
||||||
|
|
||||||
.org 0x0080
|
.org 0x0080
|
||||||
|
@ -38,8 +34,7 @@ debut:
|
||||||
EIMSK <- 0b00000011 ; On active les interruptions PD0 et PD1 sur front descendant
|
EIMSK <- 0b00000011 ; On active les interruptions PD0 et PD1 sur front descendant
|
||||||
EICRA <- 0b00001010
|
EICRA <- 0b00001010
|
||||||
EICRB <- 0b00000000
|
EICRB <- 0b00000000
|
||||||
; On active les interruptions au niveau du µP
|
; On active les interruptions au niveau du µP
|
||||||
SREG <- 0b10000000
|
|
||||||
|
|
||||||
chen <- 0b00000001
|
chen <- 0b00000001
|
||||||
chen <- 0xAA
|
chen <- 0xAA
|
||||||
|
@ -48,7 +43,7 @@ debut:
|
||||||
sei
|
sei
|
||||||
|
|
||||||
boucle:
|
boucle:
|
||||||
sleep ; On ne fait rien jusqu'à la prochaine interruption
|
sleep ; On ne fait rien jusqu'à la prochaine interruption
|
||||||
jump boucle
|
jump boucle
|
||||||
|
|
||||||
horaire:
|
horaire:
|
||||||
|
@ -84,4 +79,4 @@ afficher:
|
||||||
si (port & 0x01) == 1 alors PORTA@IO <- 0x00
|
si (port & 0x01) == 1 alors PORTA@IO <- 0x00
|
||||||
si (port & 0x01) == 0 alors PORTA@IO <- chen
|
si (port & 0x01) == 0 alors PORTA@IO <- chen
|
||||||
si (port & 0x01) == 1 alors PORTB@IO <- chen
|
si (port & 0x01) == 1 alors PORTB@IO <- chen
|
||||||
ret
|
ret
|
||||||
|
|
56
TP2/TP22.txt
56
TP2/TP22.txt
|
@ -1,15 +1,10 @@
|
||||||
.equ PINA = 0x00 ; définition des adresses des ports
|
.equ PINA = 0x00 ; définition des adresses des ports
|
||||||
.equ DDRA = 0x01
|
.equ DDRA = 0x01
|
||||||
.equ PORTA = 0x02
|
.equ PORTA = 0x02
|
||||||
.equ PINB = 0x03
|
|
||||||
.equ DDRB = 0x04
|
|
||||||
.equ PORTB = 0x05
|
|
||||||
.equ PINC = 0x06
|
.equ PINC = 0x06
|
||||||
.equ DDRC = 0x07
|
.equ DDRC = 0x07
|
||||||
.equ PORTC = 0x08
|
.equ PORTC = 0x08
|
||||||
|
|
||||||
.equ SREG = 0x3F
|
|
||||||
|
|
||||||
.equ WDTCSR = 0x60
|
.equ WDTCSR = 0x60
|
||||||
.equ TCCR0A = 0x24
|
.equ TCCR0A = 0x24
|
||||||
.equ TCCR0B = 0x25
|
.equ TCCR0B = 0x25
|
||||||
|
@ -29,10 +24,10 @@
|
||||||
; Vecteur RESET
|
; Vecteur RESET
|
||||||
jmp debut
|
jmp debut
|
||||||
|
|
||||||
.org 0x0018
|
.org 0x0018 ; Interruption du watchdog
|
||||||
jmp wd
|
jmp wd
|
||||||
|
|
||||||
.org 0x002E
|
.org 0x002E ; Interruption du timer
|
||||||
jmp tm
|
jmp tm
|
||||||
|
|
||||||
.org 0x0080
|
.org 0x0080
|
||||||
|
@ -48,22 +43,19 @@ debut:
|
||||||
select <- 0x01
|
select <- 0x01
|
||||||
|
|
||||||
cli
|
cli
|
||||||
SREG <- 0b10000000
|
|
||||||
|
|
||||||
; Configuration des ports
|
; Configuration des ports
|
||||||
DDRA@IO <- 0xFF
|
DDRA@IO <- 0xFF
|
||||||
DDRB@IO <- 0xFF
|
|
||||||
DDRC@IO <- 0xFF
|
DDRC@IO <- 0xFF
|
||||||
|
|
||||||
; Watchdog toutes les secondes
|
; Watchdog toutes les secondes
|
||||||
WDTCSR <- 0x10
|
WDTCSR <- 0x10
|
||||||
WDTCSR <- 0b01000110
|
WDTCSR <- 0b01000110
|
||||||
|
|
||||||
; Timer toutes les 8-16ms
|
; Timer toutes les 2 ms
|
||||||
;TCCR0A@IO <- 0x00
|
TCCR0A@IO <- 0x00
|
||||||
;TCCR0B@IO <- 0x04
|
TCCR0B@IO <- 0x04
|
||||||
;TIMSK0 <- 0x01
|
TIMSK0 <- 0x01
|
||||||
;TIFR0 <- 0x01
|
TIFR0 <- 0x01
|
||||||
sei
|
sei
|
||||||
|
|
||||||
boucle:
|
boucle:
|
||||||
|
@ -72,28 +64,26 @@ boucle:
|
||||||
|
|
||||||
wd:
|
wd:
|
||||||
inc d0
|
inc d0
|
||||||
si d0 < 10 saut finwd
|
si d0 < 10 saut affichage
|
||||||
d0 <- 0
|
d0 <- 0
|
||||||
inc d1
|
inc d1
|
||||||
si d1 < 10 saut finwd
|
si d1 < 10 saut affichage
|
||||||
d1 <- 0
|
d1 <- 0
|
||||||
inc d2
|
inc d2
|
||||||
si d2 < 10 saut finwd
|
si d2 < 10 saut affichage
|
||||||
d2 <- 0
|
d2 <- 0
|
||||||
finwd:
|
affichage:
|
||||||
PORTA@IO <- afficheur@ROM[d1]
|
; Affichage Simulateur
|
||||||
PORTC@IO <- 0x40
|
; PORTC@IO <- afficheur@ROM[d0]
|
||||||
|
; PORTB@IO <- afficheur@ROM[d1]
|
||||||
|
; PORTA@IO <- afficheur@ROM[d2]
|
||||||
reti
|
reti
|
||||||
|
|
||||||
tm:
|
tm:
|
||||||
;PortC@IO <- select
|
PortC@IO <- select
|
||||||
;si select = 0x80 alors PortA@IO <- afficheur@ROM[d0]
|
si select = 0x80 alors PortA@IO <- afficheur@ROM[d0]
|
||||||
;si select = 0x40 alors PortA@IO <- afficheur@ROM[d1]
|
si select = 0x40 alors PortA@IO <- afficheur@ROM[d1]
|
||||||
;si select = 0x20 alors PortA@IO <- afficheur@ROM[d2]
|
si select = 0x20 alors PortA@IO <- afficheur@ROM[d2]
|
||||||
;lsl select
|
lsl select
|
||||||
;si select = 0 alors select <- 0x20
|
si select = 0 alors select <- 0x20
|
||||||
;PORTC@IO <- afficheur@ROM[d0]
|
reti
|
||||||
;PORTB@IO <- afficheur@ROM[d1]
|
|
||||||
PORTA@IO <- afficheur@ROM[d2]
|
|
||||||
PORTC@IO <- 0x40
|
|
||||||
reti
|
|
||||||
|
|
62
TP2/TP23.txt
62
TP2/TP23.txt
|
@ -1,20 +1,11 @@
|
||||||
.equ PINA = 0x00 ; définition des adresses des ports
|
.equ PINA = 0x00 ; définition des adresses des ports
|
||||||
.equ DDRA = 0x01
|
.equ DDRA = 0x01
|
||||||
.equ PORTA = 0x02
|
.equ PORTA = 0x02
|
||||||
.equ PINB = 0x03
|
|
||||||
.equ DDRB = 0x04
|
|
||||||
.equ PORTB = 0x05
|
|
||||||
.equ PIND = 0x09
|
.equ PIND = 0x09
|
||||||
.equ DDRD = 0x0A
|
.equ DDRD = 0x0A
|
||||||
.equ PORTD = 0x0B
|
.equ PORTD = 0x0B
|
||||||
|
|
||||||
.equ SREG = 0x3F
|
|
||||||
|
|
||||||
.equ WDTCSR = 0x60
|
.equ WDTCSR = 0x60
|
||||||
.equ TCCR0A = 0x24
|
|
||||||
.equ TCCR0B = 0x25
|
|
||||||
.equ TIMSK0 = 0x6E
|
|
||||||
.equ TIFR0 = 0x35
|
|
||||||
|
|
||||||
.equ EIMSK = 0x3D
|
.equ EIMSK = 0x3D
|
||||||
.equ EICRA = 0x69
|
.equ EICRA = 0x69
|
||||||
|
@ -54,13 +45,12 @@ afficheur:
|
||||||
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||||
|
|
||||||
debut:
|
debut:
|
||||||
d1 <- 0
|
d1 <- 0 ; Digit dizaines
|
||||||
d0 <- 0
|
d0 <- 0 ; Digit unités
|
||||||
route <- 0
|
route <- 0 ; 1 : Four en marche, 0 : Four à l'arrêt
|
||||||
|
|
||||||
cli
|
cli
|
||||||
SREG <- 0b10000000
|
|
||||||
|
|
||||||
; Configuration des ports
|
; Configuration des ports
|
||||||
DDRA@IO <- 0xFF
|
DDRA@IO <- 0xFF
|
||||||
DDRB@IO <- 0xFF
|
DDRB@IO <- 0xFF
|
||||||
|
@ -80,22 +70,22 @@ debut:
|
||||||
call affiche
|
call affiche
|
||||||
|
|
||||||
boucle:
|
boucle:
|
||||||
sleep
|
sleep ; Le programme ne fonctionne que sur interruption
|
||||||
jump boucle
|
jump boucle
|
||||||
|
|
||||||
b1s:
|
b1s: ; Bouton +1 seconde
|
||||||
inc d0
|
inc d0 ; Incrémente le chiffre des unités
|
||||||
si d0 < 10 saut finb1s
|
si d0 < 10 saut finb1s ; Si il reste inférieur à 10, on affiche juste
|
||||||
d0 <- 0
|
d0 <- 0 ; Sinon, on le remet à 0 et on fait comme si on avait appuyé sur le bouton +10 secondes
|
||||||
jump b10s
|
jump b10s
|
||||||
finb1s:
|
finb1s:
|
||||||
call affiche
|
call affiche
|
||||||
reti
|
reti
|
||||||
|
|
||||||
b10s:
|
b10s: ; Bouton +10 secondes
|
||||||
inc d1
|
inc d1 ; On incrémente le chiffre des dizaines
|
||||||
si d1 < 10 saut finb10s
|
si d1 < 10 saut finb10s ; Si il reste inférieur à 10, on affiche juste
|
||||||
d0 <- 9
|
d0 <- 9 ; Sinon, on bloque à 99
|
||||||
d1 <- 9
|
d1 <- 9
|
||||||
finb10s:
|
finb10s:
|
||||||
call affiche
|
call affiche
|
||||||
|
@ -106,30 +96,30 @@ affiche:
|
||||||
PORTB@IO <- afficheur@ROM[d0]
|
PORTB@IO <- afficheur@ROM[d0]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
marche:
|
marche: ; Bouton marche
|
||||||
route <- 1
|
route <- 1 ; Met la minuterie en route
|
||||||
PORTD@IO <- 0x80
|
PORTD@IO <- 0x80
|
||||||
reti
|
reti
|
||||||
|
|
||||||
arret:
|
arret: ; Bouton annuler
|
||||||
route <- 0
|
route <- 0 ; Remet tout dans sa position d'origine
|
||||||
d0 <- 0
|
d0 <- 0
|
||||||
d1 <- 0
|
d1 <- 0
|
||||||
call affiche
|
call affiche
|
||||||
reti
|
reti
|
||||||
|
|
||||||
wd:
|
wd:
|
||||||
si route = 0 saut finwd
|
si route = 0 saut finwd ; Si on est pas en route, ne rien faire
|
||||||
dec d0
|
dec d0 ; Si on est en route, décrémenter le compteur
|
||||||
si d0 < 10 saut prefinwd
|
si d0 < 10 saut prefinwd ; Si le chiffre des unités était strictement supérieur à 0, juste actualiser l'affichage
|
||||||
d0 <- 9
|
d0 <- 9 ; Si le chiffre des unités était à 0, il passe à 9 et on décrémente celui des dizaines
|
||||||
dec d1
|
dec d1
|
||||||
si d1 < 10 saut prefinwd
|
si d1 < 10 saut prefinwd ; Si le chiffre des dizaines était strictement supérieur à 0, juste actualiser l'affichage
|
||||||
route <- 0
|
route <- 0 ; Sinon, c'est qu'on était à 00, donc il faut éteindre le four
|
||||||
PORTD@IO <- 0x00
|
PORTD@IO <- 0x00
|
||||||
d0 <- 0
|
d0 <- 0 ; On remet à 00 (avant ces lignes d0 = 9 et d1 = 255)
|
||||||
d1 <- 0
|
d1 <- 0
|
||||||
prefinwd:
|
prefinwd:
|
||||||
call affiche
|
call affiche
|
||||||
finwd:
|
finwd:
|
||||||
reti
|
reti
|
||||||
|
|
125
TP2/a
Normal file
125
TP2/a
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
.equ PINA = 0x00 ; définition des adresses des ports
|
||||||
|
.equ DDRA = 0x01
|
||||||
|
.equ PORTA = 0x02
|
||||||
|
.equ PIND = 0x09
|
||||||
|
.equ DDRD = 0x0A
|
||||||
|
.equ PORTD = 0x0B
|
||||||
|
|
||||||
|
.equ WDTCSR = 0x60
|
||||||
|
|
||||||
|
.equ EIMSK = 0x3D
|
||||||
|
.equ EICRA = 0x69
|
||||||
|
.equ EICRB = 0x6A
|
||||||
|
|
||||||
|
.equ RAMEND = 0x21FF
|
||||||
|
.equ SPH = 0x3E ; initialisation de la pile
|
||||||
|
.equ SPL = 0x3D
|
||||||
|
|
||||||
|
.def d1 = r20
|
||||||
|
.def d0 = r21
|
||||||
|
.def route = r22
|
||||||
|
|
||||||
|
.org 0x000
|
||||||
|
; Vecteur RESET
|
||||||
|
jmp debut
|
||||||
|
|
||||||
|
.org 0x0002
|
||||||
|
jmp b10s
|
||||||
|
|
||||||
|
.org 0x0004
|
||||||
|
jmp b1s
|
||||||
|
|
||||||
|
.org 0x0006
|
||||||
|
jmp marche
|
||||||
|
|
||||||
|
.org 0x0008
|
||||||
|
jmp arret
|
||||||
|
|
||||||
|
.org 0x0018
|
||||||
|
jmp wd
|
||||||
|
|
||||||
|
.org 0x0080
|
||||||
|
|
||||||
|
afficheur:
|
||||||
|
.DB 0x7E, 0x0C, 0x37, 0x9F, 0x4D, 0xDB, 0xFB, 0x0E, 0xFF, 0xDF
|
||||||
|
; 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||||
|
|
||||||
|
debut:
|
||||||
|
d1 <- 0 ; Digit dizaines
|
||||||
|
d0 <- 0 ; Digit unités
|
||||||
|
route <- 0 ; 1 : Four en marche, 0 : Four à l'arrêt
|
||||||
|
|
||||||
|
cli
|
||||||
|
|
||||||
|
; Configuration des ports
|
||||||
|
DDRA@IO <- 0xFF
|
||||||
|
DDRB@IO <- 0xFF
|
||||||
|
DDRD@IO <- 0x80
|
||||||
|
|
||||||
|
; Interruptions
|
||||||
|
EIMSK <- 0b00001111 ; On active les interruptions PD[3:0] sur front descendant
|
||||||
|
EICRA <- 0b10101010
|
||||||
|
EICRB <- 0b00000000
|
||||||
|
|
||||||
|
; Watchdog toutes les secondes
|
||||||
|
WDTCSR <- 0x10
|
||||||
|
WDTCSR <- 0b01000110
|
||||||
|
|
||||||
|
sei
|
||||||
|
|
||||||
|
call affiche
|
||||||
|
|
||||||
|
boucle:
|
||||||
|
sleep ; Le programme ne fonctionne que sur interruption
|
||||||
|
jump boucle
|
||||||
|
|
||||||
|
b1s: ; Bouton +1 seconde
|
||||||
|
inc d0 ; Incrémente le chiffre des unités
|
||||||
|
si d0 < 10 saut finb1s ; Si il reste inférieur à 10, on affiche juste
|
||||||
|
d0 <- 0 ; Sinon, on le remet à 0 et on fait comme si on avait appuyé sur le bouton +10 secondes
|
||||||
|
jump b10s
|
||||||
|
finb1s:
|
||||||
|
call affiche
|
||||||
|
reti
|
||||||
|
|
||||||
|
b10s: ; Bouton +10 secondes
|
||||||
|
inc d1 ; On incrémente le chiffre des dizaines
|
||||||
|
si d1 < 10 saut finb10s ; Si il reste inférieur à 10, on affiche juste
|
||||||
|
d0 <- 9 ; Sinon, on bloque à 99
|
||||||
|
d1 <- 9
|
||||||
|
finb10s:
|
||||||
|
call affiche
|
||||||
|
reti
|
||||||
|
|
||||||
|
affiche:
|
||||||
|
PORTA@IO <- afficheur@ROM[d1]
|
||||||
|
PORTB@IO <- afficheur@ROM[d0]
|
||||||
|
ret
|
||||||
|
|
||||||
|
marche: ; Bouton marche
|
||||||
|
route <- 1 ; Met la minuterie en route
|
||||||
|
PORTD@IO <- 0x80
|
||||||
|
reti
|
||||||
|
|
||||||
|
arret: ; Bouton annuler
|
||||||
|
route <- 0 ; Remet tout dans sa position d'origine
|
||||||
|
d0 <- 0
|
||||||
|
d1 <- 0
|
||||||
|
call affiche
|
||||||
|
reti
|
||||||
|
|
||||||
|
wd:
|
||||||
|
si route = 0 saut finwd ; Si on est pas en route, ne rien faire
|
||||||
|
dec d0 ; Si on est en route, décrémenter le compteur
|
||||||
|
si d0 < 10 saut prefinwd ; Si le chiffre des unités était strictement supérieur à 0, juste actualiser l'affichage
|
||||||
|
d0 <- 9 ; Si le chiffre des unités était à 0, il passe à 9 et on décrémente celui des dizaines
|
||||||
|
dec d1
|
||||||
|
si d1 < 10 saut prefinwd ; Si le chiffre des dizaines était strictement supérieur à 0, juste actualiser l'affichage
|
||||||
|
route <- 0 ; Sinon, c'est qu'on était à 00, donc il faut éteindre le four
|
||||||
|
PORTD@IO <- 0x00
|
||||||
|
d0 <- 0 ; On remet à 00 (avant ces lignes d0 = 9 et d1 = 255)
|
||||||
|
d1 <- 0
|
||||||
|
prefinwd:
|
||||||
|
call affiche
|
||||||
|
finwd:
|
||||||
|
reti
|
|
@ -1,29 +1,54 @@
|
||||||
<!DOCTYPE HTML>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="fr">
|
||||||
<head>
|
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
|
|
||||||
<title>$title$</title>
|
|
||||||
<meta name="date" content="$date$" scheme="DD/MM/YYYY">
|
|
||||||
<meta name="author" content="$author$">
|
|
||||||
<style type="text/css">
|
|
||||||
body {
|
|
||||||
font-family: "Source Sans Pro", Calibri, Carlito, sans-serif;
|
|
||||||
font-size: 15pt;
|
|
||||||
margin: 1cm;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media print {
|
<head>
|
||||||
a {
|
<meta charset="utf-8">
|
||||||
color: black;
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
text-decoration: none;
|
<meta charset="UTF-8">
|
||||||
}
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/xcode.min.css" integrity="sha256-OED7Gmqde0cMVVeo1zVd+3fBD4EST32D4h9YT7KY0aY=" crossorigin="anonymous" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css" integrity="sha384-wITovz90syo1dJWVh32uuETPVEtGigN07tkttEqPv+uR2SE/mbQcG7ATL28aI9H0" crossorigin="anonymous">
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: Cantarell;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
</style>
|
code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
h1, h2, h3 {
|
||||||
|
text-decoration: underline;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
h1:first-of-type {
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
h2:first-of-type {
|
||||||
|
color: gray;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
@media print {
|
||||||
|
code {page-break-inside: avoid;}
|
||||||
|
h1, h2, h3, h4, h5 {page-break-after: avoid;}
|
||||||
|
img {page-break-after: avoid;}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>%TITLE%</title>
|
||||||
</head>
|
</head>
|
||||||
<body lang="fr-FR">
|
|
||||||
<h1>$title$</h1>
|
<body>
|
||||||
<h2>$author$</h2>
|
<main class="page-content" aria-label="Content">
|
||||||
<hr/>
|
%BODY%
|
||||||
$body$
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
Reference in a new issue