« SE4Binome2023-9 » : différence entre les versions
Aucun résumé des modifications |
Aucun résumé des modifications |
||
Ligne 146 : | Ligne 146 : | ||
Voici l'affichage de "test": | Voici l'affichage de "test": | ||
[[Fichier:7seg 7.mp4|centré|vignette|]] | [[Fichier:7seg 7.mp4|centré|vignette|]] | ||
=== Matrice LED === | === Matrice LED === | ||
Voici notre fonction pour envoyer un carcatère à la matrice : | |||
<syntaxhighlight lang="c"> | |||
void aff_matrix(void){ | |||
char a; | |||
int index; | |||
while(1){ | |||
P(SEM_SPI); | |||
index = selection(caractere_partage); | |||
spi_activer(SS_2); | |||
_wait_ms(1); | |||
for(int LED=0; LED<8; LED++){ | |||
for(int j=0; j<8;j++){ | |||
a = hex[index][LED] & (1<<j); | |||
spi_echange(a); | |||
} | |||
} | |||
spi_desactiver(SS_2); | |||
_wait_ms(500); | |||
V(SEM_SPI); | |||
} | |||
} | |||
</syntaxhighlight> | |||
Voici une vidéo du fonctionnement : | |||
[[Fichier:Video3.mp4|centré|vignette]] | [[Fichier:Video3.mp4|centré|vignette]] | ||
Nous avons écrit un tableau stockant les configurations de chaque chiffre hexadécimal : | |||
<syntaxhighlight lang="c"> | |||
char hex[16][8] = { | |||
{0x7e,0x42,0x42,0x42,0x42,0x42,0x7e,0x00}, //--> 0 | |||
{0x08,0x18,0x28,0x08,0x08,0x08,0x3e,0x00}, //--> 1 | |||
{0x18,0x24,0x04,0x08,0x10,0x20,0x7c,0x00}, //--> 2 | |||
{0x18,0x24,0x04,0x18,0x04,0x04,0x38,0x00}, //--> 3 | |||
{0x20,0x20,0x24,0x24,0x3e,0x04,0x04,0x00}, //--> 4 | |||
{0x7e,0x40,0x40,0x7e,0x02,0x02,0x7e,0x00}, //--> 5 | |||
{0x7e,0x40,0x40,0x7e,0x42,0x42,0x7e,0x00}, //--> 6 | |||
{0x7f,0x02,0x04,0x08,0x10,0x20,0x40,0x00}, //--> 7 | |||
{0x3c,0x42,0x42,0x3c,0x42,0x42,0x3c,0x00}, //--> 8 | |||
{0x7e,0x42,0x42,0x7e,0x02,0x02,0x7e,0x00}, //--> 9 | |||
{0x18,0x24,0x42,0x42,0x7e,0x42,0x42,0x42}, //--> A | |||
{0x7c,0x42,0x42,0x42,0x7c,0x42,0x42,0x7e}, //--> B | |||
{0x7e,0x40,0x40,0x40,0x40,0x40,0x40,0x7e}, //--> C | |||
{0x78,0x44,0x42,0x42,0x42,0x42,0x42,0x7c}, //--> D | |||
{0x7e,0x40,0x40,0x7e,0x40,0x40,0x40,0x7e}, //--> E | |||
{0x7e,0x40,0x40,0x7c,0x40,0x40,0x40,0x40}, //--> F | |||
}; | |||
</syntaxhighlight> | |||
Nous avons aussi fait une fonction pour faire correspondre le caractère partagé au bon index du tableau précédent : | |||
<syntaxhighlight lang="c"> | |||
int selection(char select)// pour choisir l index dans le tableau pour la matrice | |||
{ | |||
int result = 0; | |||
if(select >= '0' && select <= '9') | |||
result = select - 48; | |||
else if(select >= 'a' && select <= 'f') | |||
result = 10 + (select - 'a'); | |||
else if(select >= 'A' && select <= 'F') | |||
result = 10 + (select - 'A'); | |||
return result; | |||
} | |||
</syntaxhighlight> | |||
Version du 11 décembre 2023 à 09:50
Ordonnanceur / SE
Matériel pour l'ordonnanceur
Test du bouclier
Pour tester le bon fonctionnement des LED, nous avons simplement écrit un code avec PORTB
, PORTC
etPORTD
à 0xFF
(le code est disponible sur le git) :
Programmation du timer1
Il est demandé de générer une interruption toutes les 20 ms. En nous inspirant du code présent sur cette page, nous avons pu, par le biais d'interruptions, allumer la LED d'un Arduino Uno.
Pour générer une interruption toutes les 20 ms, il est nécessaire de régler le nombre de "ticks" et donc la valeur du registre OCR1A
. On aura alors OCR1A = 1250
pour une pré-division de la fréquence d'horloge de 256.
Ordonnanceur basique
Après avoir programmé le timer1 pour qu'il déclenche une interruption toutes les 20 ms, nous avons besoin d'écrire dans l'ISR (avec une la sauvegarde et la récupération du contexte :
/*code...*/
ISR(TIMER1_COMPA_vect,ISR_NAKED)
{
/* Sauvegarde du contexte de la tâche interrompue */
portSAVE_CONTEXT();
taches[current_task].ppile = SP;
/* Appel à l'ordonnanceur */
scheduler();
SP = taches[current_task].ppile;
/* Récupération du contexte de la tâche ré-activée */
portRESTORE_CONTEXT();
asm volatile ( "reti" );
}
/*code...*/
Ainsi qu'une fonction init_task
, qui s'occupera d'initialiser toutes les tâches à part la première (pile vide au début, pas nécessaire) :
void init_task()
{
for(uint8_t i = 1; i < NB_TASK ; i++){
uint16_t save = SP;
SP = taches[i].ppile;
uint16_t adresse=(uint16_t)taches[i].fct;
asm volatile("push %0" : : "r" (adresse & 0x00ff) );
asm volatile("push %0" : : "r" ((adresse & 0xff00)>>8) );
portSAVE_CONTEXT();
taches[i].ppile=SP;
SP = save;
}
}
Voici une vidéo où l'on fait clignoter deux LED avec un temps différent :
Lecture/écriture sur le port série
void serial_send(unsigned char c)
{
P(SEM_SERIAL);
task_current->etat=(WAIT_SERIAL|STATE_SLEEP);
TIMER1_COMPA_vect();
UDR0 = c;
V(SEM_SERIAL);
}
char get_serial(void){
P(SEM_SERIAL);
task_current->etat=(WAIT_SERIAL|STATE_SLEEP);
TIMER1_COMPA_vect();
V(SEM_SERIAL);
return UDR0;
}
Afficheur 7 segments
Pour tester l'afficheur 7 segments, nous avons utilisé un programme d'envoi SPI. Nous n'avons toutefois pas encore compris comment afficher un caractère spécifique, nous avons réussi seulement pour l'instant à afficher une série de 0 :
Après avoir consulté les ressources SparkFun, nous avons pu écrire cette fonction, qui prend en compte le caractère partagé :
void aff7seg(void)
{
P(SEM_SPI);
spi_activer(SS_3);
spi_echange(0x76);
spi_desactiver(SS_3);
V(SEM_SPI);
while(1){
P(SEM_SPI);
spi_activer(SS_3);
for(int i = 0; i<4 ; i++)
spi_echange(caractere_partage);
spi_desactiver(SS_3);
_wait_ms(50);
V(SEM_SPI);
}
}
Voici l'affichage de "test":
Matrice LED
Voici notre fonction pour envoyer un carcatère à la matrice :
void aff_matrix(void){
char a;
int index;
while(1){
P(SEM_SPI);
index = selection(caractere_partage);
spi_activer(SS_2);
_wait_ms(1);
for(int LED=0; LED<8; LED++){
for(int j=0; j<8;j++){
a = hex[index][LED] & (1<<j);
spi_echange(a);
}
}
spi_desactiver(SS_2);
_wait_ms(500);
V(SEM_SPI);
}
}
Voici une vidéo du fonctionnement :
Nous avons écrit un tableau stockant les configurations de chaque chiffre hexadécimal :
char hex[16][8] = {
{0x7e,0x42,0x42,0x42,0x42,0x42,0x7e,0x00}, //--> 0
{0x08,0x18,0x28,0x08,0x08,0x08,0x3e,0x00}, //--> 1
{0x18,0x24,0x04,0x08,0x10,0x20,0x7c,0x00}, //--> 2
{0x18,0x24,0x04,0x18,0x04,0x04,0x38,0x00}, //--> 3
{0x20,0x20,0x24,0x24,0x3e,0x04,0x04,0x00}, //--> 4
{0x7e,0x40,0x40,0x7e,0x02,0x02,0x7e,0x00}, //--> 5
{0x7e,0x40,0x40,0x7e,0x42,0x42,0x7e,0x00}, //--> 6
{0x7f,0x02,0x04,0x08,0x10,0x20,0x40,0x00}, //--> 7
{0x3c,0x42,0x42,0x3c,0x42,0x42,0x3c,0x00}, //--> 8
{0x7e,0x42,0x42,0x7e,0x02,0x02,0x7e,0x00}, //--> 9
{0x18,0x24,0x42,0x42,0x7e,0x42,0x42,0x42}, //--> A
{0x7c,0x42,0x42,0x42,0x7c,0x42,0x42,0x7e}, //--> B
{0x7e,0x40,0x40,0x40,0x40,0x40,0x40,0x7e}, //--> C
{0x78,0x44,0x42,0x42,0x42,0x42,0x42,0x7c}, //--> D
{0x7e,0x40,0x40,0x7e,0x40,0x40,0x40,0x7e}, //--> E
{0x7e,0x40,0x40,0x7c,0x40,0x40,0x40,0x40}, //--> F
};
Nous avons aussi fait une fonction pour faire correspondre le caractère partagé au bon index du tableau précédent :
int selection(char select)// pour choisir l index dans le tableau pour la matrice
{
int result = 0;
if(select >= '0' && select <= '9')
result = select - 48;
else if(select >= 'a' && select <= 'f')
result = 10 + (select - 'a');
else if(select >= 'A' && select <= 'F')
result = 10 + (select - 'A');
return result;
}
Implémentation de "sleep"
Ordonnacement complet
Carte FPGA / VHDL
Carte électronique numérique
Type carte choisi
Carte mère
Caractéristiques de la carte mère
ReX : a mettre comme sous-section de la section "Carte électronique numérique"*
ReX : utilisez la syntaxe mediawiki pour les items.
- Alimentation : USB
- Tension alimentation : 5V avec régulateur
- Programmation par AVR ISP
Schématique/Routage
Voici la schématique de la carte mère ainsi que du programmateur :
Voici le routage de la carte:
Voici la vue 3D de la carte:
Rendus
GIT
https://archives.plil.fr/yelqasta/pico_ybenmbar_yelqasta_se4.git