« SE4Binome2024-5 » : différence entre les versions
Ligne 160 : | Ligne 160 : | ||
<p style="clear: both;" /> | <p style="clear: both;" /> | ||
== Détails des composants == | === Détails des composants === | ||
=== ATmega328P === | ==== ATmega328P ==== | ||
* Micro-contrôleur | * Micro-contrôleur | ||
=== 74HC138D === | ==== 74HC138D ==== | ||
* Décodeur | * Décodeur | ||
=== CD4532BM === | ==== CD4532BM ==== | ||
* Encodeur | * Encodeur | ||
=== 74LS32 === | ==== 74LS32 ==== | ||
* Porte logique Or pour la mise en parallèle des encodeurs | * Porte logique Or pour la mise en parallèle des encodeurs | ||
=== Connecteur HE10 === | ==== Connecteur HE10 ==== | ||
* Connecteur pour la liaison PicoShield-CarteFille | * Connecteur pour la liaison PicoShield-CarteFille | ||
=== Connecteur de la matrice === | ==== Connecteur de la matrice ==== | ||
* Simplement une empreinte que l'on a créé [https://gitea.plil.fr/ktouron/se4-djadja-touron_pico/src/branch/main/CF_Clavier/Footprint_KeyboardDell_DJADJA Lien vers la bibliothèque présent sur le git] | * Simplement une empreinte que l'on a créé [https://gitea.plil.fr/ktouron/se4-djadja-touron_pico/src/branch/main/CF_Clavier/Footprint_KeyboardDell_DJADJA Lien vers la bibliothèque présent sur le git] | ||
=== AVR-ISP-6 === | ==== AVR-ISP-6 ==== | ||
* Programmateur AVR | * Programmateur AVR | ||
=== LED_SMD === | ==== LED_SMD ==== | ||
* 3 LEDs | * 3 LEDs | ||
== | == Hardware == | ||
===Kicad=== | |||
=== | ====Reçu carte vierge==== | ||
====Carte après soudure des composants==== |
Version du 20 novembre 2024 à 11:01
Introduction
Ce wiki documente le développement d’un pico-ordinateur modulaire. Ce dernier est constitué d’une carte principale, composée d’une carte Shield permettant la connexion des cartes filles, et d’une carte mère (initialement simulée par une Arduino Uno avant sa conception finale). Plusieurs cartes filles sont prévues, chacune remplissant une fonction spécifique : gestion du clavier, affichage, port série, réseau, mémoire de masse et son.
Notre binôme est spécifiquement chargé du développement de la carte fille dédiée au clavier.
Toutes les ressources nécessaires, incluant les codes sources et les schémas, sont disponibles sur le dépôt Git suivant : Lien du Git
Carte Shield
Test
Allumage de LEDS sur Programmateur AVR
Avant de programmer directement sur le shield, nous avons allumé des LED pour tester la carte. Nous avons directement utilisé le code exemple fourni par l'IDE arduino en adaptant simplement les pins correspondant aux leds. Code du test
Lecture de la carte SD
Avant de programmer directement sur le shield, nous avons tester si la carte SD était bien détectée et lue. On a utilisé le code test présent dans l'IDE arduino en adaptant le port utilisé.Code du test
Connecteurs IDC HE10
Afin de tester nos connecteur HE10, nous avons utilisé un afficher 7 segments (Sparkfun 7 segments display). Pour pouvoir vérifier leurs fonctionnements nous avons branché l'afficheur sur chaque connecteur tour à tour. Le programme implanté est un simple connecteur à afficher sur l'afficheur. Voici une vidéo du compteur fonctionnant sur un des 5 connecteurs HE10. (Code ici (section : Example 2 SPI))
Ordonnanceur
Pour les interruptions de notre ordonnanceur nous avons utilisé la procédure d'initialisation du minuteur avec le Timer1 disponible dans les cours de Mr.Redon en renseignant une période de 20ms. Nous l'avons disposé dans le fichier minuteur.c car nous n'allons plus le modifier pour le reste du projet. Dans un autre fichier process.c (avec process.h), nous allons y mettre nos structures pour les process et leurs états puis une union pour le temps qui le caractérise ainsi que toutes les fonctions associés.
Processus
Structure
typedef struct {
uint16_t adresseDepart; //adresse de la fonction de départ
uint16_t adressePile; //adresse de la pile d'exécution
Etat etat;
} Process;
Notre structure caractérisant un processus est définie par les trois champs ci-contre.
Une adresse de départ correspondant à la fonction du processus associé, l'adresse où se situe le processus dans la pile puis l'état de la tâche. Nous avons décidé de faire une structure à part entière compte tenu des multitudes d'états que nous pourrons ajouter pendant la progression du projet.
Etat d'un processus
typedef union {
int sleepingtime;
} Time;
typedef struct {
int id;
Time time;
} Etat ;
L'état d'un processus est alors une structure à deux champs (pour l'instant), l'id doit correspondre à un '#DEFINE' pour avoir un sens tandis que nous avons choisi de faire une union pour le temps qui caractérise notre état afin qu'il puisse avoir un nom et type de variable cohérent avec son état.(Ici seulement sleepingtime car seul l'état endormi existe pour le moment)
Etat | ACTIVE | SLEEPY | ... | ... |
---|---|---|---|---|
Id | 0 | 1 | ... | ... |
Procédures principales
ISR
ISR(TIMER1_COMPA_vect, ISR_NAKED) // Procédure d'interruption
{
TCNT1=0;//reset timer
/* Sauvegarde du contexte de la tâche interrompue */
portSAVE_REGISTERS();
table_process[indice_tache].adressePile = SP;
/* Appel à l'ordonnanceur */
selectProcess();
/* Récupération du contexte de la tâche ré-activée */
SP = table_process[indice_tache].adressePile;
portRESTORE_REGISTERS();
asm volatile ( "reti" );
}
L'ISR est ce qu'il va être executer lors des interruptions toutes les 20 millisecondes. Cela consiste à sauvegarder tous les registres de la tâche qui était en cours avant l'appel de l'ISR pour ensuite passer à la tâche suivante valide (c'est à dire active) sans oublier de charger les registres de la nouvelle tâche.
Nous devons également, à chaque fois avant de changer de tâche, enregistrer le pointeur de pile dans le processus afin de pouvoir revenir là ou elle en est la prochaine fois qu'elle sera appelée. Respectivement, une fois la nouvelle tâche choisie, le pointeur de pile doit prendre l'adresse de là ou en était la tâche avant qu'elle soit interrompue.
Séléction de processus
Lors de la séléction de processus, nous devons parcourir tous les processus jusqu'au moment où nous en trouvons un actif. Ainsi, il deviendra la tâche que nous traiterons lors du prochain intervalle de 20 ms. A ce stade, à chaque fois que la procédure selectProcess est appelée, nous devons réduire le temps de repos de chaque process endormi de 20 ms. D'autres conditions pourrons être ajoutée si ajout d'état a lieu.
Test
Clignotement de deux LED à fréquences indivisibles entre elles
Afin de vérifier la réussite de notre ordonnanceur à fonctionnement tourniquet, nous avons programmer deux simples tâches changeant l'état d'une LED. Une à une fréquence 200ms et l'autre 300ms (avec un _delay_ms).
void tache1(void){
while (1){
PORTC ^= (1 << PC0);
_delay_ms(300);}}
void tache2(void){
while (1){
PORTD ^= (1 << PD7);
_delay_ms(200);}}
Clignotement grâce à l'état endormi
Nous ajoutons l'état endormi afin que nos tâches ne mettent pas en pause l'ordonnanceur avec un _delay_ms. Pour cela, nous incorporons une fonction makeSleep qui permet de mettre la tâche qui l'appelle dans cet état.
void makeSleep(int t){
table_process[indice_tache].etat.id = SLEEPY;
table_process[indice_tache].etat.time.sleepingtime = t;
TIMER1_COMPA_vect();}
void tache1(void){
while (1){
PORTC ^= (1 << PC0);
_delay_ms(300);}}
void tache3(void){
while (1){
PORTC ^= (1 << PC3);
//_delay_ms(1000);
makeSleep(1000);}}
void tache2(void){
while (1){
PORTD ^= (1 << PD7);
//_delay_ms(1000);
makeSleep(700);}}
A noter que la première tâche executée ne doit pas être endormie.
Carte Fille Matrice de touches
Explications générales sur la réalisation de la carte
Pour concevoir la carte fille dédiée au clavier, nous avons réutilisé un ancien clavier DELL équipé d’une matrice déjà fonctionnelle. L’idée consiste à connecter les sorties de cette matrice directement à notre carte fille à l’aide d’un connecteur adapté.
Cependant, un défi se pose : la matrice du clavier comprend un total de 26 sorties (sans compter les LED et autres signaux). Cela dépasse largement les capacités en nombre de broches d’un ATmega328P.
Pour remédier à ce problème, nous avons mis en place une solution d’encodage. Nous avons utilisé un décodeur (3 vers 8) pour gérer les lignes et trois encodeurs (8 vers 3) pour gérer les colonnes. Les encodeurs sont montés en parallèle pour réduire significativement le nombre de broches nécessaires.Cette solution permet de maximiser les ressources du microcontrôleur tout en gérant efficacement les signaux de la matrice.
Détails des composants
ATmega328P
- Micro-contrôleur
74HC138D
- Décodeur
CD4532BM
- Encodeur
74LS32
- Porte logique Or pour la mise en parallèle des encodeurs
Connecteur HE10
- Connecteur pour la liaison PicoShield-CarteFille
Connecteur de la matrice
- Simplement une empreinte que l'on a créé Lien vers la bibliothèque présent sur le git
AVR-ISP-6
- Programmateur AVR
LED_SMD
- 3 LEDs