TP6 - serie asynchrone

TP n°6 – Liaison série asynchrone
Noms des étudiants :
Attention un sujet sera ramassé à la fin de la séance avec les différents fichiers imprimés. Chaque fichier doit
comporter les noms des étudiants en premier commentaire.
1-
Objectif
Travailler sur la liaison série asynchrone et gérer des interruptions depuis ce périphérique.
Contrôler à distance le robot roulant.
2-
Préparation du Projet
•
Créer le dossier suivant : "Mes Documents / Projets MPLAB / Projet 06 – Usart"
•
Créer les dossiers suivants :
"Mes Documents / Projets MPLAB / Projet 06 – Usart / Sources"
"Mes Documents / Projets MPLAB / Projet 06 – Usart / Compte-Rendu"
•
Créer un projet MPLAB pour travailler avec le compilateur C18 (choisir « Microchip C18
Toolsuite ») dans le dossier :
"Mes Documents / Projets MPLAB / Projet 06 – Usart ". Vous nommerez ce projet
"ProjetUsart". Utilisez le guide de référence.
•
Copier le fichier « config.h » du TP précédent que vous enregistrerez dans le dossier
"Sources". Vérifier que le signal provenant du quartz (Fquartz = 10 MHz) soit directement
utilisé comme signal d’horloge par le PIC (Fosc = Fquartz= 10 MHz), avec la configuration
suivante :
#pragma config OSC = HS
3-
Exo1 - Emission et réception d’un caractère
On reprend l’exercice du TD concernant l’USART.
• Déterminer la nouvelle valeur à mettre dans le registre SPBRG si celui-ci est défini comme
un registre 8 bits et que la vitesse de transmission est fixé à 9600 bauds. Quelles sont les
valeurs des bits SYNC, BRGH et BRG16 dans ce cas ?
•
Dans votre projet, écrire le fichier « exo1.c » qui contiendra les fonctions suivantes :
Formation par Apprentissage
Département Geii, IUT de Marseille
Page 1 sur 6
« void InitUsart(void) », « void InitPort(void) » et « void main(void) ».
La fonction void InitUsart(void) sera modifiée en prenant en compte les valeurs définies
juste avant.
Un essai matériel sera réalisé en utilisant les modules sans fils « Xbee » disponible sur la carte du
µC et sur une clé USB. Cette dernière sera mise sur un port USB du PC. Vous utiliserez le logiciel de
gestion X-CTU (disponible depuis votre bureau) qui permet à la fois de configurer les modules
Xbee (déjà fait par l’enseignant) et d’utiliser une fenêtre d’envoi et de réception de caractères ASCII.
Pour le PC et le microcontrôleur, les deux modules se comportent comme une liaison série asynchrone filaire type RS232 !
•
Programmer le µC sur la carte d’expérimentation (mode « programmer »). Connecter la clé
USB supportant un des modules Xbee. Attendez quelques secondes le temps que Windows
reconnaisse le module, puis exécuter X-CTU. Sélectionner le Port COM correspondant au
module Xbee (généralement indiqué comme « USB Serial Port (COMx) »). Vérifier les paramètres dans l’onglet « PC Settings » (par défaut) :
o
o
o
o
o
Baud : 9600
Flow control : none
Data bits : 8
Parity : none
Stop bits : 1
•
Puis aller dans l’onglet « Terminal » et dans la fenêtre, taper sur n’importe quelle touche de
l’alphabet.
-
Remarque concernant « terminal » : lorsque l’on appuie sur une touche au clavier, « terminal » envoie sur la
liaison série le caractère tapé (en fait son code ASCII sur 8 bits). Lorsque « terminal » reçoit un caractère sur la
liaison série, il l’affiche !
Pour tester votre programme, c’est très simple, vous taper un caractère, qui sera envoyé au µC par la liaison
série asynchrone (sans fil via les modules Xbee). La fonction principale va modifier la valeur du code ASCII et
retourner au terminal le nouveau caractère qui sera affiché (ex. si vous tapez ‘a’ vous devriez voir ‘b’ à
l’écran…)
-
Validation Prof
4-
Exo2 - Emission et réception d’un caractère avec interruption
On reprend l’exercice précédent, mais cette fois en générant une interruption de bas niveau lors de
la réception du caractère.
• Ecrire le fichier « exo2.c » qui contiendra les fonctions « void InitUsart(void) »,
« void InitPort(void) » de l’exercice précédent.
• Ajouter une fonction « void InitInterrupt(void) » qui permet de configurer le µC pour qu’il
puisse déclencher une interruption de bas niveau lors de la réception des caractères : il
suffit donc de configurer les 3 bits généraux (GIE, IPEN et PEIE) et les 3 bits locaux au bloc
de réception de la liaison série asynchrone (RCIE, RCIP et RCIF).
• Modifier la fonction « void main(void) » pour prendre en compte cette nouvelle fonction
et supprimer dans la boucle infinie, les lignes correspondant à la réception et à la modificaFormation par Apprentissage
Département Geii, IUT de Marseille
Page 2 sur 6
•
tion de la valeur de la variable ucCarac (laisser uniquement les deux instructions pour
l’envoi).
Créer un fichier « Interrupt.c ». Ajouter les lignes nécessaires aux fonctions d’interruptions.
Celles-ci vont forcer le compilateur à mettre les instructions de la fonction d’interruption
prioritaire (priorité haute) et non prioritaire ailleurs qu’à l’adresse 0x08 et 018 de la
mémoire programme1 :
#pragma interrupt Interrupt_High
// L'interruption prioritaire correspond
// au label Interrupt_High de l'assembleur
#pragma interruptlow Interrupt_Low
// L'interruption Non prioritaire correspond
//au label Interrupt_Low de l'assembleur
#pragma code high_vector = 0x08
void interrupt_at_high_vector(void)
{
_asm
GOTO Interrupt_High
_endasm
}
// Place le code qui suit à l'adresse 0x08
// Fonction pour déclarer l'interruption prioritaire
#pragma code low_vector = 0x18
void interrupt_at_low_vector(void)
{
_asm
GOTO Interrupt_Low
_endasm
}
#pragma code
// Place le code qui suit à l'adresse 0x0018
// Fonction pour déclarer l'interruption non prioritaire
•
// Début d'écriture du code assembleur ΰ l'adresse 0x0008
// Aller à la fonction : Interrupt_High
// Fin d'écriture du code assembleur
// Début d'écriture du code assembleur à l'adresse 0x18
// Aller à la fonction : Interrupt_Low
// Fin d'écriture du code assembleur
// Libère le compilateur de l'obligation d'écrire
// à une adresse précise
Nous utiliserons dans cet exercice que la fonction d’interruption de niveau bas. Compléter
la fonction « void Interrupt_Low(void) » à partir de l’algorithme suivant :
ACTION Interrupt_Low
DEBUT
SI (Bit indicateur RCIF = 1) ALORS
(Est-ce que l’interruption est déclenchée par la
réception sur liaison série ?)
ucCarac
RCREG
ucCarac
ucCarac + 1
ATTENDRE TANTQUE (TXIF ≠ 1)
TXREG
ucCarac
RCIF = 0
(initialise RCIF à ‘0’ le bit indicateur2)
FIN SI
FIN Interrupt_High
1
Pour plus de détails, revoir le cours et TD/TP sur les interruptions.
La remise à zéro de RCIF est ici optionnel puisque fait automatiquement à la lecture du registre RCREG. Néanmoins
l’ajout de cette instruction permet de conserver une cohérence d’écriture où chaque bit indicateur (-IF) est remis à zéro à
la fin de la fonction d’interruption.
2
Formation par Apprentissage
Département Geii, IUT de Marseille
Page 3 sur 6
La fonction d’interruption effectue une modification sur la variable ucCarac, il est donc nécessaire
de déclarer de nouveau cette variable globale (type précédé du mot ‘extern’) dans le fichier « Interrupt.c » (voir complément au guide de développement).
•
Créer un fichier « Interrupt.h » pour y inclure les prototypes des deux fonctions
d’interruptions.
•
Compiler, programmer (mode « programmer ») et tester comme précédemment votre programme téléchargé dans le µC PIC18F.
Validation Prof
5-
Exo3 – Commande du robot à distance
Nous allons désormais contrôler le robot à distance à partir de certains caractères ASCII (lettres)
tapés directement dans la fenêtre « Terminal ». Ainsi, le robot doit effectuer certaines actions lors
de l’appui des touches suivantes :
‘f’ ou ‘F’
‘d’ ou ‘D’
‘g’ ou ‘G’
‘ ‘ (barre d’espace)
: le robot avance
: le robot tourne à droite
: le robot tourne à gauche
: le robot s’arrête
•
Ecrire le fichier « exo3.c » qui contiendra les fonctions « void InitUsart(void) »,
« void InitPort(void) » et « void InitInterrupt (void) » de l’exercice précédent (changer
simplement le nom du fichier exo2.c en exo3.c, et utiliser ce dernier fichier comme le fichier principal dans votre projet).
•
Copier et ajouter les fonctions « void InitTimer0(void) », « void InitTimer1(void) » et « void
InitTimer3(void) » de l’exercice 3 du TP précédent dans ce fichier.
•
N’oubliez pas d’ajouter également les prototypes de toutes les fonctions qui seront
utilisées en haut du fichier « exo3.c ».
•
Fusionner les deux fonctions « void InitPort(void) » des deux exercices (exercice précédent
et exercice 3 du TP précédent) pour que toutes les broches utilisées par les différents
périphériques (Timers, USART, E/S) soient correctement configurées.
•
Fusionner les deux fonctions « void InitInterrupt(void) » pour pouvoir déclencher des
interruptions de niveau haut depuis les 3 Timers (Timer0, Timer1 et Timer3) et de niveau
bas lors de la réception de l’USART.
•
Modifier également la fonction principale « void main(void) » pour que toutes ces
fonctions de configuration soient correctement appelées avant la boucle do…while(1).
Dans le fichier d’interruption « interrupt.c », copier et ajouter le contenu de la fonction
•
Formation par Apprentissage
Département Geii, IUT de Marseille
Page 4 sur 6
d’interruption de niveau haut du TP précédent « void Interrupt_High(void) ».
•
Sauvegarder bien ces premières modifications !
Dans le fichier d’interruption « interrupt.c », nous n’allons plus directement affecter des valeurs
aux registres TMR1H, TMR1L et TMR3H, TMR3L mais utiliser des variables. Nous pourrons ainsi
affecter des valeurs différentes suivant l’action demandée lors de la réception du caractère ASCII
via la liaison série asynchrone.
•
Déclarer 4 variables globales de type unsigned char que vous nommerez var_TMR1H,
var_TMR1L, var_TMR3H, var_TMR3L. Comme indiqué dans le document complémentaire
au guide de développement, ces variables devront également être déclarées dans le fichier
principal « exo3.c » (ajoutez ainsi les mots clés nécessaires pour qu’elles puissent être
correctement reconnues lors d’interruptions).
•
Modifier la fonction « void Interrupt_High(void) » pour que les registres TMR1H, TMR1L et
TMR3H, TMR3L soient affectés par les variables définies ci-dessus.
•
D’après le TP précédent (notamment exercice 3), quelles doivent être les valeurs à données
(en hexadécimales) à chacune des variables pour les 4 actions demandées3 :
Action : robot avance4
Action : robot tourne à droite5
var_TMR1H =
var_TMR1L =
var_TMR3H =
var_TMR3L =
var_TMR1H =
var_TMR1L =
var_TMR3H =
var_TMR3L =
Action : robot tourne à gauche
Action : robot à l’arrêt
var_TMR1H =
var_TMR1L =
var_TMR3H =
var_TMR3L =
•
var_TMR1H =
var_TMR1L =
var_TMR3H =
var_TMR3L =
La fonction « void Interrupt_Low(void) » doit correspondre à l’algorithme suivant :
ACTION Interrupt_Low
DEBUT
3
Rappel : si vous avez conservé le travail précédent, le Timer1 est utilisé pour générer une impulsion T1 (de valeur
1ms, 1,5ms ou 2 ms) sur le moteur droit (en mettant le devant du robot en face de vous) et correspondant à la broche
RB4. Sur le même principe, le Timer3 est utilisé pour générer une impulsion T3 (de valeur 1ms, 1,5ms ou 2 ms) sur le
moteur droit (en mettant le devant du robot en face de vous) et correspondant à la broche RB5.
4
Je rappelle que les moteurs sont inversés sur la structure…
5
Lorsque le robot tourne à droite (ou à gauche), une seule roue est activée, l’autre est à l’arrêt.
Formation par Apprentissage
Département Geii, IUT de Marseille
Page 5 sur 6
SI (Bit indicateur RCIF = 1) ALORS
ucCarac
RCREG
SELON (ucCarac)
‘f’ :
‘F’ : var_TMR1H = valeur hexadécimale déterminée précédemment
var_TMR1L = valeur hexadécimale déterminée précédemment
var_TMR3H = valeur hexadécimale déterminée précédemment
var_TMR3L = valeur hexadécimale déterminée précédemment
‘d’ :
‘D’ : var_TMR1H = valeur hexadécimale déterminée précédemment
var_TMR1L = valeur hexadécimale déterminée précédemment
var_TMR3H = valeur hexadécimale déterminée précédemment
var_TMR3L = valeur hexadécimale déterminée précédemment
‘g’ :
‘G’ : var_TMR1H = valeur hexadécimale déterminée précédemment
var_TMR1L = valeur hexadécimale déterminée précédemment
var_TMR3H = valeur hexadécimale déterminée précédemment
var_TMR3L = valeur hexadécimale déterminée précédemment
‘ ’ : var_TMR1H = valeur hexadécimale déterminée précédemment
var_TMR1L = valeur hexadécimale déterminée précédemment
var_TMR3H = valeur hexadécimale déterminée précédemment
var_TMR3L = valeur hexadécimale déterminée précédemment
FIN SELON
RCIF = 0
FIN SI
FIN Interrupt_High
•
Compiler, programmer (mode « programmer ») et tester comme précédemment votre programme téléchargé dans le µC PIC18F.
Validation Prof
•
Ajouter une action supplémentaire de recule du robot lorsque le caractère ASCII ‘a’ ou ‘A’
est reçu par la liaison série. Compiler, programmer (mode « programmer ») et tester
comme précédemment votre programme téléchargé dans le µC PIC18F.
Validation Prof
Formation par Apprentissage
Département Geii, IUT de Marseille
Page 6 sur 6