SE4Binome2026-3
Lien Gitea
Lien du git : https://gitea.plil.fr/etardieu/IOT4_Pico_TARDIEUX_KACHOUR.git
Présentation du projet
Voici le wiki du projet Pico ordinateur des élèves de IoT4 à Polytech Lille.
Vous trouverez ici les différentes étapes du projet, les difficultés rencontrées et l'avancement de notre travail.
Durant ce projet, nous prévoyons de construire un pico-ordinateur comprenant les éléments suivants :
- un processeur de type microcontrôleur ;
- un clavier ;
- un dispositif d'affichage ;
- un système d'exploitation stocké dans la mémoire flash du microcontrôleur ;
- une mémoire de masse allant au delà de la mémoire flash sus-citée ;
- un dispositif de communication avec l'extérieur.
Pour faire en sorte que tous les éléments puissent communiquer entre eux nous utiliserons un bus série.
Shield Arduino UNO
Le schéma, ainsi que le pcb du shield que nous allons utiliser se trouve dans le wiki Pico SE4
Nous avons étudié la composition de ce shield, afin d'ajuster notre carte mère, et de la rendre compatible avec notre shield.
Carte Mère
Dans un premier temps, après avoir étudié la composition du shield, nous allons concevoir la carte mère de notre Pico ordinateur.
Selon les consignes, la carte doit contenir les éléments suivants :
- le processeur principal de la carte mère est un ATmega32u4 tournant à 8Mhz sous 3,3V ;
- l'alimentation se fait en utilisant le connecteur USB A mâle de programmation de l'ATmega32u4 et un régulateur 3,3V bien dimensionné ;
- la carte mère présente 4 emplacements pour cartes filles :
- le bus reliant la carte mère aux cartes filles est principalement constitué du bus SPI,
- les emplacements comportent aussi une ligne CS (Chip Select) spécifique à chaque emplacement,
- vous ajouterez 4 E/S du microcontrôleur sur le bus pour des applications particulières (E/S partagées par les cartes filles),
- bien entendu, le bus comprend la masse et l'alimentation 3,3V ;
- la carte mère comprend un sous-système à base d'ATmega16u2 pour l'accès au port série du microcontrôleur principal :
- alimentation en 3,3V, horloge à 8Mhz,
- ce sous-système dispose de son propre connecteur USB A mâle de programmation et de communication USB/série,
- le bus série de l'ATmega16u est connecté au bus série de l'ATmega32u4 (TX de l'un face au RX de l'autre),
- vous pouvez utiliser le programme USB/série de l'Arduino Uno R3 ;
- la carte mère comprend un sous-système à base d'AT90USB1287 pour l'utilisation d'un clavier USB :
- alimentation en 3,3V, horloge à 8Mhz,
- ce sous-système dispose d'un connecteur USB A mâle pour la programmation de son microcontrôleur,
- il dispose aussi d'un connecteur USB A femelle pour la connexion au clavier, attention l'alimentation du clavier doit se faire en 5V,
- la broche série TX de l'AT90USB1287 est connectée à la broche série RX de l'ATmega32u4.
Nous commençons donc par réaliser le schéma électronique de notre carte mère en utilisant le logiciel Kicad.
Ordonnanceur
Test Ordonnanceur (Timer LED)
Tout d'abord, nous avons testé notre Ordonnanceur, en faisant clignoter deux LED à deux fréquences différentes.
Nous avons récupéré le code du cours de SE5 : 5.10 ATmega328p : Minuteurs, que nous avons modifié à l'aide de la schématique du shield Aduino.
#include <avr/io.h>
#include <avr/interrupt.h>
#define LED1 PB5 // Pin Arduino 13
#define LED2 PB4 // Pin Arduino 12
void init_minuteur(void)
{
TCCR1A = 0;
// Mode CTC : remise à zéro du compteur lorsque TCNT1 atteint OCR1A
// Prédiviseur = 256
TCCR1B = (1 << WGM12) | (1 << CS12);
// F_CPU = 16 MHz
// 20 ms avec un prédiviseur de 256
OCR1A = 1250;
// Compteur initialisé à 0
TCNT1 = 0;
// Autorisation de l'interruption lorsque TCNT1 atteint OCR1A
TIMSK1 = (1 << OCIE1A);
}
/* Interruption déclenchée toutes les 20 ms */
ISR(TIMER1_COMPA_vect)
{
static uint8_t compteur1 = 0;
static uint8_t compteur2 = 0;
compteur1++;
compteur2++;
/*
* 25 × 20 ms = 500 ms
* LED1 change donc d'état toutes les 500 ms
*/
if(compteur1 >= 25)
{
PORTB ^= (1 << LED1);
compteur1 = 0;
}
/*
* 50 × 20 ms = 1000 ms
* LED2 change donc d'état toutes les 1 s
*/
if(compteur2 >= 50)
{
PORTB ^= (1 << LED2);
compteur2 = 0;
}
}
int main(void)
{
/*
* PB5 = Arduino 13 = LED D1 du shield
* PB4 = Arduino 12 = LED D2 du shield
*/
DDRB |= (1 << LED1) | (1 << LED2);
/*
* Les LED du shield sont actives à l'état bas.
* On les met donc à 1 pour les éteindre au départ.
*/
PORTB |= (1 << LED1) | (1 << LED2);
// Configuration de Timer1
init_minuteur();
// Autorisation globale des interruptions
sei();
while(1)
{
// Rien à faire ici pour ce premier test
}
return 0;
}
Les LED du shield clignotent bien comme souhaité.
Sauvegarde et restauration des registres
Nous avons dabord essayé de vulgariser cette partie, afin de comprendre ce que nous faisions.
Le microcontrolleur ne pouvant pas faire plusieurs taches en même temps, il doit alterner très rapidement entre les tâches. Si nous prenons l'exemple de deux tâches A et B, le microcontrolleur va alterner entre ces deux tâches. au moment de passer à la tache B, il faut enregistrer l'état et la progression de la tâche A. Idem lors du passage de B à A. Lorsque le microcontrolleur repasse sur la tache A, il doit restaurer son état, afin de reprendre la progression.