Cours Modulation Num 2011 2012 v4
Cours Modulation Num 2011 2012 v4
SUPERIEUR ET DE LA RECHERCHE
Année Universitaire
2011 - 2012
SUPPORT DE
COURS Modulation, Démodulation
numérique
Introduction
Afin d'atteindre ces objectifs, deux documents supports sont à votre disposition. Le premier,
« Modulateurs et démodulateurs », donne une vue d'ensemble des principales modulations et de
leurs mise en oeuvre par des techniques analogiques. Le second, « Modulation et démodulation
numérique », le présent document, porte plus spécifiquement sur le micro-contrôleur et ses
applications en télécommunication. On s'intéressera notamment à la démodulation IQ.
Sommaire :
Sommaire
Chapitre 1 : La programmation sur microcontrôleur................................................4
1. Introduction..................................................................................................................................5
2. Les périphériques principaux.......................................................................................................5
2.1. Les ports d'entrée / sortie (GPIO General Purpose Input Output) .......................................7
2.2. Le Timer.............................................................................................................................10
2.3. L'ADC (Analog To Digital Converter) .............................................................................12
2.4. Le DAC (Digital to Analog Converter)..............................................................................15
2.5. Le système d'interruptions..................................................................................................15
3. Structure logicielle en couches..................................................................................................18
4. Structure logicielle pour un traitement en temps réel ...............................................................19
4.1. Conception en séquences...................................................................................................19
4.2. Les échanges d'information entre tâches............................................................................20
Chapitre 2 : La démodulation IQ sur microcontrôleur...........................................23
1. Principe de modulation & démodulation MAQ analogique......................................................24
1.1. Génération analogique d'un signal MAQ...........................................................................24
1.2. Démodulation IQ analogique.............................................................................................25
2. Démodulation directe par échantillonnage à la fréquence porteuse...........................................28
2.1. Introduction........................................................................................................................28
2.2. Echantillonnage et modulation AM...................................................................................29
2.3. Echantillonnage en quadrature...........................................................................................33
3. Démodulation directe par sous-échantillonnage .......................................................................35
3.1. Présentation........................................................................................................................35
3.2. Sous échantillonnage de la partie en quadrature................................................................35
Annexe........................................................................................................................37
1. Représentation analytique des signaux réels..............................................................................37
2. Transformée de Hilbert .............................................................................................................37
3. Transformée de Fourier d'un signal analytique .........................................................................38
4. Enveloppe complexe : signal à bande étroite.............................................................................39
5. Résumé signaux réels / signaux analytiques..............................................................................41
1. Introduction
Un microcontrôleur est un élément doté d'une CPU (Central Processing Unit) qui lui permet
d'exécuter un programme. Son véritable intérêt par rapport à un micro ordinateur, PC par exemple,
est qu'il prend place dans des applications embarquées. Par ailleurs, comme son nom l'indique, il
est destiné à contrôler des processus. Ceci implique la présence dans le microcontrôleur d'élements
d'échange avec l'extérieur (entrée / sortie) appelé périphérique.
Un périphérique est une structure électronique autorisant des échanges entre l'extérieurs du
microcontrôleur et la CPU. Parfois, les périphériques sont même capables de communiquer entre
eux, sans faire intervenir la CPU (DMA, déclenchement automatique d'un ADC par un Timer...).
Un périphérique se configure avant son utilisation proprement dite. Ainsi, sa structure électronique
contient des registres adressables par la CPU. On peut faire la distinction suivante sur les registres
d'un périphérique :
– Les registres de configuration : Ce sont ceux qui vont être initialisés, configurés, au
démarrage et généralement une seule fois, de manière à faire travailler le périphérique d'une
certaine manière. Par exemple, une broche d'un microcontrôleur sera configurée en sortie et
en mode « push-pull ».
– Les registres d'utilisation : Ce sont les registres qui sont utilisés au cours de l'application.
Par exemple, la broche configurée au départ en sortie, doit produire une alternance de '1' et
de '0' au cours de l'application : un registre d'utilisation sera utilisé pour cela.
– Les ports d'entrée/sortie (GPIO) : C'est par ces broches que transitent toutes les
communications avec l'extérieur, sous la forme de tension ('1' = 3.3V environ, '0' = 0V
environ).
– Les Timers : Ce sont des compteurs électroniques qui permettent de construire des bases de
temps (application temps réel) ou de compter des impulsions extérieures.
– Les ADC / DAC : Ce sont les interfaces qui rendent possible la manipulation de tensions
analogiques ( au lieu de traiter simplement 2 niveaux, '0' et '1', les ADC et DAC travaillent
typiquement sur 256, 1024, ...16 millions de niveaux de tension)
– Gestionnaire d'interruption : Il permet de définir par exemple, quels sont les périphériques
susceptibles de générer une interruption, de départager plusieurs demandes d'interruptions
simultannées...
Batterie Source
énergie
STM32
Système de
Timer en
Codeur mode
bus
Timer en Moteur
incrémental incrémental C.C
PWM
girouette Rotation
plateau
Timer en Servo-moteur
Accéléromètre ADC
PWM
Mesure de Bordage
gîte GPIO
GPIO
voile
USART Emetteur HF
Timer en
Récepteur HF mode capture
Messages
Télécommand d'urgence
Coeur
e de direction
Couche applicative
Logiciel en C : Couche service
Couche périphérique
On distingue en périphérie les GPIO. Plus à l'intérieur du contrôleur, on trouve les périphériques
cités précédemment (sauf le DAC). On peut constater que le périphérique Timer est décliné dans de
multiples contextes d'utilisation (PWM, Capture d'impulsions, Codeur incrémental). On voit aussi
un circuit appelé USART (Universal Synchronuous, Asynchronuous Receiver Transmetter). Tous
sont reliés au CPU (coeur).
Enfin, nous y reviendrons plus tard, on laisse entrevoir une logique dans la structure de
programmation : les logiciels seront systématiquement structurés en 3 couches : la couche
applicative, la couche service, la couche périphérique.
2.1. Les ports d'entrée / sortie (GPIO General Purpose Input Output)
Un port d'entrée/sortie communique avec l'extérieur du micro-contrôleur par le biais de
plusieurs fils (broches), en général regroupés par paquets de 8 ou 16. Il communique avec le
processeur par sa seule et unique possibilité : les bus d'adresses et de données. Ceci est commun à
TOUS les périphériques du micro-contrôleur.
Un port d'entrée / sortie a donc pour rôle d'imposer (Output) ou de lire (Input) un niveau de
tension (associé aux niveaux logique '0' ou '1' ) sur l'ensemble de ses broches. Selon le
microcontrôleur, le niveau logique '1' peut être 5V, 3V3 ou encore 1V8. Pour ce qui nous concerne,
les IO sont sensibles à 0/3,3V.
Le port d'E/S possède donc au minimum deux registres de configuration (l'un qui spécifie
pour chaque broche sa direction, l'autre spécifiant la technologie utilisée) et un registre d'utilisation
qui est à l'image logique des broches.
2.1.1. IO en sortie
Gnd = 0V
Gnd = 0V
Le Bus I2C est un bus qui permet de mettre en communication plusieurs circuits numériques
(micro-contrôleur, EEPROM, …). Deux fils sont utilisés SCL (horloge), SDA (donnée) sans oublier
la masse. Il s'agit donc d'un bus série synchrone.
Nous voyons ici un seul circuit connecté au bus (intérieur des pointillés), il faut imaginer que
n circuits sont susceptibles d'y être reliés de la même manière. Chaque circuit est composé de deux
structures de lecture / écriture. En clair, chaque circuit peut prendre la main sur les lignes SCL et
SDA (lecture ou écriture). Plusieurs circuits sont donc susceptibles d'émettre en même temps, c'est à
dire de chercher à écrire sur la ligne SDA par exemple en même temps. Un conflit a donc lieu aux
conséquences potentiellement néfastes sur le plan matériel (destruction) et logiciel (brouillage des
messages) . Dans ce dernier cas, un arbitrage de bus permet de régler le problème.
Sur le plan matériel, il n'y a en réalité aucun problème non plus. En effet, les transistors
(jaune) sont assimilables à des interrupteurs. On reconnaît donc une structure Open Drain. Ainsi,
chaque circuit peut imposer un '0' logique, mais jamais un '1'. C'est le circuit extérieur (la résistance
de tirage) qui remplit ce rôle.
Si deux circuits imposent en même temps un '0', ou un '1', il n'y a pas de conflit, et ce,
quelque soit la technologie utilisée.
Si par contre, un circuit impose un '0' et l'autre un '1', c'est celui qui impose le '0' qui
« l'emporte » car le transistor, en position fermée, est équivalent à une résistance quasi nulle. Le
circuit qui proposait '1' (équivalent, lui à Vcc avec une résistance série grande) n'est donc pas
compris, mais il ne subit strictement aucun dégât. Si la technologie avait été push-pull, alors danc ce
cas, un court-circuit se serait produit avec pour conséquence un courant trop fort débité par le
circuit qui proposait '1' (ainsi qu'à celui qui proposait '0', c'est le plus fragile qui fait
fusible...définitif).
Résumons :
En mode Push-Pull, c'est le port d'E/S qui impose le niveau logique d'une broche, que ce
soit un niveau '1' ou '0'. Il est le maître, le circuit extérieur est l'esclave, récepteur.
En mode Open Drain ( = Drain laissé ouvert, Drain est le nom de la broche du transistor MOS
reliée à la broche ), le port d'E/S ne peut imposer que le niveau logique '0'. Le niveau '1' est fixé
par le circuit extérieur. Le port d'E/S n'est donc pas le seul maître du potentiel sur la broche. Le
circuit extérieur l'est aussi.
2.1.2. IO en entrée
2.2. Le Timer
Le coeur d'un Timer est un compteur électronique. Celui-ci peut avoir une résolution de 8
bits (0 à 255), 16 bits (0 à 65 535) ou encore 32 bits (0 à 4 294 967 295 ! ).
Ce Timer possède donc bien évidemment une horloge. Selon la nature de l'horloge, on
parlera d'un fonctionnement en Timer (l'horloge est dérivée d'un quartz de référence, fixe) ou d'un
fonctionnement en compteur (l'horloge est dérivée d'une broche du microcontrôleur). L'entrée
d'horloge est très souvent précédée d'un Prescaler. Son rôle est d'opérer une première division de la
fréquence de l'horloge avant d'attaquer concrètement l'horloge du compteur (voir schéma).
Enfin, précisions que le compteur est très souvent associé à un registre dit Autoreload. Celui-ci
contient la valeur de redémarrage du compteur après un débordement (haut ou bas).
up/down on/off
quartz 16 bits (par
exemple)
Autoreload
Timer
horloge
compteur
t
Retard volontairement
Valeur exagéré (le front est la
compteur cause du changement) Tck Evènement
(Demande d'IT)
2 1 0 4 3 2 1 0 4 3 2 1 0
t
Ordre de Rechargement synchrone :
chargement l'ordre vaut '1' ET il y a un T
front montant
Retard volontairement
exagéré (la valeur 0 est la
cause de l'impulsion)
Sur cet exemple, la durée T est la période d'évolution de la séquence du Timer. Elle vaut 5 T ck. Tck
étant la période d'horloge.
Ainsi, en généralisant, si l'on souhaite une période pour la séquence du Timer de n.Tck, on
placera dans le registre Tck la valeur n-1.
La génération de l'évènement (demande d'interruption par exemple, mais pas forcément) se traduit
physiquement par une impulsion qui a lieu à l'underflow (décomptage) ou overflow (comptage).
L'underflow est le passage de 0 à la valeur suivante (0xFFFF si l'autorelaod n'est pas configuré,
valeur de l'autorelaod dans le cas contraire).
Exemple :
On dispose d'une horloge de 40MHz en entrée d'un Timer 16 bits (H_ref). Le Prescaler est sur 16
bits. On veut génerer une impulsion périodique de 0,5s.
Quelle valeur donner au Prescaler, ainsi qu'à l'auto-reload pour parvenir à cela, sachant que l'on veut
une fréquence la plus grande possible sur le compteur (cela revient à dire une valeur d'autoreload
maximale).
Solution :
La valeur maximale d'autorelaod est de 216 = 65536. La période correspondante en entrée de comptage est donc 0,5s / 65536 = 7,629µs.
A partie d'une fréquence de 40MHz, le Presceler doit donc donner une fréquence de 1/7,629 µs = 131 072 Hz.
Le Prescaler vaudra donc P = 40MHz / 131 072 Hz =305,17.
Il faut arrondir à l'entier supérieur. En effet, dans le sens inverse (arrondi inférieur) la fréquence en entrée de comptage serait trop forte => Autorelaod saturé.
Prenons donc P=306 => Freq_Cpt = H_ref / P.
La valeur de l'autoreload est telle que : Auto_Rel*T_Cpt = 0,5s => Auto_Rel/ Freq_Cpt = 0,5s soit Auto_Rel = 0,5* Freq_Cpt = 0,5 * H_ref / P
AN: Auto_Rel = 0,5*40M/306 = 65359,477, arrondi à 65359, ce qui donne une période exacte de 499,99635 ms, à la précision du quartz près !
Finalement, pour le réglage on placera 306 -1 = 305 dans le prescaler et 65359-1 = 65358 dans l'Autorelaod, eu égard aux comptage synchrone expliqué ci-dessus
Un ADC a pour rôle de fournir un nombre entier à l'image d'une tension. Une tension possède par
définition une infinité de valeurs possibles (grandeur analogique), alors que le nombre entier fourni,
lui, est forcément limité en quantité de valeurs.
Le quantum d'un ADC est l'incrément de tension q, qui fait évoluer le nombre entier d'une valeur
à la suivante.
L'étendue de mesure est la plage d'entrée de l'ADC, noté ∆V sur la caractéristique.
La résolution d'un ADC renseigne plus ou moins directement sur la quantité de valeurs entières
que peut prendre le nombre de sortie de l'ADC. Les données suivantes, bien que différentes,
renseignent sur la résolution :
– ADC 1024 points 3 manières de
– ADC 10 bits donner la
– ADC dont l'étendue de mesure est 5V et le quantum vaut 4,883mV résolution d'un
même ADC
La précision d'un ADC dénote l'aptitude de l'ADC à être fidèle. Autrement dit, elle renseigne sur
l'alignement de la caractéristique réelle avec la caractéristique théorique en forme d'escalier (dont
les quantums sont parfaitement réguliers).
Résolution et précision sont parfois confondues. Un dernier exemple qui permet de bien faire la
différence, est celui d'un voltmètre. En effet, un voltmètre ayant une résolution de 2000pts, est un
appareil dont l'afficheur LCD possédant les 4 digits, mais ne pouvant indiquer que des valeurs de 0
à 1999 (la virgule se déplaçant au gré des calibres).
La précision, indique le degré d'exactitude de la valeur annoncée. Si par exemple on mesure 10.05V
avec le voltmètre, alors que la tension réelle vaut 10,09V, la précision sera donc de
0,04/10,09=0,4%. Dans cet exemple, l'ADC est d'une précision insuffisante vis à vis de la
résolution. Habituellement, un système de mesure discret (l'ADC en est un) possède une précision
cohérente vis à vis de la résolution. C'est à verifier en toute rigueur.
on/off
16 bits (par
exemple)
Fréquence Registre de Data bus
ADC prescaler ADC résultat
Plusieurs mode de fonctionnement existent, on peut citer (la liste n'est pas exhaustive) :
– le mode single conversion : l'utilisateur lance une conversion et récupère le résultat dans le
registre associé, soit en scrutant le drapeau EOC, soit en attendant l'entrée en interruption.
– Le mode auto conversion : l'utilisateur lance une conversion, et dès que l'ADC finit sa
conversion, il en lance une autre, eventuellement sur un autre canal, et ce de manière
cyclique. Les résultats sont donc à lire régulièrement, sinon ils sont perdus. Selon le
microcontrôleur les résultats peuvent être stockés dans une table de registres internes au
périphérique, ou directement dans une table en RAM. On parle alors de DMA (Direct
Memory Access).
Période d'échantillonnage,
Te
Temps de conversion, tconv : Dès lors que l'échantillonneur est ouvert, la tension e(t) reste
constante, et la conversion peut commencer. Elle dure un temps lié à l'horloge d'entrée de
l'ADC et à la technologie de l'ADC.
Ces deux grandeurs temporelles, tech et tconv, sont habituellement paramétrables via un registre de
configuration de l'ADC.
Temps de conversion total : Ce terme, non générique, traduit simplement le temps nécessaire à une
conversion totale, depuis la demande de conversion, jusqu'à l'écriture du résultat dans le registre
associé.
1
F e Max=
t ech t conv
Il est le réciproque de l'ADC. Il possède un temps de réponse très rapide. En effet, le procéssus de
conversion est très souvent basé sur une échelle de résistances de type réseau R-2R. Chacun des N
bits sont appliqués, sous la forme de tension (3,3V ou 0V) en parallèle sur le circuit. Le temps de
réponse est donc négligeable.
Ce périphérique est à priori très simple : après une configuration minimale (nombre de bits,
activation), il suffit d'écire la valeur numérique représentative de la valeur analogique souhaitée
(voir ADC), pour observer la tension effective sur la broche du GPIO correspondante.
NB: Tout comme pour l'ADC, le DAC peut être directement associé à la RAM du microcontrôleur,
via un circuit de DMA. La configuration se complique alors, et chaque constructeur possède sa
propre spécificité. A voir au cas par cas.
En principe, un périphérique donné possède un fil de sortie que l'on peut appeler Interrupt Flag, ou
encore Interrupt Request. Le périphérique est relié au coeur, via un gestionnaire d'interruptions. Ce
dernier est capable d'interrompre le coeur et de lui fournir une adresse où est situé le programme
d'interruption à traiter (le Handler). Cette adresse est connue sous le nom de vecteur d'interruption.
Finalement, si chaque périphérique possède son propre vecteur d'interruption, alors il est très simple
de dérouter le coeur de son activité pour l'aiguiller directement sur le programme correspondant.
Parfois, pour des raisons de simplicité de fabrication, plusieurs périphériques, possèdent le même
vecteur d'interruption. Dans ce cas, le programmeur doit prévoir un test sur les Interrupt Flag, afin
de savoir qui est à l'origine de l'interruption et donc de lancer le traitement approprié.
Périph 1 IR 1
Contrôleur IR
IR 2 d'interruption
Périph 2 Coeur
Bus
d'adresses,
IR n de données
Périph n
Évènement,
Handler demande
d'interruption
Periph1
Fin de Pgm
traitement de principal
la routine
d'IT
Précisons que le contrôleur d'interruptions permet aussi de gérer les priorités d'interruptions (dans le
cas où plusieurs sont demandées en même temps). Enfin, pour qu'un périphérique puisse émettre
une interruption il faut d'une part que la condition de réalisation soit rencontrée (débordement d'un
timer par exemple), mais il faut aussi que la demande soit autorisée. Très souvent, au sein d'un
périphérique, on trouve un bit qu'on peut appeler IT_Periph_IE, où IE signifie Interrupt Enable.
Signalons enfin, que dans de nombreux cas, un bit de commande global, GIE (Global Interrupt
Enable), appartenant au coeur permet de bloquer ou pas l'ensemble des interruptions validées
localement dans chaque périphérique.
Pour des raisons de qualité et de portabilité, on demande de construire le logiciel en trois couches :
La couche application : Cette couche ne comporte que du code dédié à une application. Elle
comporte l’ensemble des fonctions de traitement et d’orchestration de l’application.
La couche de services applicatifs : Cette couche est un ensemble de fonctions qui masquent les
périphériques matériels au niveau de l’application pour en offrir une représentation abstraite.
Par exemple, le service d’acquisition d’une vitesse masque l’appel au périphérique ADC pour offrir
une vision purement abstraite de la variable de vitesse.
La couche de pilotes : Cette couche ne comporte que du code lié à la configuration et l’utilisation
des périphériques sans présupposer une utilisation particulière par une application.
Une telle architecture offre de nombreux avantages :
– Seules les couches « services applicatifs »et « pilotes » doivent changer si le matériel évolue,
la couche application n’ayant a priori besoin que de quelques modifications pour prendre en
considération les nouvelles capacités du support d’exécution (surtout en ce qui concerne le
temps).
– Les modules qui composent la couche pilotes peuvent être utilisés pour différentes
applications et ainsi offrir des composants pris sur étagères.
– La couche services applicatifs fournit des services génériques pour un même ensemble de
familles d’applications sans avoir besoin d’être réécrit à chaque développement ou évolution
d’une application sur le même support.
– Le test des modules est fait de manière unitaire, ce qui facilite le débogage sans avoir besoin
de chercher la petite bête.
Les éléments qui composent une couche ne peuvent communiquer qu’avec un élément d’une couche
inférieure et cela se fait uniquement à travers les API des différents modules.
Pour plus d'informations, lire le document « poly_periph.pdf » disponible sur le site WIKI.
Afin d'écrire proprement un programme temps réel, on vous propose une démarche rigoureuse. Elle
repose sur la décomposition de l'exécution en tâches successives, dont une et une seule peut être
active à la fois. Par ailleurs, chacune des tâches entamée devra être achevée avant de passer à la
suivante. Il ne s'agit donc pas de « multi-tâche », mais de tâches qui s'enchaînent les unes après les
autres.
Ensuite, on établit une planification des tâches. On commence donc par repérer la périodicité des
occurrences de tâches. On notera cette périodicité Periode = N*T_ref. La variable Index_Tache
servira de repérage des tâches.
Il ne reste plus qu'à définir l'ensemble des tâches à exécuter, et à définir l'instant de démarrage.
NB: Chaque tâche doit avoir une durée inférieure à T_Ref de manière à être sûr qu'elle soit achevée
avant le lancement de la prochaine.
Exemple :
une période
Tâche n°0
Tâche n°1
Tâche n°2
Tâche n°3
Tâche n°4
Voici ce que peut donner, en langage C, une telle gestion de type « tourniquet »:
void IT_Timer(void)
{
// Tourniquer sur Index_Tache :
Index_Tache++;
if ( Index_Tache==N) Index_Tache=0; // dans l'exemple, la constante N vaut 8
if ( Index_Tache%8)== 0) // Si Index_Tache = 0 modulo 8
{
Tache_0(); // lancement de la tâche 0
}
else if ( (Index_Tache%8 == 1)||(Index_Tache%8 == 4)||(Index_Tache%8 == 5))
{
Tache_1();
}
else if ( (Index_Tache%8 == 2)||(Index_Tache%8 == 7))
{
Tache_2();
}
else if (Index_Tache%4 == 3)
{
Tache_3();
}
else if (Index_Tache%4 == 6)
{
Tache_4();
}
}
La variable Index_Tache doit être globale. En effet, elle doit pouvoir être initialisée, donc vue, par
le programme d'initialisation qui lance le tourniquet. Ce programme doit initialiser le timer en
débordement sur T_Ref. Le programme IT_Timer qui gère le tourniquet, est le programme
d'interruption lancé sur le débordement du timer.
Au cours du déroulement du programme, les tâches seront amenées à échanger des informations. On
distingues ces dernières en deux types :
– les informations « Mémoire partagée» : elles contiennent des valeurs comme par exemple le
résultat d'une conversion, le résultat d'un calcul...
– les informations de type « drapeau » : Elles permettent d'influencer le déroulement d'une
tâche. Elle servent d'indicateur binaire pour opérer un choix conditionnel.
Ces deux types d'informations sont des variables visibles par les tâches concernées, donc globale et
permanentes en mémoire (pas dynamique).
Les tâches, selon qu'elles sont à l'origine de telle ou telle information, ou qu'elles exploitent ces
informations sont classées en deux catégories (du point de vue d'une information d'échange):
– Emetteur : la tâche affecte, écrit la variable
– Recepteur : la tâche exploite, donc lit la variable.
Afin de se faire une idée des échanges qui peuvent avoir lieu entre les diverses tâches, on propose
de procéder de la manière suivante :
Var_1 : drapeau
Tâche 4
Cette illustration, montre l'ensemble des drapeaux et variables de type mémoire partagée, qui sont
utilisés pour la tâche x. Elle indique aussi, pour chaque variable ou drapeau, si la tâche est de type
émettrice ou réceptrice. C'est le sens des flèches qui renseigne.
Index_ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
Tache
...
Var_1 Flag
Var_2 Mem
partagée
Var_3 Mem
partagée
Var_4 Mem
partagée
Lecture du tableau :
Le drapeau (flag) Var_1 est généré par la tâche n°0 puis exploitée pour une décision dans la tâche
n°4.
La tâche n°4 mets à jour une variable de type mémoire partagée, var_3, pour sa prochaine
exécution.
….
La fonction main est utilisée pour le lancement de toutes les initialisations, pour la préparation du
tourniquet...
Lorsque ces diverses configurations sont exécutées, alors peut commencer le balai des tâches. Entre
deux tâches successives, il subsiste toujours un temps mort. En effet, rappelons que dans le cadre de
ce cours, chacune des tâches doit se loger dans le créneau de durée T_ref. Le temps mort correspond
au retour d'interruption vers la fonction main.
On peut donc considérer que la fonction main est une tâche de fond non prioritaire. Sa durée
d'exécution sur une période complète est difficile à calculer et surtout peut fluctuer, selon les
exécutions conditionnées (par des sémaphores) de certaines tâches. Néanmoins, son avantage est
que c'est la seule tâche qui peut s'étaler au delà d'une période T_Ref. Elle sera par exemple utilisée
pour un calcul de fond, plus ou moins complexe et non critique en terme de vitesse d'éxecution.
L'idée est donc d'utiliser le formalisme des signaux analytiques, et de l'enveloppe complexe. (voir
annexe pour plus de détail) :
Au signal réel x(t), on associe son signal analytique, le complexe zx(t). De plus, x(t) étant un signal à
bande étroite, on écrit directement :
j. t j.2. . f 0 .t j.2. . f 0 .t
z x t=a t. e .e = x t .e sous condition que a(t)>0
La représentation par signal analytique, permet de sortir la phase du cosinus et rend alors possible la
réprésentation spectrale.
Le complexe x t est l'enveloppe complexe de x(t). Ecrivons la, en faisant apparaître les parties
réelles et imaginaires :
x t= p t j.qt
puisque, par définition, le signal réel est la partie réelle de son signal analytique.
Ainsi, le signal réel x t =a t .cos 2.. f 0 .tt est strictement équivalent à
Il s'agit d'une double modulation AM en quadrature, simple à réaliser (d'où le nom de MAQ).
NB : sans passer par toute la théorie de l'enveloppe complexe, on peut directement montrer
l'équivalence des deux expressions, le plus simple étant de partir de l'expression MAQ.
p(t)
cos(2.π.f0.t) X +
-π/2 x(t)
-
q(t)
X
Le principe de la démodulation IQ
x(t)
cos(2.π.f0.t) X p'(t)
+π/2
-sin(2.π.f0.t)
X q'(t)
Analysons ici le cas d'un récepteur dont l'oscillateur local est décalé en fréquence et en phase
Afin d'alléger les notations, nous allons raisonner en pulsation. On considère qu'en réception on
dispose d'un cosinus légèrement décalé en fréquence par rapport à la porteuse : cos 0 ' .t
ω0' = ω0 - ∆ω. La référence au récepteur s'écrit cos 0− . t .
Nous nous intéresserons par la suite uniquement au terme “différence” issu de chacun des produits,
sachant que la composante “somme” est filtrée. Donc volontairement, dans le calcul des produits, le
terme somme n'apparaît pas.
1 t=[ pt . cos 0 . t−q t .sin 0 . t]. cos 0−. t
1 t=[ pt . cos 0 . t−q t .cos 0 . t− ] . cos 0− .t
2
1 1
p ' t= . pt . cos . t−− . qt . cos .t−−
2 2 2
1 1
p ' t = . pt . cos . t −− . qt . sin . t−
2 2
1 1
p ' t= . a t . cos . cos .t−− . a t. sin . sin . t−
2 2
finalement :
1
p ' t= . a t . cos . t−
2
1
q ' t= . a t .sin . t−
2
Après ces développements, on se rend compte que l'enveloppe complexe obtenue possède un
argument faussé, qui “glisse” à la vitesse qui est l'écart de fréquence de démodulation.
Le diagramme de constellation s'obtient dans le plan complexe (représentation de I et Q).
La constellation obtenue dans ces conditions (après multiplication par 2) est :
q'(t)
q(t)
a (t )
p(t)
ϕ(t) ∆ω.t - ψ
p'(t) ℜ
Opération temporelle :
x(t) xech(t)
Fe = F0 xech(t)
Opération fréquentielle :
γx(f)
-f0 f0 f
γx*(f)
-Fe Fe f
L'observation du spectre ci-dessus montre que l'opération d'échantillonnage génère une infinité de
spectres, ceux d'origine qui sont translatés tous les k.Fe. Parmi cette infinité, un seul nous intéresse
celui situé en bande de base, autour de 0Hz.
Afin de rapprocher le phénomène d'échantillonnage de celui de la modulation, nous allons dans un
premier temps montrer qu'un échantillonnage est équivalent à une infinité de modulation AM.
2.2.1. Théorie
La modulation AM est ici prise au sens de la multiplication par un cosinus (modulation AM sans
porteuse).
Rappelons que l'échantillonnage peut être vu comme la multiplication d'un signal x(t) par un peigne
k=∞
de Dirac que l'on notera Peignet =∑k=−∞ t −kT e
On montre que la transformée de Fourier du peigne temporel est un peigne fréquentiel que l'on
notera :
1 k=∞
Peigne f = ∑k=−∞ f −kF e
Te
On peut alors regrouper les termes deux à deux, par fréquences opposées. Cela donne alors :
1 k=∞ 1
Peigne f =
Te
∑ k=1
[ f −kF e f kF e ] 0
Te
2 k=∞ 1 1 1
Peigne f =
Te
∑ k=1
[ . f −kF e . f kF e ] 0
2 2 Te
1 j 1 −j
Ap.cos( 2.π.fp.t + ϕp) donne S f = . f − f p. e . f f p . e
2 2
1 2 k=∞
Peignet = ∑k=1 cos 2. . k. F e . t
Te Te
1 2 k=∞
x ech t=Peignet. x t= . x t ∑k=1 [ x t. cos 2. . k. F e . t]
Te Te
Résumé
Le fait d'introduire la multiplication analogique de x(t) par un peigne de Dirac (que nous
considérons ici comme une fonction continue) conduit à faire un rapprochement avec ce que nous
connaissons des modulations classiques :
1/Te
x(t)
X
2/Te.cos(2.π.Fe.t)
X
2/Te.cos(2.π.2.Fe.t)
∑ xech(t)
X
2/Te.cos(2.π.k.Fe.t)
X
Les représentations discrètes et continues sont tout à fait équivalentes. Elles produisent le même
type de signal. Soulignons que ce dernier n'a pas de réalité physique, puisqu'il s'agit de suite de
Dirac (d'amplitude infinie par définition). Néanmoins, si nous acceptons que l'on puisse construire
une infinité de multiplieurs, si nous acceptons aussi le fait que le sommateur ne sature pas (pas de
limite d'amplitude), et enfin si nous considérons les multiplieurs et sommateurs comme des
éléments à bande passante infinie, alors nous avons recréé sur la figure ci-dessus, l'échantillonnage
de x(t) avec des fonctions et opérateurs continus.
Cet effort d'imagination, d'abstraction étant fait, on peut envisager de traiter xech(t) comme un signal
réel Lambda, bien qu'il ne possède pas de réalité physique.
Tout ce qui a été vu jusqu'à maintenant sur la théorie de l'échantillonnage est nécessaire et
indispensable pour comprendre ce qui se joue en terme de signal, temporel, fréquentiel.
Nous avons notamment montré que du point de vue mathématique, échantillonner un signal réel, de
type tension par exemple, revient à obtenir un signal sans existance physique, qui aurait la forme
d'une suite d'impulsions de durée nulle, d'amplitude infinie, et dont le poids (la surface) contiendrait
l'information de la grandeur traitée.
On représente (à tord mais on peut difficilement faire autrement), un signal échantillonné par une
suite de traits ou de flèches, dont l'amplitude est à l'image du signal échantillonné (faux, puisque
c'est la surface, rappelons-le qui contient l'information).
Il est nécessaire maintenant de faire le lien entre cette abstraction mathématique et la réalité des
systèmes échantillonnés par micro-contrôleur.
Signal
échantillonné,
Signal
Signal numérisé bloqué
Signal échantillonné
analogique (inobservable)
Fe
Processus de Traitement Processus de
Bloqueur
x(t) conversion numérique conversion
d'ordre 0 y(t)
A/N N/A
[V] xech(t) xNum(n) yNum(n) [V]
yech(t)
[V.S-1] [] [] [V.S-1]
Convertisseur Convertisseur
CPU
analogique/numérique numérique/analogique
Légende :
Signal échantillonné bloqué : c'est une grandeur analogique (tension) qui est
constante entre deux échantillons.
Explication :
L'ADC (Analog to Digital Converter) :
Il transforme le signal analogique en une suite d'impulsion Xnum(n). Sur le schéma, le travail de
l'ADC est décomposé en deux : l'échantillonnage (opération purement mathématique), et la
conversion proprement dite (quantification). On note au passage que le signal échantillonné Xech(t)
est devenu Xnum(n) qui est une suite de nombre, et non plus une suite de Diracs.
La CPU :
C'est le lieu du calcul numérique. A ce niveau là, les signaux on tous des spectres infinis et qui se
répètent tous les Fe (fréquence d'échantillonnage), les spectres sont périodiques.
δ(t) h(t)
1
t Τe t
1
Fh(t) = ∫0
T e
1.e
− j.2. . f.t
dt=
− j.2.. f
.e
− j.2. . f.T
−1 = H(jf)
e
e j.2. . f.T /2
e
j.2. . f.T / 2 − j.2. . f.T /2
= .e e
−e e
j.2.. f
= .e −ee
=T e e j.2. . f.T /2 sinc. f.T e
e e
j.2. . f.T e
|H(jf)|
Te
1/Te 2/Te k/Te
Le bloqueur d'ordre 0 aura donc la propriété essentielle de filtrage passe-bas, ce qui préserve les
fréquences en dessous de Fe (avec une distorsion). Le spectre n'est plus infini, n'est plus périodique :
le bloqueur d'ordre 0 a donc opéré le changement de nature échantillonné / continu.
Enfin, le bloc « processus de conversion N/A » du schéma permet de transformer les nombres
YNum(n) en une suite d'impulsions de Dirac, Yech(t), compatible en terme de dimension avec le
bloqueur d'ordre 0. On note également que c'est à ce niveau que se passe la quantification du DAC.
Représentons le spectre Xech(f) progressivement , pour x(t) de type MAQ à la fréquence f0:
X(f)
échantillonnage
-f0 f0 f
Xech(f) k=0
AM à 0Hz
+
-f0 f0 f
AM à fe
Xech(f) k=1
Spectres
superposés
-2f0 -2f0
+
f
Xech(f) k=2
AM à 2fe
Xech(f)
...
-fe fe f
...
-fe fe f
Te k =∞ T
PeigneQuad t =Peigne t− =∑k =−∞ t−kT e − e
4 4
1 2 k=∞
PeigneQuad t = ∑ k=1 cos 2. . k. F e .t−k.
T e Te 2
2
Ainsi, pour k=1, on se retrouve avec l'équivalent d'une multiplication par sin 2.. k. F e . t
Te
Afin de reproduire à la fois la multiplication en cosinus et celle en sinus, on va procéder à un
échantillonnage unique, dont la fréquence réelle d'échantillonnage de l'ADC, fe_ADC, est quatre fois
plus grande que la fréquence d'échantillonnage fe du signal. A l'issue d'une période complète
d'échantillonnage Te = 1/fe, on disposera de 4 échantillons (prélevés à Te_ADC = 1 / fe_ADC), dont les
deux premiers seront respectivement représentatif due la multiplication en cosinus et en sinus.
fe_ADC = 4.fe
fe_ADC= 4.fe Échantillonnage
P'(n) réel P', Q' à fe
xech(n) -Q'(n)
x(t) ADC
inutilisé
Multiplexeur
analogique 4 inutilisé
positions
Le signal IQ présent à l'entrée est x t = p t .cos 2. . f 0 . t −q t. sin 2. . f 0 . t
Ce dispositif d'échantillonnage est aussi appelé Filtre polyphase numérique. Il est donc vu comme
un filtre numérique ultra-simple, fonctionnant à la fréquence Fe, mais possédant plusieurs phases en
sortie, 4 pour être précis.
3.1. Présentation
Dans cette partie, nous allons exploiter les résultats vus précédemment, et procéder à un sous
échantillonnage. La fréquence fe vaut donc f0/M, M étant entier. Voyons cela au niveau spectral :
BP
X(f)
-f0 f0
f
Peigne(f)
fe
f
Xech(f)
-f0 f0
f
Dans cet exemple, la “modulation d'amplitude” qui nous intéresse est celle dont la fréquence est
3.fe. Bien entendu, le spectre Xech(f) est encombré par l'infinité des autres modulations. Le bloqueur
d'ordre 0 fera son travail d'élimination de ces éléments gênants.
Si l'on observe le signal avant échantillonnage, X(f), dont le spectre est bien plus élevé que f e, le
théorème de Shannon n'est pas respecté. Par contre, il faut noter que si on ne veut pas de repliement
de spectre du modulant, il faut nécessairement que fe > Bp, Bp est la bande passante du signal à
bande étroite. Dans l'exemple, on se trouve juste à la limite.
Le peigne en phase produit uniquement des cosinus. Ce n'est pas le cas du peigne décalé d'un quart
de période. Toutes les harmoniques ne donnent pas un sinus.
1 2 k=∞
PeigneQuad t = ∑ k=1 cos 2. . k. F e .t−k.
T e Te 2
Nous pouvons dresser un tableau qui indique la nature de l'onde sinusoïdale en fonction de son rang
k:
Annexe
Il s'agit d'un nombre complexe composé pour partie réelle du signal x(t) et pour partie imaginaire de
la transformée de Hilbert de x(t).
Remarque : zx(t) n'a pas de réalité physique, mais nous verrons que cette notation est pratique pour
l'analyse des signaux à bande étroite.
2. Transformée de Hilbert
La transformée de Hilbert d'un signal réel x(t) a pour effet de déphaser de π/2 (retard) chacune des
composantes spectrales de X(f). Le module vaut 1.
Sa fonction de transfert, H(f), peut se représenter par :
|H(f)|
ϕ(f)
+π/2
f
−π/2
Remarque : La transformée de Hilbert peut être vue comme un filtre linéaire. Ceci dit, celui-ci n'est
pas réalisable car non causal. Il peut être approximé dans une bande de fréquence donnée.
x t =A.cos 2. . f x . t− =A.sin 2. . f x . t
2
|X(f)| |Zx(f)|
A/2
A
f f
f f
−ϕ
Cas général :
Cette relation traduit clairement le fait que Zx(f) est asymétrique unilatéral, avec la mise à l'échelle
d'un facteur 2.
f f
b f0 b f0
Ici, b<f0, on peut associer directement un signal Dans ce cas, on ne peut pas faire correspondre
analytique simplement un signal analytique : il faut f0>b
Ainsi, on ne parlera d'enveloppe complexe que pour des signaux à bande étroite.
Prenons l'expression générale qui définit un signal modulé à la fois en amplitude et en phase :
x t =a t .cos 2.. f 0 .tt , ou a(t) et ϕ(t) sont réels. De plus a(t) >0.
Il s'écrit aussi :
j 2. . f 0 .t t − j 2. . f 0 . t t j.2. . f 0 .t − j.2. . f 0 . t
e e e e
x t =a t . a t . =a t. e j. t . a t. e− j. t .
2 2 2 2
1 1
X f =ℱ [a t . e j. t ]⊗ . f − f 0 ℱ [a t . e− j. t ]⊗ . f f 0
2 2
Comme le signal est à bande étroite, le premier terme, qui correspond aux fréquences positives, ne
déborde pas du côté négatif des fréquences. Ainsi, par définition du signal analytique,
Z x f =2.U f . X f , il vient
1
Z x f =ℱ [a t . e j.t ]⊗ . f − f 0 , ce qui donne par transformée de Fourier inverse le
2
signal analytique associé :
En exprimant zx(t) sous la forme partie réelle et partie imaginaire (transformée de Hilbert), on
obtient :
z x t= x t j x t=a t. cos 2. . f 0 . t t j.a t . sin 2. . f 0 .tt
L'enveloppe complexe peut se représenter dans le plan complexe (et c'est l'intérêt !) :
q(t)
a(t)
ϕ(t)
ℜ
p(t)
Pour une modulation de phase et d'amplitude (MAQ), l'enveloppe complexe, observée sur un temps
suffisamment long (l'ensemble des symboles possible ayant pu défiler), devient le diagramme de
constellation.
MAQ-4 : p(t) =+/-1, q(t) =+/-1
q(t) Ι
a(t
ϕ(t)
)
p(t)
ℜ
z x t= x t j. x t
z x t=a t. e j. t . e j.2. . f .t
x t =a t .cos 2.. f 0 .tt 0
x t =R[ z x t]
Z x f =2.U f . X f
X f =ℱ [s t ] Z x f =ℱ [ z x t]