« SE4Binome2024-2 » : différence entre les versions
Ligne 177 : | Ligne 177 : | ||
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments. | La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments. | ||
<br><br> | <br><br> | ||
[[Fichier:Diode.jpg|gauche|vignette| | [[Fichier:Diode.jpg|gauche|vignette|412x412px|Test des LEDs]] | ||
[[Fichier:TestSD.jpg|vignette|Test de la carte SD]] | [[Fichier:TestSD.jpg|vignette|Test de la carte SD]] | ||
[[Fichier:Video7seg.mp4|vignette|400x400px|Timer sur un afficheur 7 segments|néant]] | [[Fichier:Video7seg.mp4|vignette|400x400px|Timer sur un afficheur 7 segments|néant]] | ||
<br><br> | |||
== Tests Réalisés == | == Tests Réalisés == |
Version du 23 octobre 2024 à 09:16
Pico Ordinateur
Ce projet vise à concevoir un pico ordinateur divisé en plusieurs parties, réalisées par différents binômes. Le rôle de notre binôme est de développer une carte fille équipée d'un microcontrôleur ATMega328p et d'un écran LCD contrôlé par un HD44780, en plus de la conception d'un Shield et d'un ordonnanceur. Cette carte sera connectée à une carte mère via un connecteur HE10 et devra gérer l'affichage de caractères ASCII, ainsi que quelques commandes spécifiques VT100. De plus, nous ajouterons une RAM SPI pour améliorer les performances de gestion de l'affichage.
Carte Fille (Écran LCD)
Description
La carte fille que nous avons développée contient les éléments suivants :
- Un microcontrôleur ATMega328p pour la gestion de l'affichage.
- Un écran LCD avec contrôleur HD44780 pour l'affichage de caractères ASCII.
- Un potentiomètre 3310P pour ajuster la luminosité des cristaux liquides de l'écran.
- Un connecteur HE10 pour relier la carte fille à la carte mère.
- Un connecteur AVR ISP pour la programmation du microcontrôleur.
- Une RAM SPI (e.g. FM24C04B-GTR) pour stocker temporairement les données d'affichage.
Fonctionnalités Demandées
- Gestion de l'écran LCD : Le microcontrôleur doit gérer les écrans HD44780 avec 1, 2, 3 ou 4 lignes et afficher des caractères ASCII.
- Saut de ligne et retour chariot : Les caractères spéciaux `\n` et `\r` doivent être pris en compte.
- Commandes VT100 : Quelques codes VT100, notamment ceux pour le déplacement du curseur, doivent être supportés.
- Défilement automatique : Le contrôleur HD44780 doit être configuré pour activer le mode de défilement automatique.
- Connexion SPI : La carte mère doit envoyer les commandes via SPI. Le premier octet envoyé doit être le code commande `0x01`, suivi des caractères à afficher.
- Vérification de la disponibilité de l'écran : La carte fille met la ligne SPI en état haut lorsque l'affichage est en cours. La carte mère doit attendre que l'état soit bas avant de transmettre de nouvelles données, ou envoyer des commandes `0xFF` pour vérifier si l'écran est prêt.
Ajout d'une RAM SPI
Pour complexifier la carte fille, nous ajouterons une RAM SPI (e.g. FM24C04B-GTR). Cette mémoire permet de stocker temporairement les caractères reçus par SPI avant leur affichage. Le microcontrôleur de la carte fille rafraîchit régulièrement l'écran en lisant les données de la RAM, ce qui améliore la fluidité de l'affichage et permet de libérer la carte mère plus rapidement.
Nous avons choisi la RAM FM25W256-G disponible chez RS Component. https://fr.rs-online.com/web/p/memoires-fram/1254228?gb=s
Voici un schéma simplifié de la communication entre les composants :
- La carte mère écrit dans la RAM SPI via le bus SPI.
- Le microcontrôleur de la carte fille lit les données de la RAM SPI et les envoie à l'écran LCD pour mise à jour régulière.
Schéma de Connexion
//capture ecran a ajouter
Ordonnanceur
Introduction
L'ordonnanceur est une partie essentielle de notre pico ordinateur. Il est responsable de la gestion des différentes tâches et de leur exécution de manière organisée. L'objectif de cet ordonnanceur est de permettre un partage équitable du temps processeur entre les tâches et d'assurer que chaque tâche puisse accéder aux ressources du système sans conflit.
L'ordonnanceur prend également en compte la gestion des périphériques, tels que notre écran LCD, en s'assurant que chaque périphérique est disponible avant d'envoyer une nouvelle commande.
Structure des Tâches
Voici comment chaque tâche est représentée dans le système :
struct Task {
int taskID; // Identifiant unique de la tâche
int spiLine; // Ligne SPI associée à la tâche (pour gérer un périphérique)
bool isReady; // Indique si la tâche est prête à s'exécuter
bool isRunning; // Indique si la tâche est actuellement en cours d'exécution
};
Chaque tâche a un identifiant unique `taskID`, ainsi qu'une ligne SPI (`spiLine`) qui lui est assignée pour la gestion des périphériques. Le champ `isReady` permet de savoir si la tâche est prête à être exécutée (par exemple, si le périphérique SPI est disponible), et `isRunning` indique si la tâche est en cours d'exécution.
Fonctions de l'Ordonnanceur
L'ordonnanceur est principalement basé sur deux fonctions principales :
1. scheduler() : Gère le changement de tâche en fonction de l'algorithme Round Robin. 2. spiAvailable() : Vérifie la disponibilité de la ligne SPI avant d'exécuter une tâche.
Fonction `scheduler()`
La fonction `scheduler()` est responsable du passage d'une tâche à l'autre en suivant l'algorithme Round Robin. Elle incrémente l'indice de la tâche courante et revient au début de la liste si la dernière tâche a été atteinte.
Voici le code de la fonction `scheduler()` :
void scheduler() {
// Incrémentation de l'indice de la tâche courante
currentTask++;
// Si l'indice dépasse le nombre de tâches, on revient à la première tâche
if (currentTask == NB_TASKS) {
currentTask = 0;
}
// Vérifie si la tâche suivante est prête à être exécutée
if (taskArray[currentTask].isReady && spiAvailable(taskArray[currentTask].spiLine)) {
// Exécuter la tâche si elle est prête et que la ligne SPI est disponible
executeTask(taskArray[currentTask].taskID);
} else {
// Si la tâche n'est pas prête, passe à la tâche suivante
scheduler();
}
}
Explication du Code :
- currentTask++ : Cette ligne incrémente l'indice de la tâche courante, passant ainsi à la tâche suivante dans la liste.
- if (currentTask == NB_TASKS) : Si l'ordonnanceur arrive à la fin de la liste des tâches (déterminée par `NB_TASKS`, le nombre total de tâches), il revient à la première tâche (`currentTask = 0`).
- taskArray[currentTask].isReady : L'ordonnanceur vérifie si la tâche est prête à être exécutée (en attente d'exécution).
- spiAvailable(taskArray[currentTask].spiLine) : Cette fonction est appelée pour vérifier si la ligne SPI associée à la tâche est disponible (explication ci-dessous).
- executeTask() : Si la tâche est prête et que la ligne SPI est libre, cette fonction exécute la tâche courante.
- scheduler() : Si la tâche n'est pas prête ou si la ligne SPI n'est pas disponible, l'ordonnanceur passe à la tâche suivante.
Fonction `spiAvailable()`
La fonction `spiAvailable()` vérifie si la ligne SPI associée à une tâche est libre. Cela permet d'éviter que plusieurs tâches tentent d'utiliser la même ligne SPI en même temps, ce qui pourrait causer des conflits d'accès.
Voici le code de la fonction `spiAvailable()` :
bool spiAvailable(int spiLine) {
// Vérifie l'état de la ligne SPI
if (getSpiState(spiLine) == SPI_FREE) {
return true;
} else {
return false;
}
}
Explication du Code :
- getSpiState(spiLine) : Cette fonction interroge l'état actuel de la ligne SPI spécifiée (`spiLine`). Si la ligne est libre (`SPI_FREE`), la fonction retourne `true`, sinon elle retourne `false`.
- return true/false : La fonction retourne `true` si la ligne SPI est disponible, permettant ainsi à la tâche de s'exécuter.
Fonction `executeTask()`
La fonction `executeTask()` est celle qui exécute la tâche courante une fois qu'elle est prête et que la ligne SPI est disponible. Cette fonction lance la tâche spécifique en fonction de son `taskID`.
Voici un exemple de la fonction `executeTask()` :
void executeTask(int taskID) {
switch (taskID) {
case 1:
// Exécuter la tâche 1 (affichage sur écran LCD)
updateLCD();
break;
case 2:
// Exécuter la tâche 2 (lecture d'un clavier SPI)
readKeyboard();
break;
// Ajout d'autres tâches ici...
default:
// Si la tâche n'est pas reconnue, ne rien faire
break;
}
}
Explication du Code :
- switch (taskID) : Cette instruction permet de choisir la tâche à exécuter en fonction de l'ID de la tâche.
- updateLCD() : Exemple d'une tâche qui met à jour l'affichage de l'écran LCD.
- readKeyboard() : Exemple d'une tâche qui lit les données d'un clavier SPI.
- default : Si l'ID de la tâche n'est pas reconnu, aucune action n'est effectuée.
Gestion des Interruptions
L'ordonnanceur peut également être interrompu si un événement important survient, comme l'arrivée d'une nouvelle commande ou la fin d'une transmission SPI. Ces interruptions sont gérées via des Interrupt Service Routines (ISR), qui permettent de traiter rapidement ces événements sans interrompre l'ordonnancement global.
Un exemple d'ISR :
ISR(SPI_vect) {
// Gestion de l'interruption SPI
if (isTransmissionComplete()) {
// Marquer la tâche SPI comme terminée
taskArray[currentTask].isReady = true;
}
}
Explication du Code :
- ISR(SPI_vect) : Cette fonction est une ISR qui est appelée lorsque l'événement lié au SPI se produit (par exemple, la fin d'une transmission).
- isTransmissionComplete() : Vérifie si la transmission SPI est terminée.
- taskArray[currentTask].isReady = true : Marque la tâche comme prête à être exécutée à nouveau.
L'ordonnanceur joue un rôle central dans notre pico ordinateur, en gérant les tâches et en s'assurant que chaque tâche a accès aux ressources SPI sans conflit. Ce système d'ordonnancement permet d'assurer un fonctionnement fluide et sans interruption de notre pico ordinateur.
Carte Shield
Description
La carte Shield est une carte mère qui sert à connecter et contrôler divers périphériques, notamment la carte fille (écran), un clavier, et d'autres composants. Nous avons conçu cette carte pour faciliter la gestion des communications SPI entre la carte mère et les différentes cartes filles.
Connectivité SPI
La carte Shield utilise plusieurs lignes SPI pour communiquer avec les cartes filles. Chaque périphérique, comme l'écran, est assigné à une ligne SPI spécifique. La carte Shield vérifie également la disponibilité des périphériques avant d'envoyer des commandes via SPI. Nous avons effectué plusieurs test afin de vérifier le bon fonctionnement de notre carte Shield. Nous avons tester le fonctionnement des LED, la connectivité de la carte SD, et nous avons utiliser le Shield pour faire un timer sur un afficheur 7 segments.
Tests Réalisés
Tests de l'Ordonnanceur //acompleter
- Gestion des tâches : Nous avons simulé plusieurs tâches, dont l'affichage et la gestion du clavier, et vérifié que l'ordonnanceur passe correctement d'une tâche à l'autre.
- En utilisant le logiciel minicom nous avons pus lancer une 2eme tâche en parallèle d'une première tâche. En tapant "a" une deuxième LED se met a clignoter.
- //image et video
Tests de la RAM SPI //a completer
- Stockage des données d'affichage :