Interruptions événement aléatoire ou programmé static void interrupt Nom_SPint() void main(void) 1) saut { + sauve contexte if(RB3==1) sur pile { TRISD=0x04; while(1) PORTD I= 0x10; 2) exécution du S-P { else PORTD^=1; } } cours normal du programme PORTD=0x20; 3 ) retour + ….;de pile récupère contexte } sauvegarde PC + sauvegarde environne mémoire de données ( pile à 8 niveaux chargement Mémoire de événement aléatoire données ou programmé adresse S-P I saut déroulement programme Mémoire de programme (1 & 2) 14 sources d’interruption (pic16f877) #include<htc.h> __CONFIG(WDTE_OFF & FOSC_HS); void main(void) { GIE=1; // registre INTCON T0IE=1; // registre INTCON OPTION_REG=0x01; TRISD=0x04; TMR0=5; while(1) { PORTD^=1; } } static void interrupt test_int() { if( T0IF ==1 && T0IE==1) { if(RB3==1) PORTD |= 0x10; else PORTD=0x20; } TMR0=5; T0IF=0; } 1 2 b a 3 4 c Exemple de code void main(void) static void interrupt test_int() { { GIE=1; // registre INTCON if( T0IF ==1 && T0IE==1) T0IE=1; // registre INTCON { OPTION_REG=0x01; if(RB3==1) TRISD=0x04; PORTD I= 0x10; TMR0=5; else while(1) PORTD=0x20; { } PORTD^=1; TMR0=5; } } T0IF=0; } Watchdog • horloge indépendante basée sur des composants RC internes , • pas de composants externes. Fonctionne indépendamment de l’horloge principale => watchdog fonctionne même lorsque le processeur est en mode sommeil, (instruction SLEEP). • Si le microcontrôleur est en mode normal, le watchdog génère un RESET du microcontrôleur (au bout de 18 ms). • Si le microcontrôleur est en mode SLEEP, le débordement du watchdog générera un réveil du microcontrôleur Le watchdog peut être désactivé en mettant à 0 le bit de configuration WDTE (adresse 0x2007) __CONFIG(WDTE_OFF); CLRWDT et SLEEP réinitialiser le registre WDT et prévient donc débordement et ainsi le RESET #include<htc.h> void main (void) { #include<htc.h> int i; void main (void) TRISD=0; { while(1) TRISD=0; { while(1) reset par Watchdog toutes les 18 ms!!!! for (i=0;i<500/15;i++) { { __delay_ms(500); __delay_ms(15); RD0^=1; CLRWDT; } } } RD0^=1; désactivation du reset pour les 18 prochaines ms } } Conversion analogique / numérique En interruption : 4 registres : • ADCON0 • bits d’autorisation : ADIE, GIE et PEIE • drapeau d’interruption : ADIF Config. • • • ADCON1 ADRESH ADRESL Résultat multiplexage 8 vers 1 1 CAN 8 entrées (voies) Résolution de 10 bits, 12 Tad = temps de conversion Minimum Tad = 1.6 us Result = ADRESH*2^8+ADRESL Result = ADRESH+(ADRESL>>6) vitesse voies Start Fini activation format config. broches A/D void main(void) static void interrupt test_int() { { GIE=1; // registre INTCON if( T0IF ==1 && T0IE==1) T0IE=1; // registre INTCON { OPTION_REG=0x01; ADCON0 l = 0x04; TRISD=0x04; while(!(ADCON0 & 0x04)); TMR0=5; if((ADRESH&0x03)*256+ADRESL)>750) ADCON0 l= 0x91 ; // F/32, Voie2, ON PORTD^=1; ADCON1 =0x80 ; // all pins analog, right justified } while(1); TMR0=5; } T0IF=0; } Communications séries : module USART • Communication = transfert de données sous forme binaire entre 2 appareils • Liaison série : transfert de données binaires séquentiellement = les bits sont transmis les uns après les autres, • 3 fils minimum pour transmission / réception : TX, RX, masse,… • Vitesse de transmission : bits/s ou baud • Deux types de liaison série : - synchrone : transmission de l’horloge via ligne dédiée en plus Ex : liaison SPI - asynchrone : synchronisation par horloges côté émetteur et récepteur réglées de manière identique Ex : liaison RS232 Module série asynchrone (16f87xx) Tx = RC6 Rx = RC7 brochage d’une liaison RS232 équipement identique sur tous appareils Niveau logique Tension RS232 Tension TTL "0" +3V à +25V 0V "1" -3V à -25V +5V sur pic 16f877 TX -> RC6 RX -> RC7 Attention broche TTL ->convertisseur Format de trame RS232 temps liaison asynchrone => génération d’horloge de chaque côté (Baud rate generator) pour emission et reconstruction de données @9600 bauds : emission d’1 bit dure 104 us Exemple d’une trame capturée Registres associés : état transmission 0 0 1 0 0 1 0 0 Ex : TXSTA=0x24 Registre associée : état réception 1 0 0 1 0 0 0 0 Ex : RCSTA = 0x90 Registre SPBRG : baud rate generator Registres de réception et de transmission RCREG = registre en lecture en réception TXREG =registre en écriture en émission Exemple de code pour liaison série asynchrone Communication sur 8 bits @ 9600 bauds, sans contrôle de parité #include<htc.h> void uart_init(void); void TX(unsigned char TX_BYTE); unsigned char a; void main() { uart_init(); while(1); } void uart_init(void) { TRISC7 = 1; // Rx TRISC6 = 0; // Tx SPBRG = 129; // 9600 bauds, BRGH = 1; // @ Fosc= 20 MHz TXSTA = 0x24; RCIE =1 ; GIE =1; PEIE =1; // autorisation pour interruption sur // réception série RCSTA = 0x90; } void interrupt receive(void) { if(RCIE && RCIF) { RCIF = 0; TX(RCREG); } } void TX(unsigned char TX_BYTE) { TXREG = TX_BYTE; while(!TRMT); } Module série synchrone (16f87xx) SPI I2C (Serial Peripheral Interface) (Inter Integrated Circuit) 2 modes : maître ou esclave Fonction Label Horloge SCK RC3 S Horloge SCL RC3 E Données sortantes SDO (MISO) RC5 S Données SDA RC4 E Données entrantes SDI (MOSI) RC4 E SS/ RA5 E/S Synchronisation maître / esclave Broche Sens Mode maître • FOSC/4 (or TCY) • FOSC/16 (or 4•TCY) • FOSC/64 (or 16 • TCY) • 2/(TMR2 output) Fonction Label Broche Sens Débit • 100 kHz • 400 kHz • 1MHz => Max = 10Mb/s @ Fosc=40 MHz Taille données 8 bits variable : encapsulée dans trame Module SPI : liaison full-duplex L'émission et la réception se font simultanément par le même registre à décalage SSPSR. Emission/réception commence à écriture 1 octet dans SSPBUF puis transfert vers registre à décalage SSPSR. Les bits sont transmis un à un sur SDO par 8 tops d’horloges. Octet émis, remplacé par bits arrivant sur SDI. =>nouveau contenu de SSPSR (= octet reçu) copié dans SSPBUF. => mise à 1 du bit BF et SSPIF. BF est en lecture seule =>remise à 0 = lire registre SSPBUF. • • mode « master »: impose l’horloge / débit aux esclaves mode « slave » : horloge générée par « master » => démarrage emission / réception du « slave » Module SPI : système à esclaves multiples data + horloge envoyées simultanément à tous les esclaves sélection par « master » broches d’I/O Module SPI : mode « maître » (master) Module SPI : mode maître (master) BF : Indicateur qui indique quand il passe à 1 que le registre SSPBUF contient l'octet qui vient d'être reçu. Ce bit est remis automatiquement à zéro au moment de la lecture du registre SSPBUF. Module SPI : mode maître (master) Module SPI : mode esclave (slave) Module SPI : mode esclave (slave) Module SPI : mode esclave (slave) Module SPI : mode esclave (slave) Module SPI : mode esclave (slave) Procédure pour liaison SPI • • • • • Configurer la direction des lignes RC4/SDI, RC5/SDO et RC3/SCK Définir la polarité de l'horloge par le bit SSPCON.CKP Définir la fréquence de l'horloge à l'aide des bits SSPCON.SSPMx Définir le moment de lecture des bits entrant à l'aide du bit SSPSTAT.SMP Définir le moment d’écriture des bits sortants à l'aide du bit SSPSTAT.CKE Valider le port par le bit SSPCON.SSPEN Après l’initialisation, l'émission/réception se fait comme suit : • Copier un octet dans SSPBUF pour démarrer l’émission/réception • attendre la fin en surveillant SSPSTAT.BF ou PIR1.SSPIF • La lecture de SSPBUF est la seule façon de r.à.z le bit SSPSTAT.BF • Si on l’utilise, le drapeau PIR1.SSPIF doit être remis à 0 Exemple : liaison entre 2 uC master vers slave côté « master » côté « slave » void main(void) { unsigned char dataTX = 0xFF; TRISA = 0x00; // broche SS sur slave TRISC = 0x00; // SDO et SCK en sortie OpenSPI(SPI_FOSC_16, MODE_10, SMPMID); // configuration de la liaison SPI while(1) { PORTAbits.RA0 = 0; //Slave Select enable putcSPI(dataTX); // envoie d’1 octet vers slave PORTAbits.RA0 = 1; //Slave Select disable delay_ms(5); if(dataTX == 0) dataTX = 0xFF; else dataTX--; } } void main(void) { unsigned char dataRX; TRISA = 0xFF; // SS sur RA5 TRISB = 0x00; PORTB = 0x00; TRISCbits.TRISC3 = 1; //SCLK TRISCbits.TRISC4 = 1; //MOSI = SDI OpenSPI(SLV_SSON, MODE_10, SMPMID); while(1) { while (!DataRdySPI()); dataRX = getcSPI(); // lire octet du master PORTB = (x>>1); delay_ms(5); } }