avr:exemple
Table of Contents
Exemple de code pour AVR
Attiny 85
Exemple de code pour ATtiny 85 sur le programmeur / platine d'expérimentation STK500
Allumer et éteindre les LEDs
- main.c
#include<inttypes.h> #include<avr/io.h> #define F_CPU 1000000UL //1MHZ, réglage de la fréquence du CPU #include<util/delay.h> int main() { DDRB = 0b111111; //initialisation de tous les pins PORTB en sortie while(1) { //Séquence 1 PORTB = 0b010111; //toutes les LED sont éteintes _delay_ms(150); //attente PORTB = 0b010110; //allumage de la LED0 _delay_ms(50); //attente PORTB = 0b010100; //allumage des LED0 + LED1 _delay_ms(50); //attente PORTB = 0b010000; //allumage des LED0 + LED1 + LED2 _delay_ms(50); //attente PORTB = 0b000000; //allumage des LED0 + LED1 + LED2 + LED3(sur PB4) _delay_ms(150); // ... PORTB = 0b010000; _delay_ms(50); PORTB = 0b010100; _delay_ms(50); PORTB = 0b010110; _delay_ms(50); PORTB = 0b010111; _delay_ms(150); //Séquence 2 PORTB = 0b000111; _delay_ms(50); PORTB = 0b000011; _delay_ms(50); PORTB = 0b000001; _delay_ms(50); PORTB = 0b000000; _delay_ms(150); PORTB = 0b000001; _delay_ms(50); PORTB = 0b000011; _delay_ms(50); PORTB = 0b000111; _delay_ms(50); PORTB = 0b010111; _delay_ms(150); //Séquence 3 PORTB = 0b010110; _delay_ms(50); PORTB = 0b010101; _delay_ms(50); PORTB = 0b010011; _delay_ms(50); PORTB = 0b000111; _delay_ms(50); PORTB = 0b010111; _delay_ms(150); PORTB = 0b000111; _delay_ms(50); PORTB = 0b010011; _delay_ms(50); PORTB = 0b010101; _delay_ms(50); PORTB = 0b010110; _delay_ms(50); PORTB = 0b010111; _delay_ms(150); //Séquence 4 PORTB = 0b000000; _delay_ms(50); PORTB = 0b000001; _delay_ms(50); PORTB = 0b000010; _delay_ms(50); PORTB = 0b000100; _delay_ms(50); PORTB = 0b010000; _delay_ms(50); PORTB = 0b000000; _delay_ms(150); PORTB = 0b010000; _delay_ms(50); PORTB = 0b000100; _delay_ms(50); PORTB = 0b000010; _delay_ms(50); PORTB = 0b000001; _delay_ms(50); PORTB = 0b000000; _delay_ms(150); } return 0; }
Allumer une LED en appuyant sur un bouton switch
- main.c
#include<inttypes.h> #include<avr/io.h> int main() { DDRB = 0xFF; //initialisation de tous les pins PORTB en sortie (<=> DDRB = 0b1111'1111) DDRB |= (1<<PB0); // mise en sortie de PB0 [(1<<PB0) <=> PB = 0b0000'0001)] PORTB &= ~(1<<PB0); //nous nous assurons que la LED reliée à PB0 sera allumée DDRB |= (1<<PB1); //mise en sortie de PB1 [(1<<PB1) <=> PB = 0b0000'0010)] DDRB &= ~(1 << PB2); // mise en entrée de PB2 [~(1<<PB2) <=> 0b1111'1011)] while (1) { if (PINB & (1<<PB2)) // s'il y a un signal rentrant par PINB (pas de pression sur le bouton) PORTB |= (1<<PB1); // la LED1 reste éteinte (PORB = 0b0000'0010) else PORTB &= ~(1<<PB1); // allumage de la LED1 reliée à PB1 (PORB = 0b0000'0000) } return 0; }
Créer une interruption en cliquant sur un bouton switch
Séquence 1: extinction différée des LEDs 0 et 1 lors de la pression sur le bouton
- main.c
#include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 1000000UL //1MHZ #include <util/delay.h> ISR(INT0_vect) //définition de l'interruption avec comme paramètre le vecteur INT0 { //pression sur le bouton switch PORTB |= (1<<PB0); //extinction de la LED0 _delay_ms(150); PORTB |= (1<<PB1); //extinction de la LED1 _delay_ms(150); } int main(void) { DDRB = 0xFF; //initialisation de tous les pins PORTB en sortie DDRB |= (1<<PB0); //mise en sortie de PB0 DDRB |= (1<<PB1); //mise en sortie de PB1 DDRB &= ~(1 << PB2); //mise en entrée de PB2 cli(); //désactivation des interruptions // Activer l'interruption externe "INT0" GIMSK |= (1<<INT0); //masque d'interruption MCUCR |= (1<<ISC00); //signal interrompu en montée MCUCR |= (1<<ISC01); sei(); //activation des interruptions while(1) { PORTB &= ~(1<<PB0); //les LEDs 0 et 1 restent allumées PORTB &= ~(1<<PB1); } return 0; }
Séquence 2: extinction des LEDs 0 et 1 uniquement lors de la pression sur le bouton
- main.c
#include <avr/io.h> #include <avr/interrupt.h> ISR(INT0_vect) //définition de l'interruption avec comme paramètre le vecteur INT0 { if (bit_is_set(PINB,PB2)) //relâchement du bouton switch: allumage des LEDs { PORTB &= ~(1<<PB0); //allumage de la LED0 PORTB &= ~(1<<PB1); //allumage de la LED1 } else //si pression sur le bouton switch: extinction des LEDs { PORTB |= (1<<PB0); //extinction de la LED0 PORTB |= (1<<PB1); //extinction de la LED1 } } int main(void) { DDRB = 0xFF; //initialisation de tous les pins PORTB en sortie DDRB |= (1<<PB0); //mise en sortie de PB0 DDRB |= (1<<PB1); //mise en sortie de PB1 DDRB &= ~(1 << PB2); //mise en entrée de PB2 cli(); //désactivation des interruptions // Activer l'interruption externe "INT0" GIMSK |= (1<<INT0); //masque d'interruption MCUCR |= (1<<ISC00); //signal interrompu par n'importe quel changement logique sei(); //activation des interruptions while(1); return 0; }
Créer une interruption grâce à une minuterie
- main.c
#include <avr/io.h> #include <avr/interrupt.h> #define DDRB_IN(a) DDRB &= ~(1<<a) //mise en entrée #define DDRB_OUT(a) DDRB |= (1<<a) //mise en sortie #define LED_ON(a) PORTB &= ~(1<<a) //allumage d'une LED #define LED_OFF(a) PORTB |= (1<<a) //extinction d'une LED ISR(TIMER1_COMPA_vect) //vecteur du timer de comparaison A { PORTB ^= (1<<PB0); //changement du statut de la LED (passage à allumé si éteint, éteint si allumé) } int main() { DDRB = 0xFF; //initialisation de tous les pins PORTB en sortie DDRB_OUT(PB0); //mise en sortie de PB0 DDRB_OUT(PB1); //mise en sortie de PB1 LED_ON(PB0); //allumage de la LED0 TCCR1 |= (1<<CTC1); //activation du mode CTC (comparaison) TIMSK |= (1<<OCIE1A); //activation de l'interruption si l'on atteint la valeur de OCR1A sei(); //activation des interruptions OCR1A = 244; //valeur à atteindre (nous partons d'une fréquence itiale de 8MHz pour arriver à une fréquence de 2 Hz: (8*10^6/2)/16384=244) TCCR1 |= (1<<CS10) | (1<<CS11) | (1<<CS12) | (1<<CS13); //début du timer à CK/16384 while(1){ LED_OFF(PB1); //extinction de la LED1 } return 0; }
Configuration et lecture du convertisseur AD
- main.c
#include<inttypes.h> #include<avr/io.h> #define F_CPU 8000000UL #include<util/delay.h> void initAdc (void); void main (void) { int valHigh; int valLow; initAdc(); while (1) { ADCSRA|=(1<<ADSC); //Commence la conversion AD while (ADCSRA & (1<<ADSC)); //tant que la conversion AD n'est pas fini : ne fait rien valHigh = ADCH; valLow = ADCL; } return 0; } // Cette fonction configure la conversion AD void initAdc (void) { ADMUX = 0b00000001; //REFS1 = 1 -> RFS = 010 référence de voltage interne(1.1V) //REFS1 = 0 -> RFS = 000 VCC utilisé comme référence (VCC = 5V) //REFS0 = 0 //ADLAR = 0 -> ne shift pas les registres ADCH et ADCL //REFS2 = 0 //MUX3-0 = 0001 -> utiliser PB2 ADCSRA = 0b10000110; //ADEN = 1 -> active l'adc //ADSC = 0 -> n'active pas encore la CONVERSION adc //ADATE = 0 //ADIF = 0 //ADIE = 0 //ADPS2-0 = 011 -> prescaler à 8 //ADPS2-0 = 110 -> prescaler à 64 }
La configuration du convertisseur AD a été réalisé à l'aide du datasheet de l'ATTINY85 téléchargable ici :http://www.atmel.com/Images/doc2586.pdf. Les registres utilisés se trouvent dès la page 138.
avr/exemple.txt · Last modified: 2013/09/18 16:54 by sdolt