avr:exemple
This is an old revision of the document!
Table of Contents
Exemple de code pour AVR
Pour le montage technique du microcontrôleur, ainsi que des différents câbles sur le stk500, se référer à ce site http://www.robotroom.com/Atmel-ATtiny-STK500-Programming.html.
Pour la théorie et le premier exemple pratique un passage par ce site est conseillé http://iamsuhasm.wordpress.com/tutsproj/avr-gcc-tutorial/.
Pour la théorie et le premier exemple pratique un passage par ce site est conseillé http://iamsuhasm.wordpress.com/tutsproj/avr-gcc-tutorial/.
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.1379515914.txt.gz · Last modified: 2013/09/18 14:51 by sdolt