== 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). == Code de base == == LED == == Boutons == == 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'interesse a l'espace mémoire occupé par la fonction {{{sprintf}}}. De plus , il peut servir ed'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. {{{ #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 ; } }}} == Interruptions == 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. === code === {{{ int main(void) { char text[32]; uint32_t i; //Configuration de l'horloge à 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 périphériques utilisés LPC_SYSCON->SYSAHBCLKCTRL0 |= (IOCON | GPIO0 | SWM | CTIMER0 | GPIO_INT); //initialisation de l'affichuer lcd avec un affichage init_lcd(); sprintf(text,"Waiting..."); lcd_gohome(); lcd_puts(text); // Configuration des interruptions sur front descendant des boutons // Configure P0.18, P0.19 as pin interrupts 1, 0 // Make PORT0.18, PORT0.19 outputs driving '0'. LPC_GPIO_PORT->DIR0 |= (1<<19)|(1<<17)|(1<<21)|(1<<11); // Configure P0.18 - P0.19 as pin interrupts 1 - 0 by writing to the PINTSELs in SYSCON LPC_SYSCON->PINTSEL[0] = 13; // PINTSEL0 is P0.13 LPC_SYSCON->PINTSEL[1] = 12; // PINTSEL1 is P0.12 // Configure the Pin interrupt mode register (a.k.a ISEL) for edge-sensitive on PINTSEL1,0 LPC_PIN_INT->ISEL = 0x0; // Configure the IENR (pin interrupt enable rising) for rising edges on PINTSEL0,1 //LPC_PIN_INT->IENR = 0x0; // Configure the IENF (pin interrupt enable falling) for falling edges on PINTSEL0,1 LPC_PIN_INT->IENF = 0x3; // Clear any pending or left-over interrupt flags LPC_PIN_INT->IST = 0xFF; // Enable pin interrupts 0 - 1 in the NVIC (see core_cm0plus.h) NVIC_EnableIRQ(PININT0_IRQn); NVIC_EnableIRQ(PININT1_IRQn); // config priority. De base elles sont prioritaires mais on refefinit leurs priorites NVIC->IP[6]= (0<<6)|(3<<14); while(1) { // affichage du timer sur l'écran LCD sprintf(text," %d ",i++); lcd_position(1,1); lcd_puts(text); } return 0 ; } //fonction interruption 0 GPIO sur front descendant void PININT0_IRQHandler(void){ LED1= !LED1; // Falling edge on PIN INT0, LED off LPC_PIN_INT->FALL = 1<<0; // Clear the interrupt flag return; } } }}} Voila pour les interruptions par bouton. Mais on peut également faire des interruption par timer comme explicité dans le code suivant: {{{ #include #include #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; } }}}