Taille: 3182
Commentaire:
|
Taille: 10479
Commentaire:
|
Texte supprimé. | Texte ajouté. |
Ligne 1: | Ligne 1: |
== Présentation == | == Présentation == |
Ligne 3: | Ligne 3: |
Un fichier de présentation un peu général à été rédigé par M. Juton et est disponible ici: [[attachment:Creation_projet_MCUXPRESSOIDE.pdf]]. | |
Ligne 6: | Ligne 7: |
== LED == | == LED == La LED est l'élément de base pour sortir un info basique sur ce que fait le programme. Comme toutes les entrées sortie, il faut définir le sens avec la variable {{{DIR0}}}. Pour une LED, il faut la positionner sur sortie sur 1. Le registre {{{LPC_GPIO_PORT -> DIR0}}} regroupe les directions pour toutes les entrées sortie. Il faut donc faire un OU logique avec la variable {{{blue (1<<11)}}} qui est un 1 décalé de 11 bits, ce qui correspond à la LED Bleu. {{{ #include <cr_section_macros.h> #include <LPC8xx.h> #include <syscon.h> //bits de GPIO utilises #define blue (1<<11) int main(void){ int cpt; LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON GPIO0); LPC_GPIO_PORT -> DIR0 |= blue; while(1){ LPC_GPIO_PORT -> PIN0 ^= blue; // OU exclusif pour changé l'état de la LED for(cpt=0;cpt<200000;cpt++); // temporisation sale pour attendre a peu pres 1s } } }}} |
Ligne 9: | Ligne 31: |
Lancer des commandes, c'est bien. Mais récuperer un peu d'interraction avec l'utilisateur, c'est mieux ! Le plus simple pour cela est d'utiliser les boutons. La carte de base en comporte 3 (dont un reset qui peut à tout moment "griller" votre carte donc on va dire 2...). Ils sont monté selon un schéma spécial qui fait que tout appuis sur un bouton allume directement la LED associée (basiquement, chaque LED est en série avec un bouton). L'utilisation des boutons, comme toutes les I/O du GPIO, se fait au travers du registre {{{LPC_GPIO_PORT}}}. {{{ #include <cr_section_macros.h> #include <LPC8xx.h> #include <syscon.h> //bits de GPIO utilises #define button (1<<13) int main(void){ int cpt; LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON GPIO0); while(1){ if ((LPC_GPio_PORT -> PIN0 & button)==0){ // le bouton est enfoncé // Des instructions... } else{ // il ne l'est pas // Encore des instructions... } // Toujours des instructions... } } }}} D'autres boutons sont utilisables avec l'extension de la carte mais il sont définit dans les header fournit avec. |
|
Ligne 14: | Ligne 64: |
L'écran LCD est présente sur les extensions de carte pour le LPC804. Son utilisation est assez simple et il fait l'objet d'une petite partie du TP3 dans laquelle on s’intéresse à l'espace mémoire occupé par la fonction {{{sprintf}}}. De plus , il peut servir d'affichage très rudimentaire pour le debug (si on à pas envi d'utiliser la console de mcuxpresso ni la visualisation des variables). === code === Voici un code simple d'utlisation de l'écran LCD. D'autres fonctions sont disponibles. {{{#!highlight C #include "lib_UE441_lcd.h" // contient les fonctions utiles pour l'utilisation de l'écran int main(void) { char text[32];// contiendra le texte à afficher init_lcd(); lcd_position(0,0); // on positionne le curseur au début (ligne,colonne). 16 colonne sur l'écran. sprintf(text,"\O_O/ \O_O/ \O_O/");// formate la chaîne pour l'affichage et le stocke dans text lcd_puts(text);// affiche le texte lcd_position(1,0);// seconde ligne lcd_puts("Second line bitch !");// On est pas obligé d'utiliser la fonction sprintf si le texte est simple while(1); // si on attend pas, on verra rien return 0 ; } }}} |
|
Ligne 16: | Ligne 88: |
=== Par bouton === | |
Ligne 18: | Ligne 91: |
=== code === {{{ |
{{{#!highlight C |
Ligne 89: | Ligne 160: |
=== Par Timer === Voila pour les interruptions par bouton. Mais on peut également faire des interruption par timer comme explicité dans le code suivant: {{{#!highlight C #include <cr_section_macros.h> #include <stdio.h> #include "LPC8xx.h" #include "fro.h" #include "rom_api.h" #include "syscon.h" #include "swm.h" #include "i2c.h" #include "ctimer.h" #include "core_cm0plus.h" #include "lib_UE441_lcd.h" //periode en ms des notes de la gamme LA440 #define P_DO 3822 #define P_RE 3405 #define P_MI 3033 #define P_FA 2862 #define P_SOL 2550 #define P_LA 2271 #define P_SI 2024 #define P_DOA 1911 int Gamme[8]={P_DO,P_RE,P_MI,P_FA,P_SOL,P_LA,P_SI,P_DOA}; //boutons et leds de la carte #define BP1 LPC_GPIO_PORT->B0[13] #define BP2 LPC_GPIO_PORT->B0[12] #define LED1 LPC_GPIO_PORT->B0[19] //utilisée ici en PWM #define LED2 LPC_GPIO_PORT->B0[17] #define LED3 LPC_GPIO_PORT->B0[21] #define LED4 LPC_GPIO_PORT->B0[11] volatile int temps=0; // temps actuel qui descend toute les secondes volatile int total=1; // temps total de seconde que l'on doit compter volatile int prochain=1; // Prochain nombre de seconde que l'on comptera int main(void) { char text[32]; //text utilisé pour l'afficheur LCD //Configuration de l'horloge a 15 MHz LPC_PWRD_API->set_fro_frequency(30000); // Peripheral reset to the GPIO0 and pin interrupt modules. '0' asserts, '1' deasserts reset. LPC_SYSCON->PRESETCTRL0 &= (GPIO0_RST_N & GPIOINT_RST_N); LPC_SYSCON->PRESETCTRL0 |= ~(GPIO0_RST_N & GPIOINT_RST_N); //Mise en fonctionnement des peripheriques utilises LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON | GPIO0 | SWM | CTIMER0 | GPIO_INT); //initialisation de l'affichuer lcd init_lcd(); // Configuration de l'interruption pour le bouton comme precedement LPC_GPIO_PORT->DIR0 |= (1<<19)|(1<<17)|(1<<21)|(1<<11); LPC_SYSCON->PINTSEL[1] = 12; // PINTSEL1 is P0.12 LPC_PIN_INT->ISEL = 0x0; LPC_PIN_INT->IENF = 0x3; LPC_PIN_INT->IST = 0xFF; NVIC_EnableIRQ(PININT1_IRQn); // config priority. De base elles sont prioritaires NVIC->IP[6]= (0<<6)|(3<<14); // configuration du SysTick Timer SysTick -> CTRL |= (1<<0); // active le timer SysTick -> LOAD = 0xb71aff; // compte a peu pres une seconde SysTick -> CTRL |= (1<<1); // active les interruptions par le SysTick //Affichage du texte de base qui restera sur l'ecran LCD. sprintf(text,"Temps: ",temps,total); lcd_position(0,0); lcd_puts(text); sprintf(text,"Prochain: ",temps,total); lcd_position(1,0); lcd_puts(text); while(1) { // efface l'espace des infos sprintf(text," ",prochain); lcd_position(0,7); lcd_puts(text); sprintf(text," ",prochain); lcd_position(1,10); lcd_puts(text); // affichage les nouvelles infos sprintf(text,"%u sur %u ",temps,total); lcd_position(0,8); lcd_puts(text); sprintf(text,"%u",prochain); lcd_position(1,10); lcd_puts(text); } return 0 ; } //Interruption du timer void SysTick_Handler(void){ temps++; // incremente le nombre de seconde if(temps>=total){// on est arrive a la fin du temps LED1= !LED1; // la LED change temps=0; // le compte revient a 0 total=prochain; // on prend en compte le prochain temps } } //Interruption du bouton void PININT1_IRQHandler(void){ prochain=(prochain+1) % 20; //Incrmentation du prochain temps pris en compte LPC_PIN_INT->FALL = 1<<1; // Efface l'interruption return; } }}} |
Présentation
Cette page à pour but de répertorier des exemples de code utiles pour les TP (et pour le partiel) de l'UE441 du M1 IST de EEA. Vous pouvez évidement contribuer à cette page mais assurez vous de rajouter du code compréhensible (commentaire, nom de variable explicite etc), fonctionnelle, et bien répertorié (cette page à des sections, respectez les). Un fichier de présentation un peu général à été rédigé par M. Juton et est disponible ici: Creation_projet_MCUXPRESSOIDE.pdf.
Code de base
LED
La LED est l'élément de base pour sortir un info basique sur ce que fait le programme. Comme toutes les entrées sortie, il faut définir le sens avec la variable DIR0. Pour une LED, il faut la positionner sur sortie sur 1. Le registre LPC_GPIO_PORT -> DIR0 regroupe les directions pour toutes les entrées sortie. Il faut donc faire un OU logique avec la variable blue (1<<11) qui est un 1 décalé de 11 bits, ce qui correspond à la LED Bleu.
#include <cr_section_macros.h> #include <LPC8xx.h> #include <syscon.h> //bits de GPIO utilises #define blue (1<<11) int main(void){ int cpt; LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON GPIO0); LPC_GPIO_PORT -> DIR0 |= blue; while(1){ LPC_GPIO_PORT -> PIN0 ^= blue; // OU exclusif pour changé l'état de la LED for(cpt=0;cpt<200000;cpt++); // temporisation sale pour attendre a peu pres 1s } }
Boutons
Lancer des commandes, c'est bien. Mais récuperer un peu d'interraction avec l'utilisateur, c'est mieux ! Le plus simple pour cela est d'utiliser les boutons. La carte de base en comporte 3 (dont un reset qui peut à tout moment "griller" votre carte donc on va dire 2...). Ils sont monté selon un schéma spécial qui fait que tout appuis sur un bouton allume directement la LED associée (basiquement, chaque LED est en série avec un bouton).
L'utilisation des boutons, comme toutes les I/O du GPIO, se fait au travers du registre LPC_GPIO_PORT.
#include <cr_section_macros.h> #include <LPC8xx.h> #include <syscon.h> //bits de GPIO utilises #define button (1<<13) int main(void){ int cpt; LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON GPIO0); while(1){ if ((LPC_GPio_PORT -> PIN0 & button)==0){ // le bouton est enfoncé // Des instructions... } else{ // il ne l'est pas // Encore des instructions... } // Toujours des instructions... } }
D'autres boutons sont utilisables avec l'extension de la carte mais il sont définit dans les header fournit avec.
Timers
Ecran LCD
L'écran LCD est présente sur les extensions de carte pour le LPC804. Son utilisation est assez simple et il fait l'objet d'une petite partie du TP3 dans laquelle on s’intéresse à l'espace mémoire occupé par la fonction sprintf. De plus , il peut servir d'affichage très rudimentaire pour le debug (si on à pas envi d'utiliser la console de mcuxpresso ni la visualisation des variables).
code
Voici un code simple d'utlisation de l'écran LCD. D'autres fonctions sont disponibles.
1 #include "lib_UE441_lcd.h" // contient les fonctions utiles pour l'utilisation de l'écran
2
3 int main(void) {
4 char text[32];// contiendra le texte à afficher
5
6 init_lcd();
7 lcd_position(0,0); // on positionne le curseur au début (ligne,colonne). 16 colonne sur l'écran.
8 sprintf(text,"\O_O/ \O_O/ \O_O/");// formate la chaîne pour l'affichage et le stocke dans text
9 lcd_puts(text);// affiche le texte
10 lcd_position(1,0);// seconde ligne
11 lcd_puts("Second line bitch !");// On est pas obligé d'utiliser la fonction sprintf si le texte est simple
12 while(1); // si on attend pas, on verra rien
13
14 return 0 ;
15 }
Interruptions
Par bouton
Le principe des intéruptions est que l'on va assigner une pine à un type d'interuption et on va lui donner une priorité. Si l’événement attendu survient (input, timer, etc), une certaine fonction va être appelée et l'on va interrompre le programme principale. Un des intérêt est que les interruptions sont gérées à un niveau plus bas et les sont donc beaucoup plus rapidement prise en compte que si l'on vérifiais l’appui sur un bouton. En contre partie, c'est chiant à coder.
1 int main(void) {
2
3 char text[32];
4 uint32_t i;
5
6 //Configuration de l'horloge à 15 MHz
7 LPC_PWRD_API->set_fro_frequency(30000);
8
9 // Peripheral reset to the GPIO0 and pin interrupt modules. '0' asserts, '1' deasserts reset.
10 LPC_SYSCON->PRESETCTRL0 &= (GPIO0_RST_N & GPIOINT_RST_N);
11 LPC_SYSCON->PRESETCTRL0 |= ~(GPIO0_RST_N & GPIOINT_RST_N);
12
13 //Mise en fonctionnement des périphériques utilisés
14 LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON | GPIO0 | SWM | CTIMER0 | GPIO_INT);
15
16 //initialisation de l'affichuer lcd avec un affichage
17 init_lcd();
18 sprintf(text,"Waiting...");
19 lcd_gohome();
20 lcd_puts(text);
21
22 // Configuration des interruptions sur front descendant des boutons
23
24 // Configure P0.18, P0.19 as pin interrupts 1, 0
25 // Make PORT0.18, PORT0.19 outputs driving '0'.
26 LPC_GPIO_PORT->DIR0 |= (1<<19)|(1<<17)|(1<<21)|(1<<11);
27
28 // Configure P0.18 - P0.19 as pin interrupts 1 - 0 by writing to the PINTSELs in SYSCON
29 LPC_SYSCON->PINTSEL[0] = 13; // PINTSEL0 is P0.13
30 LPC_SYSCON->PINTSEL[1] = 12; // PINTSEL1 is P0.12
31
32 // Configure the Pin interrupt mode register (a.k.a ISEL) for edge-sensitive on PINTSEL1,0
33 LPC_PIN_INT->ISEL = 0x0;
34
35 // Configure the IENR (pin interrupt enable rising) for rising edges on PINTSEL0,1
36 //LPC_PIN_INT->IENR = 0x0;
37
38 // Configure the IENF (pin interrupt enable falling) for falling edges on PINTSEL0,1
39 LPC_PIN_INT->IENF = 0x3;
40
41 // Clear any pending or left-over interrupt flags
42 LPC_PIN_INT->IST = 0xFF;
43
44 // Enable pin interrupts 0 - 1 in the NVIC (see core_cm0plus.h)
45 NVIC_EnableIRQ(PININT0_IRQn);
46 NVIC_EnableIRQ(PININT1_IRQn);
47
48 // config priority. De base elles sont prioritaires mais on refefinit leurs priorites
49 NVIC->IP[6]= (0<<6)|(3<<14);
50
51 while(1) {
52 // affichage du timer sur l'écran LCD
53 sprintf(text," %d ",i++);
54 lcd_position(1,1);
55 lcd_puts(text);
56 }
57 return 0 ;
58 }
59
60 //fonction interruption 0 GPIO sur front descendant
61 void PININT0_IRQHandler(void){
62 LED1= !LED1; // Falling edge on PIN INT0, LED off
63 LPC_PIN_INT->FALL = 1<<0; // Clear the interrupt flag
64 return;
65 }
66
67 }
Par Timer
Voila pour les interruptions par bouton. Mais on peut également faire des interruption par timer comme explicité dans le code suivant:
1 #include <cr_section_macros.h>
2 #include <stdio.h>
3 #include "LPC8xx.h"
4 #include "fro.h"
5 #include "rom_api.h"
6 #include "syscon.h"
7 #include "swm.h"
8 #include "i2c.h"
9 #include "ctimer.h"
10 #include "core_cm0plus.h"
11
12 #include "lib_UE441_lcd.h"
13
14 //periode en ms des notes de la gamme LA440
15 #define P_DO 3822
16 #define P_RE 3405
17 #define P_MI 3033
18 #define P_FA 2862
19 #define P_SOL 2550
20 #define P_LA 2271
21 #define P_SI 2024
22 #define P_DOA 1911
23 int Gamme[8]={P_DO,P_RE,P_MI,P_FA,P_SOL,P_LA,P_SI,P_DOA};
24
25 //boutons et leds de la carte
26 #define BP1 LPC_GPIO_PORT->B0[13]
27 #define BP2 LPC_GPIO_PORT->B0[12]
28 #define LED1 LPC_GPIO_PORT->B0[19] //utilisée ici en PWM
29 #define LED2 LPC_GPIO_PORT->B0[17]
30 #define LED3 LPC_GPIO_PORT->B0[21]
31 #define LED4 LPC_GPIO_PORT->B0[11]
32
33 volatile int temps=0; // temps actuel qui descend toute les secondes
34 volatile int total=1; // temps total de seconde que l'on doit compter
35 volatile int prochain=1; // Prochain nombre de seconde que l'on comptera
36
37 int main(void) {
38 char text[32]; //text utilisé pour l'afficheur LCD
39
40 //Configuration de l'horloge a 15 MHz
41 LPC_PWRD_API->set_fro_frequency(30000);
42
43 // Peripheral reset to the GPIO0 and pin interrupt modules. '0' asserts, '1' deasserts reset.
44 LPC_SYSCON->PRESETCTRL0 &= (GPIO0_RST_N & GPIOINT_RST_N);
45 LPC_SYSCON->PRESETCTRL0 |= ~(GPIO0_RST_N & GPIOINT_RST_N);
46
47 //Mise en fonctionnement des peripheriques utilises
48 LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON | GPIO0 | SWM | CTIMER0 | GPIO_INT);
49
50 //initialisation de l'affichuer lcd
51 init_lcd();
52
53 // Configuration de l'interruption pour le bouton comme precedement
54 LPC_GPIO_PORT->DIR0 |= (1<<19)|(1<<17)|(1<<21)|(1<<11);
55 LPC_SYSCON->PINTSEL[1] = 12; // PINTSEL1 is P0.12
56 LPC_PIN_INT->ISEL = 0x0;
57 LPC_PIN_INT->IENF = 0x3;
58 LPC_PIN_INT->IST = 0xFF;
59 NVIC_EnableIRQ(PININT1_IRQn);
60
61 // config priority. De base elles sont prioritaires
62 NVIC->IP[6]= (0<<6)|(3<<14);
63
64 // configuration du SysTick Timer
65 SysTick -> CTRL |= (1<<0); // active le timer
66 SysTick -> LOAD = 0xb71aff; // compte a peu pres une seconde
67 SysTick -> CTRL |= (1<<1); // active les interruptions par le SysTick
68
69 //Affichage du texte de base qui restera sur l'ecran LCD.
70 sprintf(text,"Temps: ",temps,total);
71 lcd_position(0,0);
72 lcd_puts(text);
73 sprintf(text,"Prochain: ",temps,total);
74 lcd_position(1,0);
75 lcd_puts(text);
76
77 while(1) {
78 // efface l'espace des infos
79 sprintf(text," ",prochain);
80 lcd_position(0,7);
81 lcd_puts(text);
82 sprintf(text," ",prochain);
83 lcd_position(1,10);
84 lcd_puts(text);
85
86 // affichage les nouvelles infos
87 sprintf(text,"%u sur %u ",temps,total);
88 lcd_position(0,8);
89 lcd_puts(text);
90 sprintf(text,"%u",prochain);
91 lcd_position(1,10);
92 lcd_puts(text);
93 }
94 return 0 ;
95 }
96
97 //Interruption du timer
98 void SysTick_Handler(void){
99 temps++; // incremente le nombre de seconde
100
101 if(temps>=total){// on est arrive a la fin du temps
102 LED1= !LED1; // la LED change
103 temps=0; // le compte revient a 0
104 total=prochain; // on prend en compte le prochain temps
105 }
106 }
107
108 //Interruption du bouton
109 void PININT1_IRQHandler(void){
110 prochain=(prochain+1) % 20; //Incrmentation du prochain temps pris en compte
111 LPC_PIN_INT->FALL = 1<<1; // Efface l'interruption
112 return;
113
114 }