Base de travail pour différents projets à base d’AVR en C
Je travail sur différentes choses autour des microcontrôleurs Atmel AVR à l'heure actuelle. Je n'en dirai pas trop pour le moment, mais cela touche à la PWM et aux leds (comme souvent) ainsi qu'aux ports séries/USB. Dans le tas, il y a une signalisation lumineuse pour notre salle de réunion (dans la GLMFcave), le projet coccilight et un projet secret (tant qu'il sera pas terminé) qui manque encore d'éléments de décoration (bricoler un truc laid plein d'epoxy et de soudure c'est facile, arriver à quelque chose de présentable c'est une autre affaire).
Quoi qu'il en soit, j'ai dernièrement joué un peu avec un de mes vieux codes en assembleur Atmel que j'ai réimplémenté en C pour un AVR Attiny13 : la pulsation d'une led en PWM utilisant des valeurs sinusoïdales stockées dans la Flash du microcontrôleur.
Le stockage à proprement parler prend cette forme :
const uint8_t dasin[] PROGMEM = {
255,255,255,255,255,254,254,253,252,252,251,250,249,248,247,246,
245,243,242,240,239,237,236,234,232,230,228,226,224,222,220,218,
216,213,211,209,206,204,201,199,196,193,191,188,185,182,179,176,
174,171,168,165,162,159,156,152,149,146,143,140,137,134,131,128,
124,121,118,115,112,109,106,103,99,96,93,90,87,84,81,79,
76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,
35,33,31,29,27,25,23,21,19,18,16,15,13,12,10,9,
8,7,6,5,4,3,3,2,1,1,1,1,0,0,0,0,
0,0,0,0,1,1,1,2,3,3,4,5,6,7,8,9,
10,12,13,15,16,18,19,21,23,25,27,29,31,33,35,37,
39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,79,
81,84,87,90,93,96,99,103,106,109,112,115,118,121,124,127,
131,134,137,140,143,146,149,152,156,159,162,165,168,171,174,176,
179,182,185,188,191,193,196,199,201,204,206,209,211,213,216,218,
220,222,224,226,228,230,232,234,236,237,239,240,242,243,245,246,
247,248,249,250,251,252,252,253,254,254,255,255,255,255,255,255
};
Après quelques define préalables et autres choses indispensables en début de code...
#define F_CPU 2000000UL
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <util/delay.h>
#define PWMDDR DDRB
#define PWMOUT PB0
#define MCUCSR MCUSR
#define DELAY 5
uint8_t mcucsr __attribute__((section(".noinit")));
...on peut s'attaquer à la fonction main :
int main (void) {
volatile uint8_t j;
TCCR0A = _BV(WGM00) | _BV(WGM01) | _BV(COM0A1) | _BV(COM0A0);
TCCR0B = _BV(CS00);
OCR0A = 0;
PWMDDR |= _BV(PWMOUT);
while (1) {
for(j=0;j<255;j++) {
OCR0A = pgm_read_byte(dasin+j);
_delay_ms(DELAY);
}
}
}
Voilà, c'est tout. La table des valeurs est le résultat d'un calcul détaillé dans un précédent billet. Rien d'extraordinaire dans tout cela, certes, mais comme j'ai un peu creusé dans le code d'autres personnes et sur Google, donc je fais tourner...