« I2L 2022 Groupe6 » : différence entre les versions

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
Ligne 142 : Ligne 142 :


===== Faire parler le HP =====
===== Faire parler le HP =====
''Alimenter le HP et lui fournir une fréquence fixe, pour débuter :''<syntaxhighlight lang="c">
''Alimenter le HP et lui fournir une fréquence fixe mais mettre un délai entre 2 sons, pour débuter :''<syntaxhighlight lang="c">
#include <avr/io.h>
#include <avr/io.h>
#include <util/delay.h>
#include <util/delay.h>
Ligne 257 : Ligne 257 :
=== Prog USB ===
=== Prog USB ===
Le programme qui va sur le microcontrôleur
Le programme qui va sur le microcontrôleur
==== FAIRE PARLER LE HP EN MEME TEMPS QUE LA LED ====
==== FAIRE PARELER LE HP EN MEME TEMPS QUE LE BOUTON ET LA LED ====


=== Prog PC ===
=== Prog PC ===
Le programme qui tourne sur le pc
Le programme qui tourne sur le pc

Version du 25 mai 2023 à 09:38

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 mais mettre un délai entre 2 sons, 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

FAIRE PARLER LE HP EN MEME TEMPS QUE LA LED

FAIRE PARELER LE HP EN MEME TEMPS QUE LE BOUTON ET LA LED

Prog PC

Le programme qui tourne sur le pc