Communication série RS232 - Forge Clermont Université

Transcription

Communication série RS232 - Forge Clermont Université
DUT informatique, TP info embarquée n°3, année 2015
P. Kauffmann
MODULE INFORMATIQUE EMBARQUEE
Communication série
RS232
1. Présentation
De nombreux systèmes embarqués communiquent avec l’extérieur via une liaison filaire,
radio ou infrarouge. Beaucoup de ces interfaces de communication utilisent la liaison série
asynchrone RS232 pour se connecter au microcontrôleur.
Dans ce TP de 2 h, nous allons mettre en place une application embarquée qui génère un
signal périodique qu’elle communique via un port série RS232 directement au PC du poste de
travail qui fournira une IHM graphique déportée capable d'afficher sous forme de courbe
l’évolution temporelle du signal en fonction du temps.
2. Objectif(s) opérationnel(s)
•
Devenir capable d’écrire un pilote de périphérique RS232,
3. Organisation matérielle
Le TP sera réalisé par un groupe de deux étudiants. Le TP fera l'objet d’un rapport écrit
contenant les réponses aux questions et le code des fonctions demandées, rendu en fin de
séance sur papier.
4. Documentation et matériel nécessaire
Les documentations nécessaires pour la réalisation de ce TP sont :
•
•
•
•
polycopié de cours sur les microcontrôleurs,
notes de cours personnelles,
documentation électronique de la famille RX62,
les schémas de la plateforme cible.
Le matériel nécessaire pour la réalisation de ce TP est :
•
•
un ordinateur compatible PC avec la chaîne de développement RX62,
un système RX62N avec carte prototypage rapide.
5. Présentation des interfaces de communication
5.1. Rappels sur la liaison série RS232
La liaison série RS232 est un protocole de communication datant des années 1950 largement
utilisé durant toutes les périodes de l'informatique et qui reste essentiel de nos jours comme
interface pour les systèmes de communication plus évolués. Il a été conçu au départ pour
relier un ETTD (Elément Terminal de Traitement de Données), c'est à dire un ordinateur,
imprimante, console, etc. à un ETCD (Elément Terminal de Communication de Données),
c'est-à-dire un modem.
Nous allons utiliser cette liaison pour connecter notre système embarqué à base de RX62N ─
qui se comporte comme un ETCD ─ au PC du poste de travail ─ qui se comporte comme un
ETTD ─ et qui nous servira d’IHM.
Dans une liaison série asynchrone il faut choisir plusieurs paramètres et faire des choix
identiques pour les deux entités connectées ensembles. Les choix à faire sont :
• la vitesse de transmission en Bauds : 110,…, 9600, …, 115200, ou plus (sous
condition),
• la parité (paire, impaire ou sans),
• le nombre de bits de données par caractère (5 à 8),
• le nombre minimal de bits d’arrêt (1, 1,5 ou 2),
• le mode de contrôle de flux (hard, soft ou absent).
En ce qui nous concerne, nous allons communiquer sans contrôle de flux et sans parité, en 8
bits avec 1 bit d’arrêt au moins et à 115200 Bauds (vitesse maximale sur les PC).
6. Le SCI (Serial communication Interface) du RX62N en
mode asynchrone (RS232)
6.1. Principe général
Le RX62N dispose de six ports série nommés SCI pouvant fonctionner dans divers modes
synchrones et asynchrones. Nous allons utiliser le SCI6 qui dispose d’une prise DB9 en face
latérale gauche de la carte de prototypage.
N. B. : pour fonctionner correctement, il faut passer par un petit adaptateur DB9 qui permute
des broches car le brochage d’origine n’est pas standard.
Nous allons connecter la DB9 de la carte de prototypage sur l’adaptateur USB/série du PC via
un câble série. Cet adaptateur est relié par un pilote de périphérique au port série COM1 du
PC (connecteur 9 broches situé à l’arrière des machines de la salle de TP).
On peut distinguer plusieurs méthodes de gestion du port série :
• mode alternat, c’est-à-dire une direction après l’autre (impossibilité de recevoir
lorsqu’on émet),
• mode « full duplex », émission et réception simultané. Réception au moins sous
interruption.
La seconde méthode est plus performante, mais nécessite plus de code car la bibliothèque
RPDL ne fournit pas de code pour fonctionner en mode « full duplex ».
Pour exploiter le port série on va réaliser une classe sci minimaliste qui ne sait gérer qu’un
port série (le numéro 6) et offre un service minimal avec un seul constructeur sci(uint8_t
priority, uint32_t speed) qui initialise le port série et une seule méthode void
sciTrans(uint8_t * string) qui met dans le registre d’émission du port série le
premier caractère de la chaîne de caractères à émettre avec l’instruction SCI6.TDR =
m_sciTX6message[0]; .
Pour exploiter le port série en « full duplex » sous interruption il faut aussi deux fonctions
sciSend() et sciReceive() qui ne peuvent pas être des méthodes car ce sont des
fonctions d’interruption. Leur code est présenté sous cette forme aux paragraphes 6.3 et 6.4.
Toutefois, il est parfaitement possible d’utiliser des méthodes de même nom ; les fonctions
d’interruption se contentant alors d’appeler ces méthodes. Cette manière de faire très générale
doit être privilégiée.
Elles ont besoin d’avoir accès aux attributs publics suivants de la classe :
// for reception
volatile uint8_t m_sciRXmessage[128];
volatile bool m_sciRXfree;
// for transmission
volatile uint8_t m_sciTXmessage[64];
volatile bool m_sciTXfree;
sciSend() émet sous interruption tous les caractères excepté le premier ; les caractères
étant prélevés dans le tampon d’émission m_sciTXmessage[].sciReceive() reçoit tous
les caractères sous interruption, les place dans le tampon m_sciRXmessage[] et désactive
le fanion m_sciTXfree pour indiquer la fin de l’opération.
6.2. Initialisation
Pour initialiser la liaison série de SCI6 dans le microcontrôleur on pourra utiliser le canevas
ci-après en ajoutant les valeurs numériques manquantes.
sci::sci(uint8_t priority, uint32_t speed) {
/* Declare error flag */
bool err = true;
/* select A pins for SCI 6 */
err &= R_SCI_Set(xx);
/* Configure SCI6 in asynchronous, 8N1 mode */
err &= R_SCI_Create(xx);
// define priority of SCI6 interrupts
IPR(SCI6,
) = priority;
// activate transmission interrupt
IEN(SCI6,TXI6) = xx;
// activate reception interrupt
IEN(SCI6,RXI6) = xx;
// enable full duplex communication under interrupt
SCI6.SCR.BYTE |= 0xF0;
// SCI6 is free at this time
m_sciRXfree = m_sciTXfree = xx;
/* Halt in while loop when RPDL errors detected */
while(!err);
}
6.3. Fonctions d’émission
La méthode d’émission du premier caractère placée dans le fichier de classe sci.cpp aura
un code semblable à celui donné ci-après :
void sci::sciTrans(uint8_t * string)
{
// string memorization
strcpy((char *)m_sciTXmessage, (char *)string);
// say SCI occupied
m_sciTXfree = false;
// transmit first character
SCI6.TDR = m_sciTXmessage[0];
}
La fonction d’interruption, placée également dans le fichier de classe sci.cpp gérant
l’émission du second au dernier caractère, dont le canevas à compléter est donné ci-après,
assurera l’émission sans gestion de flux. Elle utilise l’objet sci6 de la classe sci instancié
statiquement.
void sciSend(void)
{
static uint8_t messByte = xx;
characters
// number of transmitted
if(messByte>62) messByte = xx;
// avoid overflow
if (sci6.m_sciTXmessage[messByte] == xx)
// last character ?
{
messByte = xx;
sci6.m_sciTXfree = true;
}
else
{
SCI6.TDR = sci6.m_sciTXmessage[messByte++];
}
}
N. B. : la variable messByte compte les caractères et le fanion sci6.m_sciTX6free
permet de déterminer si le port série est libre ou occupé (occupé à false).
6.4. Fonction de réception
La fonction d’interruption, placée dans le fichier de classe sci.cpp gérant la réception, dont
le canevas à compléter est donné ci-après, assurera la réception sans gestion de flux. Cette
fonction inutilisée dans l’immédiat sera indispensable pour les TP suivants lorsque la
communication deviendra bidirectionnelle.
void sciReceive(void)
{
static uint8_t messByte = xx;
if(messByte>126) messByte = xx;
// avoid overflow
sci6.m_sciRXmessage[messByte++] = SCI6.RDR;
if (sci6.m_sciRXmessage[messByte - 1] == '\n')
transmission
{
sci6.m_sciRXmessage[messByte-2] = '\0';
string
messByte = xx;
sci6.m_sciRXfree = false;
data
}
}
// receive
// end of
// add end of
// presence of new
N. B. : la variable messByte compte les caractères et le fanion sci6.m_sciRXfree
permet de déterminer si le port série est libre ou occupé (occupé à false).
6.5. Gestion des exceptions
La communication série est susceptible de générer des exceptions. Ces exceptions
déclenchent des interruptions. Ceci nous oblige à rajouter dans le code de gestion du port série
les deux fonctions d’interruption ci-après :
void sciSendEnd()
{
sci6.m_sciTXfree = true;
// inhibit end of transmission interrupt
SCI6.SCR.BIT.TEIE = 0;
}
void sciReceiveError()
{
// clear parity error
SCI6.SSR.BIT.PER = 0;
// clear framing error
SCI6.SSR.BIT.FER = 0;
// clear overrun error
SCI6.SSR.BIT.ORER = 0;
}
7. Gestion du port série coté PC
Une application adaptée est nécessaire pour visualiser sous forme de courbe les données
envoyées au PC via la liaison série. On pourra utilisera l’émulateur de terminal Teraterm
placé sur toutes les machines de la salle de TP pour vérifier sous forme de texte le bon
fonctionnement des données transmises. Cet émulateur devra toutefois être d’abord configuré
pour fonctionner correctement :
• Connexion série port COM1,
• Setup -> serial port -> Baud rate 115200, Data 8 bit, Parity none, Stop 1 bit, Flow
control none.
• Setup -> terminal -> Receive CR, Transmit CR+LF.
8. Manipulations
8.1. Dispositif embarqué communiquant
On se propose d’utiliser le lien RS232 de la maquette vers le PC pour afficher la courbe d’une
grandeur mesurée par le RX62N. Comme, pour le moment, on n’a pas de capteur installé sur
le système embarqué, on simule le signal de mesure par un signal qui évolue temporellement
périodiquement en dent de scie, signal généré par une méthode ajoutée à la classe tps
nommée void tps::dentScie(). La méthode tps::dentScie()incrémente l’attribut
m_dent (valeur initiale nulle) de 10 unités à chaque appel, et remet sa valeur à 0 à chaque
fois qu’elle atteint 400. Elle est exécutée 5 fois par seconde et l’attribut m_dent est transmis
sur le port série pour générer le signal désiré à la même fréquence.
L’application embarquée sur le RX62N aura les caractéristiques suivantes :
•
•
•
La communication par le port série se fera en mode asynchrone à la vitesse de 115200
Bauds, 8 bits, sans contrôle de flux.
La mesure obtenue par une méthode « get » sera transmise 5 fois par seconde en
même temps qu’elle sera affichée sur l’afficheur LCD embarqué (affichage lorsqu’on
se trouve à la gestion de la ligne 5 de l’afficheur et émission sans affichage lorsqu’on
se trouve à la gestion de la ligne 6 de l’afficheur).
Chaque mesure émise sur le port série se présentera sous la forme d'une chaîne de
caractères ASCII représentant un entier, terminé par un saut de ligne et respectant la
forme suivante : 50\r\n.
Réalisez le travail suivant :
•
•
•
•
Partez su squelette fourni « TP3serie ». Complétez les fichiers sci.h et sci.cpp de
façon à obtenir une classe sci complète.
Ajoutez dans l’application « TP3serie » l’ instanciation statique en sci6 de la classe sci
(priorité 2 et vitesse par défaut 115200 Bauds). Ajoutez dans le code d’affichage à la sixième
ligne le code de transmission de l’attribut « m_dent ». Testez le fonctionnement avec
l’émulateur de terminal TeraTerm et éventuellement le script tcl fourni.
Montrez le fonctionnement de votre application à l'enseignant d'encadrement.
Si vous avez le temps, ajoutez à la septième ligne le message fixe « RECEPTION » et sur la
suivante l’affichage des chaînes de caractères émanant du port série.