Vous êtes sur la page 1sur 83
UTBM – TR57 Automne 2006 – Eric OBSER & Vincent HAEGELIN – dSPIC30F4011 & PICOS
UTBM – TR57 Automne 2006 – Eric OBSER & Vincent HAEGELIN – dSPIC30F4011 & PICOS

Sommaire

1. Introduction

 

4

2. Présentation des outils de developpement

4

2.1.

MPLAB IDE

4

2.1.1.

Rapide prise en main du logiciel

5

 

2.1.1.1. Création du premier projet

5

2.1.1.2. Simulation du premier projet

9

2.2. MPLAB ICD2

11

2.3. dsPICDEM2

11

2.4. Documentations utiles

12

3. Notion sur le projet et la programmation en C

12

3.1. Composition du projet

12

3.2. Accès aux variables

13

3.3. Accès direct à un bit d’un registre de configuration

14

3.4. Registres gérant les interruptions

14

3.5. Déclaration d’une routine d’interruption

16

4. Application sous dsPIC30F

17

4.1.

Gestion des interruptions externes INT0 et INT1

17

4.1.1. Avant propos

17

4.1.2. Programmation

17

 

4.1.2.1. Initialisation des interruptions INT0 et INT1

17

4.1.2.2. Déclaration du prototype de la fonction

18

4.1.2.3. Ecriture des routines d’interruptions associées

18

4.1.2.4. Ecriture de la fonction principale (main.c)

18

4.2.

Gestion des Timers 1 et 3

19

4.2.1. Avant Propos

19

4.2.2. Programmation

24

 

4.2.2.1.

Initialisation des Timers

24

4.2.2.1.1. Timer1

24

4.2.2.1.2. Timer3

25

4.2.2.2. Déclaration du prototype des fonctions

25

4.2.2.3. Ecriture des routines d’interruptions associées

26

4.2.2.3.1. Timer1

26

4.2.2.3.2. Timer3

27

4.2.2.4.

Ecriture de la fonction principale (main.c)

27

4.2.3.

Simulation

28

4.3.

Gestion de l’UART

28

4.3.1. Avant propos

28

4.3.2. Programmation

32

 

4.3.2.1. Initialisation de l’UART

32

4.3.2.2. Déclaration du prototype de la fonction

32

4.3.2.3. Ecriture des routines d’interruptions associées

33

4.3.2.4. Ecriture de la fonction principale (main.c)

34

4.3.3.

Simulation

36

4.4.

Gestion de la PWM

37

4.4.1. Avant propos

37

4.4.2. Programmation

41

 

4.4.2.1.

Initialisation du module PWM

41

4.4.2.2.

Déclaration du prototype de la fonction

42

 

4.4.2.3.

Ecriture de la fonction principale (main.c)

43

4.4.3.

Simulation

43

4.5.

Gestion du convertisseur Analogique Numérique 10 bits

44

4.5.1. Avant propos

44

4.5.2. Programmation

53

 

4.5.2.1. Initialisation de l’ADC

53

4.5.2.2. Déclaration du prototype de la fonction

54

4.5.2.3. Ecriture des routines d’interruptions associées

54

4.5.2.4. Ecriture de la fonction principale (main.c)

54

4.5.3.

Simulation

57

4.6.

Gestion du SPI pour communication avec LCD

57

4.6.1. Avant propos

58

4.6.2. Programmation

60

 

4.6.2.1. Initialisation du module SPI

61

4.6.2.2. Sous-programme d’écriture sur l’afficheur LCD

61

4.6.2.3. Déclaration du prototype des fonctions

64

4.6.2.4. Ecriture de la fonction principale (main.c)

64

4.6.3.

Simulation

64

5. Conclusion

64

6. Le noyau temps-réel PICOS

65

6.1.

Présentation

65

6.1.1. Les avantages d’un noyau temps-réel

65

6.1.2. Les inconvénients d’un noyau temps-réel

65

6.2.

PICOS : un noyau temps-réel, multitâches, préemptif, normalisé

66

6.2.1. Un noyau

66

6.2.2. Un noyau multitâches

66

6.2.3. Un noyau préemptif

66

6.2.4. Un noyau normalisé

66

6.3.

Mise en œuvre de PICOS

67

6.3.1. Objectif et attentes

67

6.3.2. Etape n°1 : se procurer les outils nécessaires

67

6.3.3. Etape n°2 : installer et configurer les outils

67

6.3.4. Etape n°3 : création et paramétrage du projet PICOS

68

6.3.5. Etape n°4 : Ajouter les fichiers au projet

69

6.3.6. Etape n°5 : Paramétrer les chemins des ressources

69

6.4.

Comprendre le fonctionnement de PICOS, visite guidée du code

70

6.4.1. Le fichier main.c

70

6.4.2. Le fichier Tascdesc.c

73

6.4.3. Le fichier tsk_taskX.c

76

6.5.

Création d’une nouvelle tâche

77

6.5.1. Création d’un nouveau fichier tsk_taskX.c

77

6.5.2. Modifications dans le fichier taskdesc.c

77

6.5.3. Modifications dans le fichier define.h

80

6.6.

Exemple de fonction pilotée par PICOS : contrôle moteur par PWM

80

6.6.1. Phase de développement

81

6.6.2. Intégration du code dans l’environnement de PICOS

82

7. Conclusion

 

83

1.

Introduction

La plupart des processus industriels sont maintenant commandés et supervisés par des batteries de microcontrôleurs. Ces derniers permettent une meilleur flexibilité de commande des processus, de plus ils apportent des solutions de communication, qui pour lors ne sont pas réalisables dans un processus totalement analogique. Ainsi l’industrie tend de plus en plus vers des communications Machine to Machine (M2M) permettant de suivre la qualité de la fabrication et de corriger des dysfonctionnements rapidement. Pour exemple, si sur une machine-outil un roulement s’use plus rapidement que prévu, ou qu’une cote n’est plus exacte, les capteurs le détectent et envoient l’information à la machine en amont qui peut prendre la décision de changer sa commande. Tout ceci demande une intelligence embarquée

des capteurs de plus en plus importante. Ainsi les capteurs standards dans le passé mesuraient une grandeur voulue, maintenant grâce aux microcontrôleurs embarqués, il est possible de compenser les grandeurs d’influences, de donner des informations de diagnostic permettant de faire remonter des informations de dysfonctionnement aux calculateurs. Une tendance actuelle est aussi de pouvoir paramétrer les capteurs à distance.

A la lumière de ceci, nous pouvons en déduire que les microcontrôleurs au plus près du

processus (gestion de capteur, de commande moteur,…) doivent gérer un flux de données conséquents tout en respectant des contraintes temps réel.

L’unité de valeur TR57 a pour but de sensibiliser les étudiants à la commande temps réel des processus. Une commande est dite temps-réel lorsqu’elle respecte deux principes :

Le temps d’acquisition des données : le traitement et la restitution de la commande respecte des temps définis dans le cahier des charges.est dite temps-réel lorsqu’elle respecte deux principes : La commande doit être déterministe, c'est-à-dire que

La commande doit être déterministe, c'est-à-dire que pour une entrée donnée la sortie doit toujours être la même.respecte des temps définis dans le cahier des charges. 2. Présentation des outils de developpement 2.1.

2. Présentation des outils de developpement

2.1. MPLAB IDE

2. Présentation des outils de developpement 2.1. MPLAB IDE MPLAB IDE est un environnement intégré de

MPLAB IDE est un environnement intégré de développement permettant

de programmer toutes les familles de microcontrôleur de Microchip. De

base et en version gratuite disponible sur www.microchip.com , il est

possible de développer des applications uniquement en langage Assembleur. L’adjonction de module tel que C18 ou C30 permet de

programmer en C respectivement des microcontrôleurs de la famille 18F

et 30F. Ces modules sont aussi disponibles sur le site internet mais seulement en version

étudiante. Cette version optimise le code pendant une durée de 60jours puis fonctionne sans optimisation de code. L’option d’optimisation est inutile car l’utilisation ultérieur du noyau temps réel PICos(voir www.picos18.com) de la société PRAGMATEC n’utilise pas l’optimisation du code.

La suite des explications est donnée pour la version v7.5 de MPLAB IDE et MPLAB C30 version 2.05. Les développements se font sur une cible dsPIC30F4011.

2.1.1. Rapide prise en main du logiciel

Cette rapide prise en main du logiciel n’a pas pour but d’expliquer toutes les fonctionnalités de MPLAB IDE et de MPLAB C30, mais d’expliquer le minimum pour pouvoir lancer un projet.

Après avoir installé le logiciel MPLAB IDE et MPLAB C30, lancer l’application.

2.1.1.1.Création du premier projet La première étape est de vérifier que MPLAB C30 est bien installé. Pour ce faire cliquer sur ProjectËSet Language Tool Locations

Vérifier que le compilateur est bien installé. Puis faire OK

que le compilateur est bien installé. Puis faire OK La création d’un nouveau projet se fait

La création d’un nouveau projet se fait par

ProjectËProject Wizard

puis choisir la cible (dans notre cas dsPIC30F4011) puis Suivant.

Cliquer sur suivant

notre cas dsPIC30F4011) puis Suivant. Cliquer sur suivant Il faut maintenant choisir le langage de programmation,

Il faut maintenant choisir le langage de programmation, nous développons une application pour dsPIC30F il nous faut donc choisir Active Toolsuite : Microchip C30 Toolsuite. Puis cliquer sur Suivant

: Microchip C30 Toolsuite. Puis cliquer sur Suivant UTBM – TR57 Automne 2006 – Eric OBSER

Entrer le nom de votre projet ainsi que son emplacement sur le disque dur. Puis cliquer sur Suivant. Attention le nom de votre projet ne doit pas dépasser les 8 caractères et il est souvent préconisé de n’avoir aucun espace dans l’adresse de votre dossier ou le projet est sauvegardé.

Vous pouvez inclure des fichiers qui existent déjà dans votre dossier (fichier header *.h ou fichier contenant du code *.c, fichier linker .gld ou tout autre fichier reconnu par l’environnement de développement). Dans notre cas aucun fichier n’est à joindre. Cliquer sur Suivant, puis vérifier les données et cliquer sur Terminer si tout vous convient.

les données et cliquer sur Terminer si tout vous convient. Votre projet est maintenant créé. Il
les données et cliquer sur Terminer si tout vous convient. Votre projet est maintenant créé. Il

Votre projet est maintenant créé. Il faut toutefois encore y adjoindre quelques fichiers. Recherchez sur votre ordinateur le fichier p30f4011.gld, ce fichier permet de faire le lien lors de la compilation entre votre programme et le dsPIC utilisé. Il se peut que se fichier se trouve sous le répertoire

C:\Program Files\Microchip\MPLAB ASM30 Suite\Support\gld

En d’autres cas faire une recherche sous Windows.

Lorsque vous avez trouvé ce fichier, le copier dans le dossier du projet.

Recherchez aussi le fichier p30f4011.h, ce fichier contient tous les registres du microcontrôleur. Il se peut que ce fichier se trouve sous le répertoire

Emplacement où est installé MPLAB C30\support\h

6
6

En d’autres cas faire une recherche sous Windows.

Lorsque vous avez trouvé ce fichier, le copier dans le dossier du projet.

Il vous suffit maintenant d’inclure ces deux fichiers dans le projet en cliquant (clique droit) sur votre projet puis Add Files

UTBM – TR57 Automne 2006 – Eric OBSER & Vincent HAEGELIN – dSPIC30F4011 & PICOS 30

Choisir p30f4011.h puis cliquer sur Ouvrir Répéter l’opération mais en choisissant dans le menu déroulant Fichier de type Ë Linker Scripts (*.gld) sélectionner p30f4011.gld puis ouvrir.

Il faut encore configurer certains bits pour que votre projet soit prêt.

configurer certains bits pour que votre projet soit prêt. Cliquer sur Configure Ë Configuration Bits Ces

Cliquer sur ConfigureËConfiguration Bits

Ces registres permettent de configurer les bits de fonctionnement du microcontrôleur.

Oscillator Source = Primary Oscillator Cette configuration indique que le microcontrôleur utilise le quartz branché sur les broches

OSC1/OSC2.

Primary Oscillator Mode = XT w/PLL4x Le quartz branché sur les Pin OSC1 et OSC2 donne la fréquence de fonctionnement du CPU (Fcy=Fosc/4). Ce microcontrôleur peut augmenter la vitesse CPU en utilisant une PLL tout en gardant le même quartz. Ainsi si le mode XT w/PLL4x est sélectionné, la PLL augmente de 4 fois la fréquence de fonctionnement du CPU. Il est possible de l’augmenter de 8 fois ou même de 16 fois. Dans notre cas Fcy=Fosc/4=(Fquartz*4)/4=Fquartz

La connaissance de Fcy est très importante lorsque vous configurerez des registres basés sur

le temps (PWM, Timer, UART,

)

Il existe d’autres entrées d’oscillateur. Le choix de XT est dû au fait que nous utilisons une horloge externe basée sur un quartz.

Watchdog Timer=Disable Permet d’inhiber la fonction Watchdog Timer, car sinon votre microcontrôleur se réinitialise au bout d’un certain temps.

La configuration donnée est :

au bout d’un certain temps. La configuration donnée est : Votre projet est prêt, il ne

Votre projet est prêt, il ne vous reste plus qu’à y ajouter le fichier comprenant la fonction principale.

Créer un nouveau fichier en faisant FichierË Add New File to Project… entrer le nom de votre fichier (dans notre cas main.c) puis enregistrer.

Taper le code suivant :

#include "p30F4011.h" int main (void)

{

while(1) ;

}

Puis compiler ctrl+F10 ou alors ProjectËBuild All.

La compilation doit se faire sans erreur.

Pour la simulation, nous pouvons remarquer que ce programme réalise une boucle infinie sans rien faire. Il est important de toujours mettre un while(1) à la fin de votre programme car sinon le compteur programme pourrait se perdre en engendrant un plantage du système.

Modifions le programme pour réaliser des additions et comparaisons afin de pouvoir le simuler.

#include "p30F4011.h" int valeur1,valeur2;

unsigned int valeur3 ; int stop ; boucle int main (void)

{

//déclaration de deux entier signé //déclaration d’un entier non signé //déclaration d’un entier permettant de savoir quand arrêter la

valeur1=0;

valeur2=0;

valeur3=0;

stop=0;

while(stop==0)

//initialisation de valeur1 à 0

//initialisation de valeur2 à 0

//initialisation de valeur3 à 0

//initialisation de stop à 0

//tant que boucle stop est égale à 0

{

valeur1++ ;

//incrémentation de valeur1

valeur2+=valeur1+10 ;

//valeur2=valeur2+valeur1+10

valeur3=valeur1+valeur2;

//valeur3= valeur2+valeur1

if(valeur3>=1000)

//Si valeur3 supérieur ou égale à 1000 alors on

{

//arrête la boucle

stop=1;

//boucle stop =1

}

}

while(1) ;

}

Lorsque vous avez tapé ce code compiler votre projet. (ctrl+F10). Passons maintenant à la simulation.

2.1.1.2.Simulation du premier projet

L’environnement permet de simuler et debugger votre programme sans utiliser de microcontrôleur. Les fonctionnalités explicitées sont celles de base, mais bien d’autres actions peuvent être réalisées par le simulateur. (Simulation de la liaison RS232, d’entrées-sorties,…).

Configuration du simulateur

Cliquer sur Debugger Select Tool MPLAB SIM

Lorsque vous recliquez sur Debugger, de nouvelles options s’affichent. Sélectionner DebuggerËSettings

options s’affichent. Sélectionner Debugger Ë Settings Entrer la valeur du Quartz utilisé. La simulation ne prend

Entrer la valeur du Quartz utilisé. La simulation ne prend pas en compte la PLL d’entrée, pour elle dans tous les cas Fcy=Processor Frequency/4

Dans notre cas, nous avons utilisé une PLLx4 Donc le Processor Frequency=Fquartz*4 A.N. :

Fquartz=7,3728MHz

Processor Frequency=7,3728*4=29,4912 MHz

Cliquer sur Ok

Processor Frequency=7,3728*4=29,4912 MHz Cliquer sur Ok Placer maintenant des breakpoints au niveau de stop=0;

Placer maintenant des breakpoints au niveau de stop=0; stop=1; while(1);. Pour placer des breakpoints cliquer dans la barre grise au niveau de la ligne où vous voulez que la simulation s’arrête.

de la ligne où vous voulez que la simulation s’arrête. Raccourcis clavier pour la simulation F6=Reset

Raccourcis clavier pour la simulation

F6=Reset du processeur F7=mode pas à pas en entrant dans toutes les fonctions F8=mode pas à pas les fonctions sont simulées comme une unique instruction F9=lance la simulation jusqu’au prochain breakpoint.

Avant de simuler il serait peut être intéressant de suivre l’évolution de certaines variables, pour ce faire cliquer sur ViewËWatch

Une fenêtre s’affiche, dans Symbol Name, entrer les variables ou registres que vous voulez surveiller. Dans notre cas valeur1, valeur2, valeur3 et stop.

Dans notre cas valeur1, valeur2, valeur3 et stop. Lancer la simulation par F9. Elle va s’arrêter

Lancer la simulation par F9. Elle va s’arrêter sur votre premier Breakpoint stop=0 ; Passer maintenant en mode Pas à Pas (F7) et suivre l’évolution des grandeurs.

L’affichage en mode Hexadécimal des grandeurs d’évolution n’est peut être pas dans notre cas adéquat. Cliquer sur la grandeur d’évolution que vous souhaitez afficher dans une autre base puis Clique droitËProperties et dans le menu sélectionné Format=Decimal. L’affichage se fait maintenant en décimal.

Apres avoir passé le programme en revue, il serait peut être intéressant de connaître le temps que met le microcontrôleur pour effectuer la première boucle while(stop==0) ;. Pour ce faire cliquer sur Debugger StopWatch. Ce module permet de connaître le temps parcouru entre deux breakpoints à condition de l’initialiser à chaque fois.

breakpoint s à condition de l’initialiser à chaque fois. Enlever le breakpoint au niveau de la

Enlever le breakpoint au niveau de la ligne stop=1 ;

Reset du microcontrôleur par la touche F6. Puis Lancer la simulation par la touche F9. La simulation s’arrête au niveau de stop=0 ; Cliquer dans la fenêtre StopWatch sur Zero, ceci aura pour effet de remettre le compteur à 0.

Appuyer sur F9, le programme s’arrête sur la boucle while(1). On peut lire sur la StopWatch 91,417101µs. Ainsi entre les deux breakpoints il s’est écoulé 91,417101µs

entre les deux breakpoints il s’est écoulé 91,417101µs Cette fonctionnalité nous sera utile lorsque nous

Cette fonctionnalité nous sera utile lorsque nous simulerons les interruptions des Timers. Ainsi nous pourrons rapidement vérifier la fréquence des interruptions et donc la fréquence du Timer.

2.2. MPLAB ICD2

MPLAB ICD2 est un système permettant de debugger et programmer les microcontrôleurs. Le débuggage se fait sur la cible même (In circuit Debugger). Le choix entre la programmation et le débuggage se fait sous MPLAB. Attention à ne pas sélectionner les deux fonctionnalités en même temps.

Pour la programmation de la carte dsPICDEM2, sélectionner ProgrammerË Select ProgrammerËMPLAB

ICD2.

Puis ProgrammerËConnect Enfin ProgrammerËProgramm

2.3. dsPICDEM2

La carte dsPICDEM2 est une carte développement créée par Microchip. Cette carte permet de tester différents PIC 18 broches, 28 broches et 40 broches en boitier PDIP ou SPDIP. De base la carte comporte un dsPIC30F4011. Il est possible d’accéder à toutes les broches du microcontrôleur via des connecteurs, toutefois certaines fonctionnalités sont embarquées sur la carte afin d’avoir un mini environnement de développement. Ainsi la carte comprend un contrôleur RS232, un contrôleur CAN (Controller Area Network), des Leds de visualisation, des boutons, un potentiomètre, une sonde de température et un afficheur LCD (2*16 caractères).

de température et un afficheur LCD (2*16 caractères). Un Connecteur ICD permet la programmation et le
de température et un afficheur LCD (2*16 caractères). Un Connecteur ICD permet la programmation et le

Un Connecteur ICD permet la programmation et le débuggage de cette carte par MPLAB

ICD2

2.4. Documentations utiles

Avant de commencer la programmation pure de fonctionnalités, certains documents sont nécessaires :

Sur internet (www.microchip.com ) www.microchip.com)

sont nécessaires : Sur internet ( www.microchip.com ) dsPIC30Family Reference Manual Documentation expliquant tous

dsPIC30Family Reference Manual

Documentation expliquant tous les registres du dsPic30FXXXX avec la fonction de chaque bit, ainsi que des exemples de fonctionnalités. Certaines fonctionnalités et certains registres sont détaillés mais non implémentés sur le 30F4011.

30F4011 datasheetsont détaillés mais non implémentés sur le 30F4011. Documentation expliquant tous les registres du dsPic30F4011.

Documentation expliquant tous les registres du dsPic30F4011.

Documentation expliquant tous les registres du dsPic30F4011. C30_Users_Guide Document expliquant la programmation en C

C30_Users_Guide

Document expliquant la programmation en C avec le module C30 de Mplab. Attention des différences peuvent apparaître avec C18. C18 à été développé par Microchip alors que C30 a été sous-traité par Mircrochip à une société tierce.

a été sous-traité par Mircrochip à une société tierce. 16-BIT LANGUAGE TOOLS GETTING STARTED Manuel de

16-BIT LANGUAGE TOOLS GETTING STARTED

Manuel de prise en main du module C30.

TOOLS GETTING STARTED Manuel de prise en main du module C30. Sur le CD fournit avec

Sur le CD fournit avec le dsPICDEM2 dsPICDEM 2 Users Guide DS-51558A.pdf

avec le dsPICDEM2 dsPICDEM 2 Users Guide DS-51558A.pdf Document expliquant les fonctionnalités de la carte

Document expliquant les fonctionnalités de la carte dsPICDEM2 ainsi que les méthodes d’accès à l’afficheur LCD et la configuration des cavaliers et switches pour vos applications.

3. Notion sur le projet et la programmation en C

3.1. Composition du projet Avant de commencer tous les petits exemples, il est important de comprendre la structure générale des projets.

Un projet est composé de différents fichiers :

projets. Un projet est composé de différents fichiers : main.c Ce fichier comprend le programme principal

main.c

Ce fichier comprend le programme principal du projet. Code du fichier main.c

#include "define.h" int main ( void ) {//code du projet}

define.h Ce fichier comprend toutes les #include importants du projet. Code du fichier define.h //fichier

define.h

Ce fichier comprend toutes les #include importants du projet.

Code du fichier define.h

//fichier comprenant tous les registres du dsPIC30F4011 #include p30F4011.h //fichier comprenant tous les prototypes des fonctions utilisées #include "fonction.h" //Si nous utilisons la fonction printf avec l’UART nous devrons inclure stdio.h #include <stdio.h>

fonction.hnous devrons inclure stdio.h #include <stdio.h> Ce fichier comprend tous les prototypes des fonctions

Ce fichier comprend tous les prototypes des fonctions utilisées. Ainsi une fonction peut être appelée dans tous les fichiers incluant #include "define.h"

Code du fichier define.h

/********************************************************************** * Fonction prototypes. **********************************************************************/

nom_fonction.c Ce fichier comprend une fonction. Le fichier

nom_fonction.c

Ce fichier comprend une fonction. Le fichier prendra le nom de la fonction. Si la fonction est l’initialisation d’un périphérique, la description de l’interruption du périphérique est aussi incluse dans le fichier.

Tous les fichiers .c doivent comporter #include "define.h" afin d’avoir accès à toutes les fonctions.

Créer dès le départ le fichier main.c fonction.h et define.h, ceci permettra de les inclure dans chaque mini projet qui suivra.

3.2. Accès aux variables

Nous déclarons les variables globales dans le fichier main.c, pour avoir accès à ces variables dans un autre fichier que main.c, il faut déclarer dans le fichier les variables avec l’attribut extern. Attention à ne pas réinitialiser la variable dans le fichier sinon cela causera une erreur de compilation.

Pour exemple :

Création d’une variable entière dans main.c Déclaration dans le fichier main.c

int tab=0 ;

Besoin de la variable tab dans le fichier modif_uart.c Déclaration de la variable dans modif_uart.c

extern int tab ;

3.3. Accès direct à un bit d’un registre de configuration

Tous les registres de configuration sont déclarés dans p30F4011.h. Lorsque vous voulez accéder à un bit du registre, il faut taper le nom du registre (NomRegistre) suivi par bits puis d’un point et du nom du bit (NomBit) que vous voulez modifier. La syntaxe est la suivante NomRegistrebits.NomBit

Exemple pour le registre INTCON2

 

INTCON2

 

Bit

15

14

13

12

11 6

10 9

8

 

7 5

 

4

3

2

1

0

 

ALTIVT

DISI

-

-

- -

- -

-

 

- -

 

INT4EP

INT3EP

INT2EP

INT1EP

INT0EP

L’accès au bit INT0P se fait de la façon suivante :

INTCON2bits.INT0EP = 1 ;

3.4. Registres gérant les interruptions

Les registres IEC0, IEC1 et IEC2 gèrent l’autorisation des interruptions

1

= Autorisation de l’interruption

0

= Inhibe l’interruption

   

IEC0

 

Bit

15

14

13

12

11

10

9

8

 

CNIE

MI2CIE

SI2CIE

NVMIE

ADIE

U1TXIE

U1RXIE

SPI1IE

Bit

7

6

5

4

3

2

1

0

 

T3IE

T2IE

OC2IE

IC2IE

T1IE

OC1IE

IC1IE

INT0IE

CNIE =Interruption sur changement d’état des entrées

 

MI2CIE = Interruption du bus I2C lors d’une collision SI2CIE = Interruption lorsqu’un transfert I2C est fini NVMIE = Interruption lorsque l’écriture dans la mémoire Non Volatile est fini ADIE = Interruption lorsque l’ADC a fini de convertir une donnée U1TXIE = Interruption lorsque l’UART1 a transmis un caractère U1RXIE = Interruption lorsque l’UART1 a reçu un caractère SPI1IE = Interruption du module SPI1 T3IE = Interruption du Timer3 T2IE = Interruption du Timer2 OC2IE = Interruption de l’Output Compare Channel 2 IC2IE = Interruption de l’Input Compare Channel 2 T1IE = Interruption du Timer1 OC1IE = Interruption de l’Output Compare Channel 1 IC1IE = Interruption de l’Input Compare Channel 1 INT0IE = Interruption de la broche INT0

   

IEC1

 

Bit

 

15

14

13

12

 

11

10

 

9

8

   

-

-

-

-

 

C1IE

-

U2TXIE

U2RXIE

Bit

 

7

6

5

4

 

3

2

 

1

0

   

INT2IE

T5IE

T4IE

OC4IE

 

OC3IE

IC8IE

 

IC7IE

INT1IE

C1IE = Interruption du Bus CAN U2TXIE = Interruption lorsque l’UART2 a transmis un caractère U2RXIE = Interruption lorsque l’UART2 a reçu un caractère INT2IE = Interruption de la broche INT2 T5IE = Interruption du Timer5 T4IE = Interruption du Timer4 OC4IE = Interruption de l’Output Compare Channel 4 OC3IE = Interruption de l’Output Compare Channel 3 IC8IE = Interruption de l’Input Compare Channel 8 IC7IE = Interruption de l’Input Compare Channel 7 INT1IE = Interruption de la broche INT1

 
   

IEC2

 

Bit

15

 

14

 

13 12

 

11

10

9

8

 

-

 

-

 

- -

 

FLTAIE

 

-

-

QEIIE

Bit

7

 

6

 

5

4

3 2

 

1

0

 

PWMIE

 

-

 

-

-

- -

 

-

-

FLTAIE = Interruption de FAULTA dans le module PWM QEIIE = Interruption du module de Quadrature QEI PWMIE interruption du module PWM lorsqu’une période est accomplie

Les registres IFS0, IFS1 et IFS2 indiquent les interruptions qui sont actives

 

IFS0

 

Bit

15

14

13

12

11

10

9

8

 

CNIF

MI2CIF

SI2CIE

NVMIF

ADIF

U1TXIF

U1RXIF

SPI1IF

Bit

7

6

5

4

3

2

1

0

 

T3IF

T2IF

OC2IF

IC2IF

T1IF

OC1IF

IC1IF

INT0IF

 

IFS1

 

Bit

15

14

13

12

11

10

9

8

 

-

-

-

-

C1IF

-

U2TXIF

U2RXIF

Bit

7

6

5

4

3

2

1

0

 

INT2IF

T5IF

T4IF

OC4IF

OC3IF

IC8IF

IC7IF

INT1IF

 

IFS2

 

Bit

15

14

13

12

11

10

9

8

 

-

-

-

-

FLTAIF

-

-

QFIIF

Bit

7

6

5

4

 

3 2

1

0

 

PWMIF

-

-

-

 

- -

-

-

Lorsqu’une interruption survient, il faudra effacer le bit correspondant à l’interruption dans la routine.

Exemple :

Interruption activée sur le Timer2 (IEC0bits.T2IE=1) dans la routine d’interruption il faudra penser à mettre IFS0bits.T2IF=0

3.5. Déclaration d’une routine d’interruption

Il y a trois façons de déclarer une interruption

1. Aucune sauvegarde de contexte

void

{//code de l’interruption}

attribute

((

interrupt

))

_Nom de l’interruption(void)

2. Sauvegarde de contexte rapide par push. et pop.s

Sauvegarde des bits DC N OV Z C et des registres W0 à W3 du CPU

DC = Demi Carry permet de savoir si un carry est survenu sur les 4 bits de poids faible d’un

octet (8bits) ou bien si un carry est survenu sur les 8bits d’un mot (16bit).

N = Signe du registre de l’Unité Arithmétique et Logique

OV = Overflow de l’Unité Arithmétique et Logique

Z =

C = Carry de l’Unité Arithmétique et Logique

void

{//code de l’interruption}

Zero de l’Unité Arithmétique et Logique

attribute

((

interrupt

,

shadow

))

_Nom de l’interruption (void)

3. Sauvegarde du contexte en spécifiant les données à sauvegarder et restaurer.

Les variables 1 et 2 seront sauvegardées sur la pile puis restituées à la fin de l’interruption

void

(void) {//code de l’interruption}

attribute

((

interrupt

(

save

(variable1,variable2))))

_ Nom de l’interruption

Tous les noms d’interruption sont déclarés dans le fichier p30F4011.gld. Attention il faut enlever un underscore (_) par rapport au nom donné dans le fichier

Quelques exemples des interruptions les plus usitées :

Interruption

Déclaration en C

ADC

_ADCInterrupt

Timer1

_T1Interrupt

INT0

_INT0Interrupt

INT1

_INT1Interrupt

U1TX

_U1TXInterrupt

U1RX

_U1RXInterrupt

4. Application sous dsPIC30F

4.1. Gestion des interruptions externes INT0 et INT1

4.1.1. Avant propos

Le but de cette manipulation est d’utiliser les interruptions INT0 et INT1. Ces deux interruptions sont des interruptions externes qui interviennent lors d’un changement d’état sur la broche RE8 (INT0 pin 17) et RD0 (INT1 pin 23).

 

INTCON2

 

Bit

15

14

 

13 12

11 8

10

9 6

7

 

5

4

3

2

1

0

 

ALTIVT

DISI

- -

 

- -

-

- -

-

 

-

INT4EP

INT3EP

INT2EP

INT1EP

INT0EP

ALTIVT: Autorise la table des interruptions alternatives

1 = Use alternate vector table

0 = Use standard (default) vector table DISI: Statut des instructions INTxEP: Choix du front de détection

1

= Interruption sur front descendant

0

= Interruption sur front montant

4.1.2. Programmation

L’exemple que nous allons développer sur le dsPICDEM2 utilise le front montant sur INT0 pour déclencher une interruption qui éteindra la LED du port RB0, le front descendant sur INT1 déclenche une interruption qui allumera la LED du port RB0.

Créer un nouveau projet en incluant tous les fichiers de base d’un projet (define.h, fonction.h, main.c, p30f4011.h et p30f4011.gld). Tout d’abord afin de respecter la composition d’un projet, créons un fichier init_int01.c.

Ce

programmes d’interruption.

fichier

comprendra

l’initialisation

des

interruptions

INT0

et

INT1

ainsi

que

les

4.1.2.1.Initialisation des interruptions INT0 et INT1

Nous voulons la détection du front montant sur INT0 et du front descendant sur INT1

INTCON2bits.INT0EP = 1; INTCON2bits.INT1EP = 0;

Ensuite il faut effacer le flag d’interruption correspondant à l’interruption extérieure 0 et 1 IFS0bits.INT0IF = 0; IFS1bits.INT1IF = 0;

Puis activer les interruptions IEC0bits.INT0IE = 1; IEC1bits.INT1IE = 1;

void init_INT01(void)

{

 

INTCON2bits.INT0EP = 1; //interruption sur Front descendant INTCON2bits.INT1EP = 0; //interruption sur Front montant

IFS0bits.INT0IF = 0; IEC0bits.INT0IE = 1; IFS1bits.INT1IF = 0; IEC1bits.INT1IE = 1;

//Efface le flag d'interruption INT0 //Autorise les interruptions INT0 //Efface le flag d'interruption INT1 //Autorise les interruptions INT1

}

4.1.2.2.Déclaration du prototype de la fonction

Penser à mettre le prototype de la fonction dans fonction.h afin que tous les fichiers associés au projet aient accès à cette fonction. Dans fonction.h void init_INT01(void) ;

4.1.2.3.Ecriture des routines d’interruptions associées

Les interruptions n’ont pas besoin de sauvegarder le contexte car aucun calcul n’est effectué et donc nous n’utilisons pas l’ALU

Le bouton branché sur la broche RE8 (INT0 pin 17) éteint la Led branchée sur le PORTB0

void

attribute

((

interrupt

))

_INT0Interrupt(void)

{

 

LATBbits.LATB0 = 0; IFS0bits.INT0IF = 0;

 

//Eteint la LED //efface le flag d’interruption INT0

}

Le bouton branché sur la broche RD0 (INT1 pin 23) allume la Led branchée sur le PORTB0

void

attribute

((

interrupt

))

_INT1Interrupt(void)

{

 

LATBbits.LATB0 =1; IFS1bits.INT1IF = 0;

 

// Eteint la LED //efface le flag d’interruption INT1

}

Penser toujours à effacer les flags d’interruptions à la fin de chaque routine d’interruption

4.1.2.4.Ecriture de la fonction principale (main.c)

Dans la fonction principale, il faudra initialiser les interruptions avec le sous-programme que nous avons écrit. Penser aussi à définir le PORTB0 en sortie.

#include "define.h"

int main ( void )

{

init_INT01();

TRISBbits.TRISB0=0; //configure le PORTB0 comme sortie LATBbits.LATB0=0;//initialise le PORTB0 à 0

while(1);

}

Compiler le projet (ctrl+F10) puis programmer la platine dsPICDEM2. En appuyant sur les boutons poussoir INT0 et INT1 juste au dessus de l’afficheur LCD, vous verrez une Led s’allumer ou s’éteindre selon vos actions.

4.2. Gestion des Timers 1 et 3

4.2.1. Avant Propos Le but de cette manipulation est de pouvoir initialiser des Timers pour réaliser diverses actions relatives au temps. La famille des dsPIC30F possède différents types de Timers (A,B,C) qui caractérisent leurs fonctionnalités.

de Timers (A,B,C) qui caractérisent leurs fonctionnalités. Type A Les Timers de type A (Timer1 la

Type A

Les Timers de type A (Timer1 la plus part du temps) peuvent opérer en mode « 32kHz Low Power » et peuvent utiliser une source externe comme référence de comptage. La plupart du temps ce type de Timer est utilisé dans les OS temps réel pour décompter le temps.

utilisé dans les OS temps réel pour décompter le temps. UTBM – TR57 Automne 2006 –

Registre contrôlant le Timer1

 

T1CON

 

Bit

15

14

13

12

11

10

9 8

 
 

TON

-

TSIDL

-

-

-

- -

 

Bit

7

6

5

4

3

2

1 0

 
 

-

TGATE

TCKPS1

TCKPS0

-

TSYNC

TCS

-

TON: Lance le Timer

1

= Lance TIMER1

0

= Arrête TIMER1

TSIDL: Mode de fonctionnement en IDLE mode

1

= Arrête le TIMER1 en Idle Mode

0

= Continue les opérations de TIMER en IDLE mode

TGATE: Le TIMER1 est mis en mode "Timer Gated Time Accumulation" en d'autres termes le compteur du TIMER1(TMR1) s'incrémente uniquement lorsque TxCK est à l'état 1.

1 = Autorise le mode "Timer gated time accumulation"

(TCS doit être mis à ‘0’ quand TGATE = 1)

0 = Inhibe la fonction "Timer gated time accumulation" (Lecture d'un ‘0’ si TCS = 1)

TCKPS<1:0>: Prescaler de l'horloge TIMER1

11

= 1:256 prescaler

10

= 1:64 prescaler

01

= 1:8 prescaler

00

= 1:1 prescaler

TSYNC: Synchronisation avec l'horloge extérieure Quand TCS = 1:

1 = Synchronisation avec l'horloge externe

0 = Pas de Synchronisation avec l'horloge externe Quand TCS = 0:

Ce bit est ignoré

TCS: Choix de la source du TIMER1

1

= Horloge de la PIN TxCK

0

= Horloge interne (FOSC/4)

= Horloge de la PIN TxCK 0 = Horloge interne (FOSC/4) Type B Les Timers de

Type B

Les Timers de type B (Timer2 et Timer4 si implémenté) sont capables d’être concaténés avec un Timer de type C. Le bit T32 du registre TxCON contrôle alors le compteur 32bits. L’horloge d’incrémentation du Timer de type B utilise un prescaler permettant de fonctionner à une autre vitesse que celle du CPU (Tcy).

Registre contrôlant le Timer2 ou Timer4   T2CON et T4CON   Bit 15 14 13

Registre contrôlant le Timer2 ou Timer4

 

T2CON et T4CON

 

Bit

15

14

13

12

11

10

9 8

 
 

TON

-

TSIDL

-

-

-

- -

 

Bit

7

6

5

4

3

2

1 0

 
 

-

TGATE

TCKPS1

TCKPS0

T32

-

TCS

-

TON: Lance le Timer

Si T32=1 (Mode Timer 32 bits)

1

= Lance TIMER2 ou 4 32bits

0

= Arrête TIMER2 ou 4 32bits

Si T32=0 (Mode Timer 16 bits)

1

= Lance TIMER2 ou 4 16bits

0

= Arrête TIMER2 ou 4 16bits

TSIDL: Mode de fonctionnement en IDLE mode

1

= Arrête le TIMER1 en Idle Mode

0

= Continue les opérations de TIMER en IDLE mode

TGATE: Le TIMER2 ou 4 est mis en mode "Timer Gated Time Accumulation" en d'autres termes le compteur du TIMER2 ou 4 (TMR2 ou 4) s'incrémente uniquement lorsque TxCK est à l'état 1.

1 = Autorise le mode "Timer gated time accumulation"

(TCS doit être mis à ‘0’ quand TGATE = 1)

0 = Inhibe la fonction "Timer gated time accumulation" (Lecture d'un ‘0’ si TCS = 1)

TCKPS<1:0>: Prescaler de l'horloge TIMER2 ou 4 11 = 1:256 prescaler

10

= 1:64 prescaler

01

= 1:8 prescaler

00

= 1:1 prescaler

T32 : Sélectionne le Mode Timer 32bits

1 = Le Timer 2/3 ou 4/5 forme un timer 32bits

0 = Timer2 ou 4 16bits TCS: Choix de la source du TIMER2 ou 4

1

= Horloge de la PIN TxCK

0

= Horloge interne (FOSC/4)

= Horloge de la PIN TxCK 0 = Horloge interne (FOSC/4) Type C Les Timers de

Type C

Les Timers de type C (Timer3 et Timer5 si implémenté) ont la possibilité d’être concaténés avec un Timer de Type B. Un des Timers de type C (Timer3 en général) permet de lancer une conversion Analogique Numérique. (Le choix de la source de déclenchement des conversions ADC se fait dans les registres de l’ADC « SSRC de ADCON1 »)

se fait dans les registres de l’ADC « SSRC de ADCON1 ») UTBM – TR57 Automne

Registre contrôlant le Timer3 ou 5

 

T3CON

Bit

15

14

13

12

11

10

9 8

 
 

TON

-

TSIDL

-

-

-

- -

 

Bit

7

6

5

4

3

2

1 0

 
 

-

TGATE

TCKPS1

TCKPS0

-

-

TCS

-

TON: Lance le Timer

1

= Lance TIMER3 ou 5

0

= Arrête TIMER3 ou 5

TSIDL: Mode de fonctionnement en IDLE mode

1

= Arrête le TIMER1 en Idle Mode

0

= Continue les opérations de TIMER en IDLE mode

TGATE: Le TIMER3 ou 5 est mis en mode "Timer Gated Time Accumulation" en d'autres termes le compteur du TIMER3 ou 5 (TMR3 ou 5) s'incrémente uniquement lorsque TxCK est à l'état 1.

1 = Autorise le mode "Timer gated time accumulation"

(TCS doit être mis à ‘0’ quand TGATE = 1)

0 = Inhibe la fonction "Timer gated time accumulation" (Lecture d'un ‘0’ si TCS = 1)

TCKPS<1:0>: Prescaler de l'horloge TIMER3 ou 5

11

= 1:256 prescaler

10

= 1:64 prescaler

01

= 1:8 prescaler

00

= 1:1 prescaler

TCS: Choix de la source du TIMER3 ou 5

1

= Horloge de la PIN TxCK

0

= Horloge interne (FOSC/4)

Chaque TIMERx (x=1, 2, 3, 4, 5) possède les registres suivant :

TMRx = registre contenant la valeur de comptage. PRx = registre contenant la période du Timer. Ce registre est comparé à TMRx lorsque les deux registres sont égaux le Timer se réinitialise.

La valeur de PRx se calcul de la façon suivante :

Time

_

PRx =

x =

(

PRx

* Pr

escaler

)

Fcy

Time

_

x

*

Fcy

Pr escaler

4.2.2. Programmation

Créez un nouveau projet en incluant tous les fichiers de base d’un projet (define.h, fonction.h, main.c, p30f4011.h et p30f4011.gld). Tout d’abord afin de respecter la composition d’un projet, créons un fichier init_int01.c.

Ce

programmes d’interruption.

fichier

comprendra

l’initialisation

des

interruptions

4.2.2.1.Initialisation des Timers

INT0

et

INT1

ainsi

que

les

Le timer1 sera utilisé pour gérer une horloge, l’interruption permettra de mettre à jour les variables heure, minute, seconde et milliseconde. La fréquence d’interruption sera donc la milliseconde. Le timer3 permettra de créer la fréquence d’échantillonnage du convertisseur Analogique Numérique. Nous utiliserons une fréquence d’échantillonnage de 2kHz

4.2.2.1.1.

Timer1

Créer tout d’abord un fichier inclus dans le projet appelé init_timer1.c. Après avoir inclus le fichier define.h (#include "define.h"), commencer l’initialisation du

TIMER1.

Créer un sous programme void init_timer1(void)

Avec la description du registre donnée plus haut suivre les étapes suivantes :

1. Calculer la valeur de PR1 pour savoir si un prescaler est utile.

(Time_x=1ms, Fcy= (Fosc/4)*PLL4x=Fosc)

Pr

escaler =

Time

1

_

x

*

Fcy

PR 1 =

Pr escaler

=

1*10

- 3

*7,3728*10

6

=

[7372,8]

=

7372

=

0

1

x CCC

<

0

xFFFF

PR1 ne dépasse pas 65536 donc le prescaler n’a pas d’utilité.

2. Arrêter le Timer1

3. Configurer le TIMER1 :

Le Timer1 peut continuer les opérations en IDLE mode.2. Arrêter le Timer1 3. Configurer le TIMER1 : La fonction "Timer gated time accumulation" n’est

La fonction "Timer gated time accumulation" n’est pas utilisée.: Le Timer1 peut continuer les opérations en IDLE mode. Le prescaler vaut 1. La synchronisation

Le prescaler vaut 1.gated time accumulation" n’est pas utilisée. La synchronisation avec l’horloge externe n’est pas

La synchronisation avec l’horloge externe n’est pas utilisée.n’est pas utilisée. Le prescaler vaut 1. La source du timer est le quartz. Initialiser la

La source du timer est le quartz.avec l’horloge externe n’est pas utilisée. Initialiser la valeur du Registre contenant la valeur du

Initialiser la valeur du Registre contenant la valeur du compteur à 0.n’est pas utilisée. La source du timer est le quartz. Initialiser le Registre contenant la période

Initialiser le Registre contenant la période du Timerla valeur du Registre contenant la valeur du compteur à 0. UTBM – TR57 Automne 2006

Registres configurés :

T1CON=0X00;

TMR1=0;

PR1=7372;

Nous voulons utiliser l’interruption du Timer1 pour mettre à jour notre horloge

Effacer le Flag d'interruption du Timer1

IFS0bits.T1IF = 0;

Puis autoriser les interruptions du Timer1

IEC0bits.T1IE = 1 ;

La configuration du Timer1 est faite et il peut être lancé.

T1CONbits.TON=1 ;

4.2.2.1.2.

Timer3

La configuration est la même pour le Timer3 à la différence près que le temps est calculé pour avoir une fréquence d’échantillonnage de 2kHz. La configuration se fera dans un nouveau fichier appelé init_timer3.c.

L’interruption du Timer3 n’est pas utile lorsque nous utilisons ce Timer pour lancer la conversion ADC. Toutefois, afin de vérifier la fréquence des interruptions en simulation, nous pouvons autoriser l’interruption.

(Time_x=0,5ms, Fcy= (Fosc/4)*PLL4x=Fosc)

Pr

escaler =

Time

1

_

x

*

Fcy

PR 3 =

Pr escaler

=

0,5*10

- 3

*7,3728*10

6

=

[3686,4]

=

3686

=

0

x

0

E

66

<

0

xFFFF

4.2.2.2.Déclaration du prototype des fonctions

Penser à mettre le prototype de la fonction dans fonction.h afin que tous les fichiers associés au projet aient accès à cette fonction. Dans fonction.h void init_timer1(void) ; void init_timer3(void) ;

4.2.2.3.Ecriture des routines d’interruptions associées

4.2.2.3.1.

Timer1

L’interruption du Timer1 permettra de mettre à jour l’horloge du système, pour ce faire il faut incrémenter le compteur de milliseconde (msec) puis traiter les cas de figure selon que les msec soient supérieurs à 1000, que les secondes (sec) soient supérieures à 60, que les minutes (min) soient supérieure s à 60 et que les heures (heure) soient supérieure s à 24.

Cette interruption utilise des opérations d’addition et de comparaisons, c’est pour ces raisons qu’il faut sauvegarder le contexte de l’unité Arithmétique et Logique avant d’entrer dans la

routine d’interruption (déclaration de l’interruption avec l’attribut

) shadow

Nous profiterons aussi de cette interruption pour faire changer l’état de la LED RB0 toutes les secondes.

Il faut penser à ré-autoriser les interruptions sur Timer1 à la fin de la routine.

La routine d’interruption du Timer1 (init_timer1.c)

void

attribute

((

interrupt

,

shadow

))

_T1Interrupt(void)

{

 

msec++; if (msec >= 1000)

 

{

msec = 0;

 

sec++; LATBbits.LATB0 =~ LATBbits.LATB0;

if(sec>=60)

 

{

 

sec=0;

min++;

if (min >= 60)

 

{

min = 0; heure++;

 

if(heure>=24)

{

 

heure=0;

 

} //fin if(heure>=24) }//fin if (min >= 60) }//fin if(sec>=60) }//fin if (msec >= 1000) IFS0bits.T1IF = 0; //ré-autorisation des interruptions

}

Vous avez pu remarquer que l’interruption a besoin des variables msec, sec, min, heure. Ces variables étant globales au projet elle seront déclarées dans le fichier main.c. Il faut juste penser à les déclarer dans le fichier init_timer1.c en tant que variables externes.

4.2.2.3.2.

Timer3

L’interruption du Timer3 n’est pas utile lorsque nous utilisons ce Timer pour lancer la conversion ADC. Toutefois afin de vérifier la fréquence des interruptions en simulation, nous pouvons écrire la routine d’interruption.

Cette routine ré-autorise la prochaine interruption du Timer3.

La routine d’interruption du Timer3 (init_timer3.c)

void

{

attribute

((

interrupt

))

_T3Interrupt(void)

IFS0bits.T3IF = 0; //ré-autorisation des interruptions

}

4.2.2.4.Ecriture de la fonction principale (main.c)

Dans le fichier main.c, il faudra déclarer msec, sec, min, heure comme variable global type entier non signé.

e
e

de

unsigned int msec, sec, min, heure ;

La fonction principal main.c initialisera msec, sec, min, heure puis le port B0 comme port de sortie et enfin fera appel aux initialisations du Timer1 et Timer3.

fichier main.c

#include "define.h" unsigned int msec, sec, min, heure ; int main ( void ) {
#include "define.h"
unsigned int msec, sec, min, heure ;
int main ( void )
{
msec=0;
sec=0;
min=0;
heure=0;
LATBbits.LATB0 = 0;
init_timer1();
init_timer3();
while(1);
}

Compiler tout le projet pour la simulation (ctrl+F10)

4.2.3.

Simulation

Nous allons simuler le projet pour voir si les interruptions interviennent dans les temps impartis. Mettre un breakpoint dans l’interruption du Timer3, puis avec le module StopWatch vérifier que l’interruption intervient tous les

500µs.

Enlever le breakpoint au niveau de l’interruption du timer3 et ajouter un breakpoint au niveau de msec++ dans l’interruption du timer1, vérifier à nouveau que l’interruption intervient toutes les 1ms.

à nouveau que l’interruption intervient toutes les 1ms. Vous pouvez aussi visualiser les variations des variables

Vous pouvez aussi visualiser les variations des variables msec, sec, min, heure en appuyant sur F7

4.3. Gestion de l’UART

Le but de cette manipulation est de pouvoir réaliser une communication entre le microcontrôleur et des périphériques extérieurs (ordinateur, modem,…) via une liaison série

RS232.

Dans le répertoire (mplabide) joint au tutoriel, un projet gère l’affichage d’un menu et la saisie de données (dossier « menu »). Dans ce projet vous trouverez des fonctions permettant de transformer un nombre saisi au clavier en entier interprétable par le microcontrôleur (int buffer2nombre(void)). Le nombre saisi doit être entouré de deux balises 0x0D (retour chariot) (0x0D 0x31 0x32 0x33 0x0D = 123) Ce projet contient aussi une fonction permettant de transformer un entier compris entre 0 et 10 en une chaine de caractères (void i2a(int valeur, unsigned char *tab)). Ces fonctions ont été développées pour une application bien spécifique, à vous de les modifier à votre guise.

4.3.1. Avant propos

Le dsPIC30F comprend un UART Full Duplex de 8 ou 9bits. Les spécifications techniques sont :

Gestion de la parité Paire, Impair, Pas de Parité (transfert de donnée 8bits uniquement)Duplex de 8 ou 9bits. Les spécifications techniques sont : 1 ou 2 stop bits Générateur

1 ou 2 stop bitsPas de Parité (transfert de donnée 8bits uniquement) Générateur de Baud intégré Vitesse de transmission

Générateur de Baud intégré(transfert de donnée 8bits uniquement) 1 ou 2 stop bits Vitesse de transmission variant entre 29bps

Vitesse de transmission variant entre 29bps à 1,875 Mbps à une Fréquence Cycle Fcy de 30 MHzuniquement) 1 ou 2 stop bits Générateur de Baud intégré Les données reçues sont stockées dans

Les données reçues sont stockées dans un buffer First-In-First-Out (FIFO) d’une profondeur de 4 octets29bps à 1,875 Mbps à une Fréquence Cycle Fcy de 30 MHz Les données à émettre

Les données à émettre sont stockées dans un buffer First-In-First-Out (FIFO) d’une profondeur de 4 octetsFirst-In-First-Out (FIFO) d’une profondeur de 4 octets La détection des erreurs de parité, de fin de

La détection des erreurs de parité, de fin de trame (stop bit manquant) et de débordement des buffers sont intégrées au module.First-In-First-Out (FIFO) d’une profondeur de 4 octets Supporte la transmission de donnée 9 bits avec détection

Supporte la transmission de donnée 9 bits avec détection du mode adresse (9 è m e bit=1) ème bit=1)

Interruption de transmission et de réceptionPossibilité de connecter la broche de transmission sur la broche de réception pour diagnostic Registre

Possibilité de connecter la broche de transmission sur la broche de réception pour diagnosticInterruption de transmission et de réception Registre du module UART   U1MODE Bit 15 14 13

Registre du module UART

 

U1MODE

Bit

15

14

13

12

11

10

 

9 8

 

UARTEN

-

USIDL

-

-

ALTIO

 

- -

Bit

7

6

5

4

3

2

 

1 0

 

WAKE

LPBACK

ABAUD

-

-

PDSEL<1:0>

STSEL

UARTEN: Activation de l'UART

1

= UART est actif. Les pins RX et TX sont contrôlées par l'UART

0

= UART est inactif. Les pins RX et TX sont des I/O standard

USIDL: Opération en mode repos

1

= Arrêt des opérations en mode sommeil (SLEEP)

0

= Poursuite des opérations en mode sommeil (SLEEP)

ALTIO: Alternance des transmissions - réceptions

1 = l'UART utilise UxATX et UxARX alternativement en réception puis en émission

0 = l'UART utilise les pins UxTX and UxRX respectivement pour l'émission et pour la réception Attention cette fonctionnalité n'est pas disponible sur tous les PICs

WAKE: Action lorsqu'un Start bit est détecté en mode sommeil

1

= Réveil du µC

0

= Ne rien faire

LPBACK: La broche TX est branchée à la broche RX en interne

1

= activation du mode

0

= désactivation du mode

ABAUD: Activation de l'auto-détection de la vitesse de transfert en paramétrant l'unité de capture. L'unité doit capturer les fronts montant et descendant du bit de Start

1

= Input to Capture module from UxRX pin

0

= Input to Capture module from ICx pin

PDSEL<1:0>:Choix de la parité et du nombre de données transmises

11

= 9-bit data, pas de parité

10

= 8-bit data, parité pair

01

= 8-bit data, parité impair

00

= 8-bit data, pas de parité

STSEL: Choix du nombre de bits de stop

1

= 2 Stop bits

0

= 1 Stop bit

 

U1STA

 

Bit

15

14

13

12

11

10

9

8

 

UTXISEL

-

-

-

UTXBRK

UTXEN

UTXBF

TRMT

Bit

7

6

5

4

3

2

1

0

 

URXISEL<1:0>

ADDEN

RIDLE

PERR

FERR

OERR

URXDA

UTXISEL: Mode d'interruption sur transmission de caractère

1

= Une interruption intervient lorsqu'il y a un transfert du buffer de transmission au Transmit Shift register, par ce biais le buffer de transmission est vide.

0

= Une interruption est réalisée lorsqu'un caractère est transmis au Transmit Shift register, ce qui implique qu'au moins un caractère peut être ajouté dans le buffer de transmission

UTXBRK: Transmission d'un break

1

= Transmission d'un état '0' pendant un minimum de 13 cycle d'horloge

0

= La broche Tx fonctionne normalement

UTXEN: Autorisation des transmissions

1

= La pin UxTX est commandée par l'UART normalement

0

= Arrêt des transmissions, toutes les transmissions en cours sont arrêtées et les buffers sont réinitialisés. La broche Tx est contrôlée par la PORT.

UTXBF: Statut du buffer de Transmission (Lecture seul)

1

= Le buffer est plein

0

= Le buffer n'est pas plein, un minimum d'une donnée peut être écrit dans le buffer

TRMT: Statut du Transmit Shift Register (Lecture seul)

1

= Le Transmit shift register est vide et le buffer de transmission est vide

0

= Le Transmit shift register n'est pas vide, une transmission est en cours

URXISEL<1:0>: Mode d'interruption sur réception

11

= L'interruption intervient lorsque le buffer de réception est plein (4 données reçues)

10

= L'interruption intervient lorsque le buffer de réception est aux 3/4plein (3données reçues)

0x = L'interruption intervient lorsqu'un caractère est reçu

ADDEN: Détection du mode Adresse

1

= Le mode adresse est activé. Si la transmission de 9 caractères n'est pas sélectionnée ce bit n'a pas d'effet.

0

= Le mode d'adresse est inhibé

RIDLE: Réception en mode Idle (au repos) (Lecture seul)

1

= Le récepteur est en mode Idle

0

= Des données sont entrain d'être reçus

PERR: Flag Erreur de parité (Lecture seul)

1

= Une erreur de parité a été détectée sur le caractère courant

0

= Aucune erreur de parité n'a été détectée

FERR: Flag erreur de forme non détection du bit de stop (Lecture seul)

1

= Une erreur de forme a été détectée sur le caractère courant

0

= Aucune erreur de forme n'a été détectée

OERR: Flag erreur sur le buffer de réception (Lecture/effacement seul) Levé dans 3 cas:

1-

Le buffer de réception est plein

2-

Le Shift register de réception est plein et ne peut pas transférer les données au buffer de réception

3-

Le bit de stop du caractère dans UxRSR est détecté et indique que le caractère de UxRSR doit être transféré dans le buffer de réception

1

= Le buffer de réception a débordé

0

= Le buffer de réception n'a pas débordé

URXDA: Des données sont disponibles dans le buffer de réception (Lecture seule)

1

= Des données sont disponibles dans le buffer de réception

0

= Le buffer de réception est vide

La vitesse de transmission se calcule de la façon suivante

Soit

Vitesse de transmission =

Fcy

16(

UxBRG

+1)

UxBRG =

Fcy

16(

Vitesse de transmission

)

- 1

A.N. pour une vitesse de transmission de 9600bauds (Fcy= (Fosc/4)*PLL4x=Fosc)

UxBRG =

7 372 800 000

16(9600)

-

1

=

[47]

=

47

Vitesse de transmission réelle calculée

Vitesse de transmission =

7 372 800 000 =

16(47

+

1)

Erreur due à l’approximation

9600bauds

Erreur

%

Vitesse de transmission voulu - Vitesse de Transmission réelle

=

Vitesse de transmission voulu

9600 - 9600

=

9600

= 0%

4.3.2. Programmation

4.3.2.1.Initialisation de l’UART

Créer tout d’abord un fichier inclus dans le projet appelé init_uart.c.

Après avoir inclus le fichier define.h (#include "define.h"), commencer l’initialisation de l’UART.

Créer un sous-programme void init_uart(void) Suivre les étapes suivantes :

1. Arrêter l’UART

2. Configurer l’UART (8bits, parité pair, 1bit de stop)

3. Une interruption intervient quand le buffer de transmission est vide

4. Choisir la vitesse de transmission (9600bauds)

5. Effacer les flags d’interruption en émission et réception

6. Activer les interruptions en émission et réception

7. Activer l’UART

8. Activer la broche Tx

void init_uart(void)

{

U1MODE=0x0003;

U1STA=0x8000;

U1BRG=47;

//Efface le flag d'interruption en réception

IFS0bits.U1RXIF=0;

//Efface le flag d'interruption en émission

IFS0bits.U1TXIF=0;

//Autorisation des interruptions en réception

IEC0bits.U1RXIE=1;

//Autorisation des interruptions en émission

IEC0bits.U1TXIE=1;

// Activation de l'UART

U1MODEbits.UARTEN=1;

// Autorisation des transmissions

U1STAbits.UTXEN=1;

}

4.3.2.2.Déclaration du prototype de la fonction

Penser à mettre le prototype de la fonction dans fonction.h afin que tous les fichiers associés au projet aient accès à cette fonction. Dans fonction.h

void init_uart(void);

4.3.2.3.Ecriture des routines d’interruptions associées

Pour l’émission de caractère nous utiliserons la fonction printf. Cette dernière fait partie de la librairie de fonction compris dans <stdio.h> et gère automatiquement l’envoi de caractères à travers l’UART

L’interruption de transmission de l’UART sert uniquement à remettre le flag d’interruption à zéro.

void

attribute

((

interrupt

))

_U1TXInterrupt(void)

{

IFS0bits.U1TXIF=0;

}

L’interruption de réception de caractère permet de transférer les données reçus dans un buffer circulaire. Ce buffer circulaire sera par la suite traité dans différentes parties du programme. Cette interruption permet aussi de savoir s’il y a une erreur sur le bit reçu (erreur de parité, de forme ou si le buffer de réception est plein).

Voir l’algorithme suivant

.

de réception est plein). Voir l’algorithme suivant . UTBM – TR57 Automne 2006 – Eric OBSER

void

attribute

((

interrupt

,

shadow

))

_U1RXInterrupt(void)

{

if(nb_val>TAILLE_BUF)

{

erreur_RX.buffer_plein=1;

}

else

{

while(U1STAbits.URXDA==1)//tant qu'il y a des valeurs dans le buffer de réception on les stocke

{

if(U1STAbits.PERR==1)erreur_RX.parite=1;//test la parité if(U1STAbits.FERR==1)erreur_RX.forme=1;//test si bit de stop présent if(U1STAbits.OERR==1)erreur_RX.buffer_RXplein=1;//test si le buffer de réception est plein

if(erreur_RX.parite==0&erreur_RX.forme==0&erreur_RX.buffer_RXplein==0)

{

 

bufferRX[ptrW++]=U1RXREG;

if(ptrW>=TAILLE_BUF)

{

ptrW=0;

}

nb_val++;

}

else

{

 

erreur_RX.reception=1;

}

}

}

IFS0bits.U1RXIF=0;

}

4.3.2.4.Ecriture de la fonction principale (main.c)

Le programme principal attend indéfiniment si un caractère est reçu. Dès qu’un caractère est reçu, on renvoie sa valeur par le port série, ceci permet de faire une fonction d’écho.

Avant d’écrire la fonction main il faut déclarer certaines variables utiles.

La première est la définition de la taille du buffer de réception, puis il faut créer une structure traçant toutes les erreurs survenues pendant la phase de réception de caractère, par la suite il faut déclarer le buffer de réception puis les pointeurs (ptrW et ptrR) permettant de manipuler le buffer de réception et finalement le compteur nb_val permettant de savoir combien de valeurs sont présentes dans le buffer de réception. Dans la fonction main, nous initialiserons les variables nb_val, ptrW et ptrR à zéro puis ferons appel à la fonction d’initialisation de l’UART.

Le reste du programme principal est une boucle infinie qui affiche les caractères du buffer de réception.

#include "define.h" #define TAILLE_BUF 20 struct erreurRX_type { unsigned char parite; unsigned char forme;
#include "define.h"
#define TAILLE_BUF
20
struct erreurRX_type
{
unsigned char parite;
unsigned char forme;
unsigned char buffer_RXplein;
unsigned char buffer_plein;
unsigned char reception;
} erreur_RX;
unsigned char bufferRX[TAILLE_BUF];
int ptrW,ptrR,nb_val;
int main ( void )
{
//remise à zéros du compteur du nombre de valeur dans le buffer de réception
nb_val=0;
//remise à zéro du pointeur d'écriture dans le buffer de réception
ptrW=0;
//remise à zéro du pointeur de lecture dans le buffer de réception
ptrR=0;
init_uart();
printf("fonction d'echo\n\r");
while(1)
{
while(nb_val!=0)
{
nb_val--;
printf("caractere=%c\n\r",bufferRX[ptrR++]);
if(ptrR>=TAILLE_BUF)
{
ptrR=0;
}
}
}
}
L’utilisation de la fonction printf nécessite de
changer une option de compilation, pour ce faire
cliquer sur ProjectËBuild option ËProject. Dans
l’onglet MPLAB LINK 30, ajouter 512 à la valeur
de HEAP SIZE puis cliquer sur OK
Compiler le projet (ctrl+F10)
UTBM – TR57 Automne 2006 – Eric OBSER & Vincent HAEGELIN – dSPIC30F4011 & PICOS 30
35

4.3.3. Simulation

MPLAB IDE ne gère pas très bien la simulation de l’UART. Toutefois un module existe. Créer tout d’abord un fichier texte dans vote répertoire de projet appelé entree_uart.txt. Ce fichier comprendra toutes les entrées que vous voulez soumettre à votre UART. Attention ne taper que des chiffres représentant des nombres hexadécimaux.

Pour exemple si vous tapez 0F, lors de la simulation le caractère reçu aura pour valeur 0x0F.

Utilisez la table ASCII pour connaître les combinaisons hexadécimales des caractères que vous voulez envoyer.

hexadécimales des caractères que vous voulez envoyer. Pour lors le fichier entree_uart.txt comprend les valeurs

Pour lors le fichier entree_uart.txt comprend les valeurs suivantes :

30 31 32 33 34 35 36 37 38 39

Choisir le simulateur MPLAB SIM, puis cliquer Debugger ËSettings. Dans l’onglet UART IO cliquer sur Enable UART1 IO. Cliquer sur Browse et entrer le chemin du fichier entree_uart.txt. Rewind Input permet de lire en boucle le fichier texte.

Dans Output cliquer sur Window. Un afficheur sera disponible en cliquant ViewËOutput, onglet SIM UART1. Sinon cliquer sur file et donner un nom de fichier recueillant les sorties de l’UART.

un nom de fichier recueillant les sorties de l’UART. UTBM – TR57 Automne 2006 – Eric

Maintenant que vous avez initialisé la liaison série, vous pouvez lancer le programme et passer aux phases de vérification avec des breakpoints. Mettre des breakpoints dans les interruptions pour vérifier l’envoi de caractères ainsi que le remplissage du buffer de réception. Si vous ne mettez aucun breakpoint vous devriez voir dans la fenêtre SIM UART1 le résultat suivant.

Ce programme peut aussi être testé sur la carte dsPICDEM2. Attention il faut mettre deux cavaliers sur H3 MALL et enlever les cavaliers sur H4 MALL.

Utiliser un câble droit et configurer l’Hyperterminal avec la configuration que vous avez donnée à la liaison soit dans notre cas 8bits, parité paire, 1bit de stop, 9600bauds.

La carte doit afficher les caractères que vous tapez au clavier.

4.4. Gestion de la PWM

4.4.1. Avant propos

tapez au clavier. 4.4. Gestion de la PWM 4.4.1. Avant propos Les modules PWM sont utilisés

Les modules PWM sont utilisés dans tout ce qui est commande de moteur. (Moteur triphasé, Moteur à courant continu, Moteur DC Brushless,…).

Les principales caractéristiques du module PWM :

Chaque PWM possède 2 sorties PWMxL/PWMxH Les sorties peuvent être complémentaires ou indépendantes Il est possible de gérer des temps morts
Les sorties peuvent être complémentaires ou indépendantes Chaque PWM possède 2 sorties PWMxL/PWMxH Il est possible de gérer des temps morts entre les
Il est possible de gérer des temps morts entre les broches PWMxL et PWMxH Les sorties peuvent être complémentaires ou indépendantes La polarité des broches PWM peut être programmée
La polarité des broches PWM peut être programmée de gérer des temps morts entre les broches PWMxL et PWMxH Différents mode de fonctionnement du
Différents mode de fonctionnement du compteur PWM et PWMxH La polarité des broches PWM peut être programmée Mode compteur Mode compteur décompteur Mode
Mode compteur Différents mode de fonctionnement du compteur PWM Mode compteur décompteur Mode compteur décompteur avec la
Mode compteur décompteur mode de fonctionnement du compteur PWM Mode compteur Mode compteur décompteur avec la possibilité de rafraichir
Mode compteur décompteur avec la possibilité de rafraichir rafraîchir le rapport cyclique à la moitié de la période du compteur PWM Mode compteur Mode compteur décompteur Mode compteur mono coup Programmation d’événements
Mode compteur mono coup Programmation d’événements pouvant synchroniser une conversion ADCMode compteur décompteur avec la possibilité de rafraichir rafraîchir le rapport cyclique à la moitié de

Les registres du module PWM

 

PTCON

Bit

15

14

13

12

11

10

 

9 8

 

PTEN

-

PTSIDL

-

-

-

- -

 

Bit

7

6

5

4

3

2

 

1 0

   

PTOPS<3:0>

PTCKPS<1:0>

PTMOD<1:0>

PTEN: arrête la base de temps de la PWM

1

= La base de temps est activée

0

= La base de temps est désactivée

PTSIDL: Etat de fonctionnement du module PWM en Idle Mode

1

= La base de temps du module est arrêtée en Idle Mode

0

= La base de temps du module fonctionne en Idle Mode

PTOPS<3:0>: A chaque fin de cycle de comptage une interruption peut être déclenchée.

Ce registre permet de définir le nombre de cycles de comptage avant que l'interruption ne soit déclenchée.

1111

= 1:16 Postscale

0001

= 1:2 Postscale

0000

= 1:1 Postscale

PTCKPS<1:0>: Prescaler d'entrée de la base de temps de la PWM

11

= PWM time base input clock period is 64 TCY (1:64 prescale)

10

= PWM time base input clock period is 16 TCY (1:16 prescale)

01

= PWM time base input clock period is 4 TCY (1:4 prescale)

00

= PWM time base input clock period is TCY (1:1 prescale)

PTMOD<1:0>: Mode de fonctionnement de la PWM

11 = La base de temps fonctionne en mode compteur-décompteur continu. Une interruption

est générée à la fin du cycle et au milieu du cycle permettant de réaliser une mise à jour du registre PDCx (=duty cycle)

10 = La base de temps fonctionne en mode compteur-décompteur continu. Une interruption

est générée à la fin de cycle permettant de réaliser une mise à jour du registre PDCx (=duty cycle) voir aussi le registre PTOPS

01 = La base de temps fonctionne uniquement sur un cycle. A la fin du cycle une interruption

est générée et le bit PTEN passe à 0

00 = La base de temps fonctionne en mode compteur continu. Une interruption est générée à

la fin de cycle permettant de réaliser une mise a jour du registre PDCx (=duty cycle) voir aussi le registre PTOPS

 

PWMCON2

 

Bit

15

14

13

12

11

10

9

8

 

-

-

-

-

 

SEVOPS<3:0>

Bit

7

6

5

4

3

2

1

0

 

-

-

-

-

-

IUE

OSYNC

UDIS

< SEVOPS> Post Scaler sur les Evénements PWM (signal de lancement ADC)

= 1111 1:16 Postcal

= 0001 1:2 Postcal

= 0000 1:1 Postcal

IUE

=

1 rafraîchissement du Duty cycle (PDC) immédiatement

=

0 rafraîchissement du Duty cycle (PDC) sur chaque période PWM

OSYNC

UDIS

= 1 écriture sur les sorties par OVDCON synchronisé par le cycle PWM

= 0 écriture sur les sorties par OVDCON au prochain cycle machine Tcy

= 1 Le rafraîchissement du temps de cycle (PDC) and du buffer (PTPER) est inhibé

= 0 Le rafraîchissement du temps de cycle (PDC) and du buffer (PTPER) est possible

 

DTCON1

 

Bit

15

14

13

12

11

10

9 8

 
 

-

-

-

-

-

-

- -

 

Bit

7

6

5

4

3

2

 

1 0

 

DTAPS<1:0>

 

DTA<5:0>

DTAPS Prescaler Value pour DTB

11

: Prescaler de 8Tcy

10

: Prescaler de 4Tcy

01

: Prescaler de 2Tcy

00

: Prescaler de Tcy

DTA Dead Time A DTA=(DeadTime*Fcy/(Prescaler_Value) Exemple 1µs DTA=(1e-6*7 372 800 000)/1=[7,3728]=0x7=00111(b)

Les temps-morts sont automatiquement mis en marche lorsque les sorties PWM sont

commandées

en

mode

complémentaire

pour

des

raisons

de

commutation

des

circuits

électroniques.

Explication des différents modes Mode comptage continu :

Explication des différents modes Mode comptage continu : Mode comptage continu mono coup : UTBM –
Mode comptage continu mono coup :
Mode comptage continu mono coup :
Mode comptage continu : Mode comptage continu mono coup : UTBM – TR57 Automne 2006 –
Mode comptage décomptage continu : PTPER est le registre gérant le temps de cycle de

Mode comptage décomptage continu :

Mode comptage décomptage continu : PTPER est le registre gérant le temps de cycle de la

PTPER est le registre gérant le temps de cycle de la PWM

En mode comptage continu et comptage mono coup :

PTPER =

Fcy

Fpwm

*

PTMR

_

prescaler

- 1

En mode comptage décomptage continu :

PTPER =

Fcy

2*

Fpwm

*

PTMR

_

prescaler

- 1

Les registres PDCx contiennent la valeur du Duty cycle.

En mode comptage continu :

Duty

_

cycle

=

PTPER

-

PDCx

% PTPER

Attention en mode comptage-décomptage continu si PDCx=PTPER cela donne un Duty

Cycle de 50% et non de 100%.

Duty

_

cycle

=

2* PTPER

-

PDCx

% PTPER

Ceci n’est pas spécifié dans la documentation Microchip

4.4.2. Programmation

4.4.2.1.Initialisation du module PWM Créer tout d’abord un fichier inclus dans le projet appelé init_pwm.c.

Après avoir inclus le fichier define.h (#include "define.h"), commencer l’initialisation de l’UART.

Créer un sous programme void init_pwm(void) Suivre les étapes suivantes :

1. Arrêter le compteur PWM

2. Configurer la PWM en mode comptage décomptage continu. Une interruption par cycle