Je continue dans ma quête pour la création d'une horloge. Je sme suis donc acheter le module DS3231 qui permet de donner l'heure en I2c.
Je me suis donc tourner dans la partie tuto du forum fantaspic pour y trouver mon bonheur.
J'ai donc suivi ce super tuto de Jérémy et j'ai essayé de l'adapter pour un 16F887, mais sous simulation je n'ai aucun résultat. J'essaie juste d'afficher l'heure sur un LCD mais rien ne se passe. L’écran reste a 00:00:00. J'ai pourtant trouver d'autres exemples sur internet qui font le travail. Mais mon code pas moyen.
Voici le code :
Code : Tout sélectionner
#define RTC_ADDR 0xD0 // Adresse I²C de l'esclave ( DS3231)
// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
unsigned char heures, minutes, secondes;
char oldstate = 0;
// Prototypes
unsigned short Bcd2Dec(unsigned short decnum);
unsigned short Dec2Bcd(unsigned short decnum);
/****************************************************************************
* Fonction: Lire les données sur le RTC
* parametre d'entrée : adresse du registre à lire
* parametre de sortie : valeur lue dans le registre
**********************************************************************************/
unsigned char RTC_Read(unsigned char addr){
unsigned char value; // Déclaration variable temporaire
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(addr); // adresse du registre à lire
I2C1_Start(); // On répète le signal de départ
I2C1_Wr(RTC_ADDR); // Adresse du DS1307
value = I2C1_Rd(0); // lecture et enregistrement de la valeur le 0=pour no ACK
I2C1_Stop(); // Arrêt de l'I²C
return value; // On retourne la valeur lue
}
/**************************************************************************************************
* Fonction: Ecrire les données sur le DS1307
* parametre d'entrée : adresse du registre à ecrire + valeur à y mettre
**************************************************************************************************/
void RTC_Write(unsigned char addr, unsigned char value){
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(addr); // adresse du registre à écrire
I2C1_Wr(value); // On écrit la valeur dans le registre
I2C1_Stop(); // Arrêt de l'I²C
}
/**************************************************************************************************
* Fonction: Ecrire le Groupe Date Heure sur appui du BP
* parametre d'entrée : Les 7 valeurs du GDH à initialiser
**************************************************************************************************/
void Ecrire_GDH (unsigned char heures , unsigned char minutes, unsigned char secondes){
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(0); // Met le pointeur à cette adresse ( N° registre)
secondes = Dec2Bcd(secondes); // Conversion de décimal en BCD pour le RTC
I2C1_Wr(secondes); // On écrit la valeur dans le registre des secondes
minutes = Dec2Bcd(minutes); // Après écriture la valeur du pointeur du registre est incrémenter automatiquement
I2C1_Wr(minutes); // On peut enchainer directement avec la prochaine valeur
heures = Dec2Bcd(heures); // etc ... toutes à la suite.
I2C1_Wr(heures);
I2C1_Stop(); // Arrêt de l'I²C
}
/**************************************************************************************************
* Fonction: Lit le Groupe Date Heure sur le RTC pour mettre à jour l'affichage
**************************************************************************************************/
void Lecture_GDH(){
I2C1_Start(); // Début de l'I²C
I2C1_Wr(RTC_ADDR); // Adresse du RTC ( 0xD0 cf datasheet)
I2C1_Wr(0); // lecture à cette adresse ( N° registre)
I2C1_Repeated_Start(); // On répète le signal de départ
I2C1_Wr(RTC_ADDR+1); // Adresse du DS1307 (1=lire / 0=ecrire)
secondes = I2C1_Rd(1); // Lecture et enregistrement de la valeur
secondes = Bcd2Dec(secondes); // Conversion de BCD en décimal pour l'afficheur
minutes = I2C1_Rd(1);
minutes = Bcd2Dec(minutes);
heures = I2C1_Rd(1);
heures = Bcd2Dec(heures);
I2C1_Stop(); // Arrêt de l'I²C
}
/*##################################################################################
########################## PROGRAMME PRINCIPAL ###############################
##################################################################################*/
void main(){
OSCCON = 0b01110000; // configuration OSCCON interne 8mhz
// 0b01110000 oscillateur 8 Mhz
// 0b01101000 oscillateur 4 Mhz
// 0b01011000 oscillateur 2 Mhz
// 0b01001000 oscillateur 1 Mhz
// 0b00111000 oscillateur 500 Khz
// 0b00101000 oscillateur 250 Khz
// 0b00011000 oscillateur 125 Khz
// 0b00001000 oscillateur 31 kHz
while(OSCCON.HTS==0); // boucle en attendant de voir le flag à 1
ANSEL = 0; // Configure AN pins as digital I/O
ANSELH = 0;
C1ON_bit = 0; // Disable comparators
C2ON_bit = 0;
TRISA0_bit = 1; // Met RA0 en entrée pour le BP.
// Utilisé pour initialisé l'horloge avec une valeur enregistrée
I2C1_Init(100000); // Initialise le BUS I2C
Lcd_Init(); // Initialise le Lcd
Lcd_Cmd(_LCD_CLEAR); // Efface écran
Lcd_Cmd(_LCD_CURSOR_OFF); // Curseur off
Delay_ms(3000); // pause 3 sec
Lcd_Cmd(_LCD_CLEAR); // Efface l'écran
LCD_Out(1,1,"DS3231 Clock :"); // le 20 c'est pour l'année 20xx
LCD_Out(2,1,"Heure:"); // On écrit la matrice du texte statique
LCD_Chr(2,11,':');
LCD_Chr(2,14,':');
/*##################################################################################
############################ BOUCLE INFINIE ##################################
##################################################################################*/
while(1){
if (Button(&PORTA, 0, 1, 0))oldstate = 1; // Anti-rebond
if (oldstate && Button(&PORTA, 0, 1, 1)) { // Si le BP est appuyé on envoi le GDH suivant
Ecrire_GDH( 23, 59, 50); //heure: min: sec
oldstate = 0; // mise à 0 du flag
}
Lecture_GDH(); // On va lire notre DS1307
Lcd_Chr(2,9, (heures / 10) + 48); // Deuxième lignes 9iéme caractère dizaine des heures
Lcd_Chr(2,10, (heures % 10) + 48); // Unité des heures
Lcd_Chr(2,12, (minutes / 10) + 48);
Lcd_Chr(2,13, (minutes % 10) + 48);
Lcd_Chr(2,15, (secondes / 10) + 48);
Lcd_Chr(2,16, (secondes % 10) + 48);
Delay_mS(10); // pause de 10ms
}
}
Si une ame charitable serait me dire ou j'ai fauté ?
D'avance merci. Après j'ai "bêtement" copier les routines de Jérémy c'est peut être différant sur un DS3231 qu'un DS1307 ?
Ps: J'utilise l'oscillateur interne a 8Mhz. Voici mon config Mikroc au cas ou :
@++