I2L 2022 Groupe6

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche

Proposition de système

Nous voudrions équiper la carte d'un port USB, d'une horloge, d'une LED, d'un bouton et d'un haut-parleur. Le but final serait de, lors d'un appui bouton et/ou CapsLock (à définir ensemble), de faire un son et un allumage de la LED.

Contre-proposition

L'idée est bien de refléter l'ensemble de l'état des touches "verrous" du clavier du PC. A chaque changement d'état de ces touches vous associerez un signal lumineux avec les 3 LED multicolores et surtout un signal sonore. Vous êtes tenus de produire des sons et pas seulement des notes. Pour cela vous devrez réussir à stocker (en mémoire flash) des échantillons sonores et à les reproduire sur votre haut-parleur.

Fichiers

Vous utiliserez le même circuit imprimé que le groupe 5.

Installation

Installation des dépendances :

apt install gcc-avr avr-libc dfu-programmer

Passer du fichier source au fichier exécutable :

Compil : avr-gcc -mmcu=atmega16u2 -DF_CPU=16000000UL -c -Wall -I. -Os main.c -o main.o

Edition des liens (exe) : avr-gcc -mmcu=atmega16u2 -g -lm -Wl,--gc-sections -o main.elf main.o

Transformer le code source en fichiers utilisable pour la carte

avr-objcopy -j .text -j .data -O ihex main.elf main.hex

dfu-programmer atmega16u2 erase

dfu-programmer atmega16u2 flash time.hex

dfu-programmer atmega16u2 reset

Programmation

MAKEFILE

AVR = avr-gcc
AVR_HEX = avr-objcopy

TARGET = atmega16u2
DFU = dfu-programmer

CFLAGS = -mmcu=atmega16u2 -DF_CPU=16000000UL -Wall -I. -Os
CLINKS = -mmcu=atmega16u2 -g -lm -Wl,--gc-sections
CHEXS = -j .text -j .data -O
 
SRC = main.c

OBJ = main.o

ELF = main.elf

HEX = main.hex

push: clean compile link hex erase flash reset

compile: 
    $(AVR) $(CFLAGS) -c $(SRC) -o $(OBJ)

link: 
    $(AVR) $(CLINKS) -o $(ELF) $(OBJ)

hex:
    $(AVR_HEX) $(CHEXS) ihex $(ELF) $(HEX)

erase:
    $(DFU) $(TARGET) erase 

flash:
    $(DFU) $(TARGET) flash $(HEX)

reset:
    $(DFU) $(TARGET) reset

clean:
    rm -f $(OBJ) $(EXEC)

Prog SE

LED

Faire clignoter une led

#include <avr/io.h>
#include <util/delay.h>

#define LED     0
#define BUTTON  2

int main(void){

    DDRD |= (1 << LED);                // Sortie pour la LED
    PORTD &= ~(1 << LED);              // Configuration de la résistance de tirage

    while(1) {
        PORTD |= (1 << LED);
        _delay_ms(5);
        PORTD &= ~(1 << LED); 
        _delay_ms(5);     
    }
}

Boutons

Faire clignoter une led en fonction du bouton
#include <avr/io.h>
#include <util/delay.h>

#define LED     0
#define BUTTON  2

int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    DDRD |= (1 << LED);  
    PORTD &= ~(1 << LED);              

    DDRC &= ~(1 << BUTTON);                
    PORTC |= (1 << BUTTON);    

    while(1) {
        if (!(PINC & (1 << BUTTON)))
        {
            PORTD |= (1 << LED);
            _delay_ms(5);
            PORTD &= ~(1 << LED); 
            _delay_ms(5);     
        }
    }
}

HP

Faire parler le HP

Alimenter le HP et lui fournir une fréquence fixe, pour débuter :

#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>


#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)

#define LED     0
#define BUTTON  2
#define SPEAKER 7


int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    TCCR1A = (1 << COM1A0); 
    TCCR1B = (1 << WGM12) | (1 << CS10); 
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;

    DDRD |= (1 << LED);               
    PORTD &= ~(1 << LED);              

    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);

    while(1) {
        uint16_t i;
        for (i = 0; i < BUFFER_SIZE; i++) {
            PORTB ^= (1 << SPEAKER); 
            _delay_us(1000000UL / (2 * TONE_FREQUENCY));
        }

        PORTB &= ~(1 << SPEAKER);
    }

    return 0;
}

Fournir un son de test bufferAudio PROGMEM codé en 8bit fourni au HP :


1) Conversion du fichier aac ou mp3 en fichier codé sous 8bit -> sortie du fichier wav via https://g711.org/

Low Definition 8-bit WAV (8Khz, Mono, 8-Bit PCM)


2) Passer du 8-bit WAV en hexadécimal -> utilisation de la commande linux xxd -i nomDuFichierAudio

A partir de maintenant, nous avons le contenu du fichier audio sous forme hexadécimal et pouvons le stocker et l'utiliser en c


EXEMPLE :

 const uint8_t audioBuffer[] PROGMEM = {
    0xFF, 0x00, 0x80, 0x7F, 0x00, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0x80, 0x7F
};
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>


#define TONE_FREQUENCY 1000  // 1kHz
#define TONE_DURATION_MS 1000 // 1 second
#define SAMPLE_RATE 8000
#define BUFFER_SIZE SAMPLE_RATE / (1000 / TONE_DURATION_MS)

#define LED     0
#define BUTTON  2
#define SPEAKER 7

 const uint8_t audioBuffer[] PROGMEM = {
    0xFF, 0x00, 0x80, 0x7F, 0x00, 0xFF, 0x7F, 0x80, 0x00, 0xFF, 0x80, 0x7F
};


int main(void){

    CLKSEL0 = 0b00010101;
    CLKSEL1 = 0b00001111;
    CLKPR = 0b10000000;
    CLKPR = 0;

    TCCR1A = (1 << COM1A0); 
    TCCR1B = (1 << WGM12) | (1 << CS10); 
    OCR1A = F_CPU / (2 * SAMPLE_RATE) - 1;

    DDRD |= (1 << LED);               
    PORTD &= ~(1 << LED);              

    DDRB |= (1 << SPEAKER);
    PORTB &= ~(1 << SPEAKER);

    while(1) {
        uint16_t i;
        for (i = 0; i < BUFFER_SIZE; i++) {
            PORTB ^= (1 << SPEAKER); 
            _delay_us(1000000UL / (2 * TONE_FREQUENCY));
        }

        PORTB &= ~(1 << SPEAKER);
    }

    return 0;
}

Prog USB

Le programme qui va sur le microcontrôleur

Prog PC

Le programme qui tourne sur le pc