Cours n°2

publicité
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);
}
}
Téléchargement