Cours:TPS 2103 tp horlogeI2c
Sommaire
Contexte : l'afficheur LCD alphanumérique
Ce type d'afficheur permet d'afficher un certain nombre de caractères ( lettre, chiffre, caractères spéciaux).
Ces afficheurs se distinguent principalement par :
- le nombre de caractères par ligne
- le nombre de lignes
- la couleur de rétroéclairage
- sa dimension
L'afficheur est donc découpé en cases, chacune étant un caractère de la table ASCII (American Standard Code for Information Interchange) :
- chaque caractère est associé à un nombre
- les codes ASCII de 0 à 127 sont les codes standards
- les codes de 128 à 255 sont les codes étendus
Remarque : le code ASCII est rarement utilisé directement, les insctructions suivantes sont équivalentes :
char c;
c='A';
c=0x41;
c=65;
c=0b01000001;
L'afficheur possède 16 broches, détaillées ci-contre. Parmi celles-ci, 11 broches sont utiles pour dialoguer avec l'afficheur : RS , R/W , E , D[7..0] Le bus de données peut-être configuré en mode 8 bits ou 4 bits afin de limiter le nombre de broches nécessaires. Dans ce cas il faudra 2 périodes pour transférer une donnée ( 2 x 4 bits). Ce bus est de type parallèle, half-duplex, synchrone ( signal E ) Il sert à la fois pour :
|
Pinout de l'afficheur utilisé :
|
écran LCD et GPIO expander
Nous allons utiliser le shield i2c utilisé lors du TP précédent pour connecter l'écran sur la carte arduino Nano que nous allons programmer.
Ce ShieldLCD comporte un écran LCD avec son potentiomètre de réglage du contraste ainsi 6 boutons poussoirs. Il est fait pour être utilisé avec une carte Arduino UNO mais fonctionne aussi sur un Arduino MEGA.
Ici nous allons utiliser une librairie modifiée pour l'utilisation au travers d'un MCP23017.
Télécharger la librairie donnée dans la partie ressources, et exécuter le programme d'exemple suivant pour vérifier le bon fonctionnement
#include <Wire.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
int32_t time=0;
int main()
{
sei();
Serial.begin(9600);
lcd.begin(16, 2);
lcd.print("Hello, world!");
Serial.print("Took "); Serial.print(time); Serial.println(" ms");
uint8_t i=0;
while(1)
{
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(time);
time++;
_delay_ms(1000);
}
}
horloge i2c : DS1307
Nous allons ajouter une horloge i2c, et utiliser l'écran LCD pour afficher l'heure sous la forme
Lun 28 Mar 2022 05 :36 :54
Attention :
- il conviendra d'ajouter au besoin un 0 pour conserver un affichage de chaque champ (heure/minute/seconde) sur 2 caractères.
- jour/mois seront affichés sur 3/4 caractères
Connecter cette target i2c et lister à l'aide d'un logiciel "i2c scanner" les périphériques i2c.
En utilisant ladatasheet du circuit DS1307 en déduire l'adresse configurée du composant
Ecrire un programme permettant d'afficher la date sous la forme demandée
Remarques :
- le bit CH doit être mis à 0 pour que l'horloge fonctionne
- il est judicieux d'utiliser un tableau de chaînes de caractères pour les jours/mois
- const char* jours[]={"Lun","Mar",....};
- Le codage BCD est utilisé :
- pour coder en binaire le nombre 45
- on code 5 en binaire : 0101
- on code 4 en binaire : 0100
- le code bcd de 45 sur 8 bits est : 01000101
- le chiffre des dizaines n'est pas nécessairement codé sur 4 bits (dépend de la valeur maximale)
- pour convertir un nombre bcd en code ascii :
- trouver la valeur des unités en masquant les bits des dizaines.
- trouver la valeur des dizaines en masquant les unités et en faisant un décalage
- pour convertir un nombre en code ASCII, ajouter 0x30 : char c=n+0x30;
- pour coder en binaire le nombre 45
- Vous pouvez vous servir de la date de compilation de votre programme pour initialiser l'horloge, ci dessous un programme d'exemple affichant l'heure et la date de compilation sur la liaison série.
char Month[12];
uint16_t Year;
uint8_t Day, monthIndex;
const char *monthName[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
sscanf(__DATE__, "%s %d %d", Month, &Day, &Year);
for (monthIndex = 0; monthIndex < 12; monthIndex++) {
if (strcmp(Month, monthName[monthIndex]) == 0) break;
}
Serial.print(Month);
Serial.print(" : ");
Serial.println(monthIndex);
Serial.println(Day);
Serial.println(Year);
uint16_t Hour, Min, Sec;
sscanf(__TIME__, "%d:%d:%d", &Hour, &Min, &Sec);
Serial.println(Hour);
Serial.println(Min);
Serial.println(Sec);
Réglage de l'heure
Les boutons sont reliés directement à la carte Arduino via la nappe I2C.
Pour limiter le nombre d’entrée pour les cinq boutons, on utilise qu’une seule entrée analogique A2.
Chaque bouton modifie un pont diviseur de tension.
Suivant la valeur de la tension mesurée on sait quel bouton est appuyé.
Le bouton Reset est relié directement à l’entrée numérique D13. (ne fonctionne pas !!)
Utiliser les boutons pour permettre un réglage de l'heure
Ressources
- Librairie arduino pour l'afficheur i2c Fichier:Adafruit RGB LCD i2cShield.zip
- datasheet DS1307