J'ai réglé le problème merci!
A+!
marC
-----
J'ai réglé le problème merci!
A+!
marC
Re-Bonsoir!
J'ai un nouveau projet. Mon projet consiste à faire un timer avec un 6 afficheurs 7 segments et un keypad.
Là! Je suis pris.... pour commencer il faudrait j'affiche les valeurs entrées du keypad sur les afficheurs, je ne sais pas comment m'y prendre pcq il y a quand même 6 afficheurs.
Voyez mon code :
C'est vraiment dans la fonction enter_code() que j'ai de la misère...Code://------ Function to Return mask for common anode 7-seg. display unsigned short mask(unsigned short num) { switch (num) { case 0 : return 0xC0; case 1 : return 0xF9; case 2 : return 0xA4; case 3 : return 0xB0; case 4 : return 0x99; case 5 : return 0x92; case 6 : return 0x82; case 7 : return 0xF8; case 8 : return 0x80; case 9 : return 0x90; } //case end } void Display_Time() { for (i = 0; i<=50; i++) { PORTC = DD0; RB0_bit = 0; // Select Ones Digit RB1_bit = 1; RB2_bit = 1; RB3_bit = 1; RB4_bit = 1; RB5_bit = 1; delay_ms(1); PORTC = DD1; RB0_bit = 1; RB1_bit = 0; // Select Tens Digit RB2_bit = 1; RB3_bit = 1; RB4_bit = 1; RB5_bit = 1; delay_ms(1); PORTC = DD2; RB0_bit = 1; RB1_bit = 1; RB2_bit = 0; // Select Hundreds Digit RB3_bit = 1; RB4_bit = 1; RB5_bit = 1; delay_ms(1); PORTC = DD3; RB0_bit = 1; RB1_bit = 1; RB2_bit = 1; RB3_bit = 0; RB4_bit = 1; RB5_bit = 1; delay_ms(1); PORTC = DD4; RB0_bit = 1; RB1_bit = 1; RB2_bit = 1; RB3_bit = 1; RB4_bit = 0; RB5_bit = 1; delay_ms(1); PORTC = DD5; RB0_bit = 1; RB1_bit = 1; RB2_bit = 1; RB3_bit = 1; RB4_bit = 1; RB5_bit = 0; delay_ms(1); } } kp = Keypad_Key_Click(); // Store key code in kp variable while (!kp); switch (kp) { case 1 : kp = '1'; if (i == 1) time_HH if (i == 2) time_HH break; case 2 : kp = '2'; break; // 2 case 3 : kp = '3'; break; // 3 case 5 : kp = '4'; break; // 4 case 6 : kp = '5'; break; // 6 case 7 : kp = '6'; break; // 7 case 9 : kp = '7'; break; // 9 case 10 : kp = '8'; break; // 10 case 11 : kp = '9'; break; // 11 case 13 : kp = 42; break; // * case 14 : kp = 48; break; // 0 case 15 : kp = 35; break; // # } i++; }
il faut savoir sur quel afficheur afficher la valeur du code entrée.... la première valeur est supposé de s'afficheur sur le 1er afficheur à gauche, la deuxième valeur sur le deuxième afficheur, etc ...
il faut tester avec un compteur... mais.. voyez mon main() :
je voudrais savoir quel serait le meilleur moyen d'afficheur chaque valeur une après l'autre sur chacun des afficheurs..Code:Keypad_Init(); // Initialize keypad time_HH = 0; time_MM = 0; time_SS = 0; do { DD0 = time_SS%10; DD0 = mask(DD0); DD1 = time_SS/10; DD1 = mask(DD1); DD2 = time_MM%10; // Extract Hundreds Digit DD2 = mask(DD2); DD3 = time_MM/10; // Extract Thousands Digit DD3 = mask(DD3); DD4 = time_HH%10; DD4 = mask(DD4); DD5 = time_HH/10; DD5 = mask(DD5); code_enter(); Display_Time(); } while(1); }
Merci beaucoup!
Bonne nuit!
A+!
marC
Salut,
on ne gère pas ainsi un afficheur 7 segments.
Il faut utiliser les interruptions.
Patiente un peu ce sera traité dans mon exposé sur le C prochainement.
@+
Merci Hulk!
A+!
marC
Bonjour!
Je suis en train de programmation un réveil matin, mais le problème c'est que je voudrais que le buzzer sonne tout le temps jusqu'à ce que je ferme la switch pour l'éteindre. Moi j'ai fais la programmation pour qu'il sonne quand l'heure courante est égale l'heure du réveil, quand il passe à la prochaine minute; le buzzer ne se fait plus entendre. Comment pourrais-je m'y prendre?... Je suis vraiment pris ici.
Merci de votre aide!
A+!
marC
Voici mon code :
merci!Code:/****************************************** * Marc HORLOGE 7 segment COMPLET avec * * affichage des secondes en temps réel * * sur afficheur géant 1 pouces 3/4 * * Microcontrôleur utilisé PIC16F887 * * de type HH.MM.SS * * Avec quartz 4 Mhz pour précision * * 2 ULN2003 un pour les 7 cathodes * * 1 autre cathode * * Date début : 15-01-2013 * * Date fin : 14-02-2013 * * Copyright (c) Marc Paradis 2013 * *******************************************/ // PORT A # define LED_BIT F1 // PORT B # define BUZZER_BIT F7 // Port E # define BIT_BP_HEURE F0 # define BIT_BP_MINUTE F1 # define BIT_BP_SET_ALARME F2 # define ALARME_ON_OFF F3 // Début déclaration variables unsigned short i, DD0, DD1, DD2, DD3, DD4, DD5; unsigned short Num; unsigned short compteur, drapeau_minute=0, drapeau_heure=0, drapeau_alarme=0, unit; unsigned short count_heure_horloge=0, count_heure_horloge_alarme=0; unsigned short count_minute_horloge=0, count_minute_horloge_alarme=0; unsigned short secondes, OneSec; unsigned short heure_reveil = 0; unsigned short int transition_bp_heure = 0; unsigned short int transition_bp_minute = 0; unsigned short int transition_bp_alarme = 0; unsigned short int etatanterieur_bp_heure = 1; // BP ouvert lors de la derniere scrutation unsigned short int etatanterieur_bp_minute = 1; unsigned short int etatanterieur_bp_alarme = 1; unsigned short int etat_port; // variable temporaire unsigned short memoire_heure_alarme1[1]; unsigned short memoire_heure_alarme2[1]; unsigned short memoire_minute_alarme1[1]; unsigned short memoire_minute_alarme2[1]; char message_EEPROM[] = "Copyright 2013 Marc Paradis"; char Edata[] = "000000000000000000000000000"; unsigned int ADD; // Start EEPROM Location char temp; // Fin déclaration variables void delay_20ms() { delay_ms(20); } void Lire_Alarme_EEPROM() // Read data from EEPROM { memoire_heure_alarme2[0] = EEPROM_Read(0x00); // Read data from adress 0 memoire_heure_alarme1[0] = EEPROM_Read(0x01); // Read data from adress 2 memoire_minute_alarme2[0] = EEPROM_Read(0x02); // Read data from adress 4 memoire_minute_alarme1[0] = EEPROM_Read(0x03); // Read data from adress 8 } void Ecrire_Alarme_EEPROM() // Write data from EEPROM { EEPROM_Write(0x00, memoire_heure_alarme2[0]); // Write some data at adress 00 EEPROM_Write(0x01, memoire_heure_alarme1[0]); // Write some data at adress 02 EEPROM_Write(0x02, memoire_minute_alarme2[0]); // Write some data at adress 04 EEPROM_Write(0x03, memoire_minute_alarme1[0]); // Write some data at adress 09 } //------ Function to Return mask for common cathode 7-seg. display en hexadécimal unsigned short mask(unsigned short num) { switch (num) { case 0 : return 0x3F; case 1 : return 0x06; case 2 : return 0x5B; case 3 : return 0x4F; case 4 : return 0x66; case 5 : return 0x6D; case 6 : return 0x7D; case 7 : return 0x07; case 8 : return 0x7F; case 9 : return 0x6F; } } //------ Function to Return mask2 for common cathode + un . à la fin en hexadécimal unsigned short mask2(unsigned short num) { switch (num) { case 0 : return 0xBF; // 0. case 1 : return 0x86; // 1. case 2 : return 0xDB; // 2. case 3 : return 0xCF; // 3. case 4 : return 0xE6; // 4. case 5 : return 0xED; // 5. case 6 : return 0xFD; // 6. case 7 : return 0x87; // 7. case 8 : return 0xFF; // 8. case 9 : return 0xEF; // 9. } } void Debounce(){ Delay_ms(300); } void Afficher_Heure() { for (i = 0; i<=50; i++) { PORTC = DD0; RD0_bit = 1; // 19 // Select Ones Digit RD1_bit = 0; // 20 RD2_bit = 0; // 21 RD3_bit = 0; // 22 RD4_bit = 0; // 27 RD5_bit = 0; // 28 delay_ms(2); PORTC = DD1; RD0_bit = 0; RD1_bit = 1; RD2_bit = 0; RD3_bit = 0; RD4_bit = 0; RD5_bit = 0; delay_ms(2); PORTC = DD2; RD0_bit = 0; RD1_bit = 0; RD2_bit = 1; RD3_bit = 0; RD4_bit = 0; RD5_bit = 0; delay_ms(2); PORTC = DD3; RD0_bit = 0; RD1_bit = 0; RD2_bit = 0; RD3_bit = 1; RD4_bit = 0; RD5_bit = 0; delay_ms(2); PORTC = DD4; RD0_bit = 0; RD1_bit = 0; RD2_bit = 0; RD3_bit = 0; RD4_bit = 1; RD5_bit = 0; delay_ms(2); PORTC = DD5; RD0_bit = 0; RD1_bit = 0; RD2_bit = 0; RD3_bit = 0; RD4_bit = 0; RD5_bit = 1; delay_ms(2); } } // ISR // À chaque débordement du TMR0 on passe par ici, il compte de 12 à 255 void interrupt() { if ( (T0IF) && (drapeau_heure == 0) && (drapeau_minute == 0)) { Num++; EEPROM_Write(0x00, count_heure_horloge_alarme/10); EEPROM_Write(0x01, count_heure_horloge_alarme%10); EEPROM_Write(0x02, count_minute_horloge_alarme/10); EEPROM_Write(0x03, count_minute_horloge_alarme%10); if(Num == 16) { // à chaque seconde... Num = 0; OneSec++; // Increase sec secondes = secondes + 1; } if (OneSec == 60) // à chaque minute (60 secondes = 1 minute) { // réinitialisation du compteur OneSec pour donner // toujours 60 secondes à chaque fois sinon on le perd... secondes = 0; OneSec = 0; count_minute_horloge = count_minute_horloge + 1; if (count_minute_horloge == 60) { count_minute_horloge = 0; count_heure_horloge = count_heure_horloge + 1; if (count_heure_horloge == 24) count_heure_horloge = 0; } } TMR0 = 12; INTCON.T0IF = 0; // Bit T0IF is cleared so that the interrupt could reoccur } } unsigned short int Test_Heure_Reveil() { if ( (count_heure_horloge == count_heure_horloge_alarme) && (count_minute_horloge == count_minute_horloge_alarme) ) return 1; return 0; } unsigned short int test_bp_set_heure() { // test du bouton poussoir SET_HEURE etat_port = PORTE.BIT_BP_HEURE; // lecture du niveau du port if ((etat_port == 0) && (etatanterieur_bp_heure == 1)) { etatanterieur_bp_heure = etat_port; return 1; // BP a été appuyé } else { etatanterieur_bp_heure = etat_port; return 0; // BP inactif } } unsigned short int test_bp_set_minute() { // test du bouton poussoir SET MINUTE etat_port = PORTE.BIT_BP_MINUTE; // lecture du niveau du port if ((etat_port == 0) && (etatanterieur_bp_minute == 1)) { etatanterieur_bp_minute = etat_port; return 1; // BP a été appuyé } else { etatanterieur_bp_minute = etat_port; return 0; // BP inactif } } unsigned short int test_bp_set_alarme() { // test du bouton poussoir SET_ALARME etat_port = PORTE.BIT_BP_SET_ALARME; // lecture du niveau du port if ((etat_port == 0) && (etatanterieur_bp_alarme == 1)) { etatanterieur_bp_alarme = etat_port; return 1; // BP a été appuyé } else { etatanterieur_bp_alarme = etat_port; return 0; // BP inactif } } void main() { ADCON0 = 0x00; // turn off ADC module ANSEL = 0; // Configure AN pins as digital I/O ANSELH = 0; C1ON_bit = 0; // Disable comparators C2ON_bit = 0; TRISA = 0x00; TRISB = 0x00; // Set PORTB direction to be output TRISC = 0x00; TRISD = 0x00; TRISE = 0b0001111; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; // initialisation de l'heure à 10.30.00 // alarme à 6.30.00 count_heure_horloge = 10; count_minute_horloge = 30; count_heure_horloge_alarme = 6; count_minute_horloge_alarme = 30; secondes = 0; Num = 0; OneSec = 0; PORTA.LED_BIT = 1; // LED témoin pour l'horloge PIC 3 Sound_Init(&PORTB, PORTB.BUZZER_BIT); // Buzzer OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0 TMR0 = 12; // Timer T0 counts from 12 to 255 INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts Lire_Alarme_EEPROM(); do { DD0 = secondes%10; // 2ième digit seconde DD0 = mask(DD0); DD1 = secondes/10; // 1er digit seconde DD1 = mask(DD1); if (drapeau_alarme == 0) { // mask2 pour que le 2ième digit aie un . à la fin pour faire type horloge DD2 = count_minute_horloge%10; // 2ieme digit minute DD2 = mask2(DD2); DD3 = count_minute_horloge/10; // 1er digit minute DD3 = mask(DD3); // mask2 pour que le 2ième chiffre aie un . à la fin pour faire type horloge DD4 = count_heure_horloge%10; // 2ieme digit heure DD4 = mask2(DD4); DD5 = count_heure_horloge/10; // 1er digit heure DD5 = mask(DD5); } if (drapeau_alarme == 1) { // mask2 pour que le 2ième digit aie un . à la fin pour faire type horloge DD2 = count_minute_horloge_alarme%10; // 2ieme digit minute DD2 = mask2(DD2); DD3 = count_minute_horloge_alarme/10; // 1er digit minute DD3 = mask(DD3); // mask2 pour que le 2ième chiffre aie un . à la fin pour faire type horloge DD4 = count_heure_horloge_alarme%10; // 2ieme digit heure DD4 = mask2(DD4); DD5 = count_heure_horloge_alarme/10; // 1er digit heure DD5 = mask(DD5); } transition_bp_heure = test_bp_set_heure(); transition_bp_minute = test_bp_set_minute(); transition_bp_alarme = test_bp_set_alarme(); if (transition_bp_heure == 1) { drapeau_heure = 1; if (drapeau_alarme == 0) { count_heure_horloge = count_heure_horloge + 1; if (count_heure_horloge == 24) count_heure_horloge = 0; } if (drapeau_alarme == 1) { count_heure_horloge_alarme = count_heure_horloge_alarme + 1; if (count_heure_horloge_alarme == 24) count_heure_horloge = 0; } } // if (transition_bp_heure) if (transition_bp_minute == 1) { drapeau_minute = 1; if (drapeau_alarme == 0) { count_minute_horloge = count_minute_horloge + 1; if (count_minute_horloge == 60) count_minute_horloge = 0; } if (drapeau_alarme == 1) { count_minute_horloge_alarme = count_minute_horloge_alarme + 1; if (count_minute_horloge == 60) count_minute_horloge_alarme = 0; } } // if (transition_bp_minute) // si la switch du réveil est à ON, on teste si c'est l'heure du réveil // sinon on ignore le if if (!PORTB.ALARME_ON_OFF) { heure_reveil = Test_Heure_Reveil(); // si c'est l'heure du réveil if (heure_reveil == 1) Sound_Play(2500, 500); } if (transition_bp_alarme == 1) drapeau_alarme = 1; if (transition_bp_heure == 0) drapeau_heure = 0; if (transition_bp_minute == 0) drapeau_minute = 0; if (transition_bp_alarme == 0) drapeau_alarme = 0; Afficher_Heure(); } while(1); // infinite loop }
Salut,
il y a pas mal de choses à revoir dans ton programme, notamment cette écriture d'EEPROM en interruption... on ne fait jamais ça dans la routine d'interruption.
Je suppose que tu veux la lire pour comparer avec l'heure et minutes et non pas l'écrire.
Attention on écrit pas indéfiniment dans une EEPROM...
Sinon pour ton problème il suffit lorsque tu détectes le match entre heure/minute de réveil programmée et heure/minute réelle de déclencher ton buzzer, il ne devra s'arrêter que si tu détectes un appui du bouton d'arrêt.
Je vais jetter un oeil à ton prgramme, mais il me semble assez confus...
Merci bien Hulk!
Bonjour!
Je me suis procuré ce petit module : http://www.ebay.ca/itm/Non-Latching-...item2a21b6f124
donc, je voudrais lire les 4 sorties, ça fonctionne sauf que je voudrais allumer une lampe et qu'elle reste ouverte jusqu'à temps que j'appuie sur le même bouton. Le problème c'est que le module fonctionne de manière si j'appuie sur le bouton ça s'active et quand je le lâche il se désactive. Y-a-t-il moyen de contourner celà grâce au TMR0 du PIC ??
merci beaucoup de votre aide!
c'est très apprécié!
A+!
marC
et si je fais pour 20 Mhz = 5 microsecondes. prescaler 1:256, une interruption du timer0 en 256*256*5 = 327680 microseconde.
1 seconde = 1000000 / 327680 = 3,0517 tour de timer0
donc comment ici on trouve l'offset??
Merci beaucoup!!! Ca va etre pratique... si je veux changer de crystal..
A++!
marC
Ton calculm est faux.
20MHz/4=5MHz => tc=0.2µs
Prescaler 1:256 => t=51.2µs
1s:51.2µs=19531.25
Il suffit de compter 19531 fois le débordement du timer 0 en 8 bits pour mettre une variable tempo_1s à jour.
Merci Hulk!
Si je fais ça :
Est-ce que c'est bon comme code??Code:unsigned short count = 0, une_seconde = 0; unsigned short int Num = 0; void interrupt() { if (INTCON.T0IF == 1) { Num++; // Interrupt causes Num to be incremented by 1 if (Num == 19531) // à chaque seconde { Num = 0; une_seconde++; } INTCON.T0IF = 0; // Bit T0IF is cleared so that the interrupt could reoccur } }
A+!
marC
Pas mal.
Juste que tu devrais ne pas incrémenter une_seconde mais mettre cette variable à 1 que tu remettras à 0 dans ton programme principal une fois la tâche accomplie.
Il faut, si tu fais ça, la déclarer en volatile: volatile char une_seconde;
TMR0 vaut combiens initalement?
Merci Hulk!
A+!
marC
Ben 0 et quand il déborde 19531 fois tu as 1s.
Merci bien!
A++!
marC
Bonjour Hulk!
J'ai vu cela sur internet :
RB port change interrupt flag"
drapeau (flag) mis à 1 lors d'un changement de niveau logique d'au moins une des broches : RB4, RB5, RB6 ou RB7 (cela ne concerne que les broches configurées en entrée)
ce drapeau ne peut être effacé que de façon logicielle
je voudrais savoir comment puis-je m'y prendre détecter une entrée sur RB4, RB5, RB6 ou RB7 et l'afficher sur l'écran LCD quelle entrée a été effectué?
comment puis-je faire cela dans ma fonction interrupt()
merci beaucoup!!!
A++!
marC
Salut,
Le principe est le suivant:
Dans l'interruption il faut tester le flag RBIF qui est le drapeau correspondant à l'interruption liée au changement d'état d'un des ports RB4~RB7.
Ce bit est contenu dans le registre INTCON du µC.
Lorsque ce flag est levé, donc à 1, il faut ensuite tester le port qui a été sollicité pour déterminer lequel est le bon.
Tu lis le port B et tu fais un masque pour trouver le bit qui a changé.
Ne pas oublier de le remettre à 0 ensuite (le drapeau).
A cette occasion tu peux aller lire le C PARTY pour y trouver la technique qui convient
C'est un bon exercice.
Où se trouve le C PARTY??Salut,
Le principe est le suivant:
Dans l'interruption il faut tester le flag RBIF qui est le drapeau correspondant à l'interruption liée au changement d'état d'un des ports RB4~RB7.
Ce bit est contenu dans le registre INTCON du µC.
Lorsque ce flag est levé, donc à 1, il faut ensuite tester le port qui a été sollicité pour déterminer lequel est le bon.
Tu lis le port B et tu fais un masque pour trouver le bit qui a changé.
Ne pas oublier de le remettre à 0 ensuite (le drapeau).
A cette occasion tu peux aller lire le C PARTY pour y trouver la technique qui convient
C'est un bon exercice.
Merci!
A+!
marC
Bonjour!
Je voudrais faire un programme qui génère 6 nombre aléatoires de 1 à 49 pour la loto 6/49; c'est fait!
Et je voudrais mémoriser les résultats dans la EEPROM du PIC16f628a. Je ne sais pas trop comment m'y prendre car je n'en sais pas beaucoup le sujet. Voici mon code, en espérant, que vous puissiez m'aider,
Merci!
A+!
marC
Code:/* ########################################################### # Projet: Générateur de loterie 6/49 7 chiffres écran LCD # # Écrit par : Marc Paradis # # Date: 19 juillet, 2012 # ########################################################### LCD Data D4-D7 connected to RB4-RB7 LCD RS -> RA0 LCD E -> RA1 */ // LCD module connections sbit LCD_RS at RA0_bit; sbit LCD_EN at RA1_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 TRISA0_bit; sbit LCD_EN_Direction at TRISA1_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; sbit ENTREE at RB0_bit; // End LCD module connections # define BP_AFFICHER_NOMBRE F0 char messagePrincipal1[] = "Generateur de "; char messagePrincipal2[] = "6/49"; char Auteur[]= "Marc Paradis "; unsigned short i=0, j=0, cpt; volatile unsigned short Nombre1=0, Nombre2=0, Nombre3=0, Nombre4=0, Nombre5=0, Nombre6=0; unsigned short int transition_bp_afficher_nombre = 0; unsigned short int etatanterieur_bp_afficher_nombre= 1; unsigned short int etat_port ; // variable temporaire char dernier_tirage[] = "00000000000"; // store le résultat du dernier tirage dans la EEPROM char *digit1 = "00"; char *digit2 = "00"; char *digit3 = "00"; char *digit4 = "00"; char *digit5 = "00"; char *digit6 = "00"; unsigned int ADD; // Start EEPROM Location char temp; unsigned short int test_bp_afficher_nombre() { // test du bouton poussoir START_PAUSE etat_port = PORTB.BP_AFFICHER_NOMBRE; // lecture du niveau du port if ((etat_port == 0) && (etatanterieur_bp_afficher_nombre == 1)) { etatanterieur_bp_afficher_nombre = etat_port; return 1; // BP a été appuyé } else { etatanterieur_bp_afficher_nombre = etat_port; return 0; // BP inactif } } void Clear_me(){ // efface l'écran LCD, et désactive le curseur sur l'écran LCD Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); } void Read_EEPROM() { ADD = 0; for (i=0; i<11; i++) { temp = EEPROM_Read(ADD+i); dernier_tirage[i] = temp; } Lcd_Out(1,1, dernier_tirage); } /* void Write_EEPROM() { ADD = 0; for (i=0; i<22; i++) { // 22 caractères temp = message7[i]; EEPROM_Write(ADD+i,temp); } } */ void AfficheMessageDepart() { // Affiche le message d'accueil Lcd_Out(1,3, messagePrincipal1); delay_ms(500); Lcd_Out(2, 7, messagePrincipal2); Lcd_Cmd(_LCD_CURSOR_OFF); delay_ms(2000); Clear_me(); Lcd_Out(1, 7, "Par"); delay_ms(500); Lcd_Out(2, 3, Auteur); delay_ms(2500); Clear_me(); } void play_sound(){ Sound_Play(2500, 500); } void Display_Digits(unsigned short Nombre1, unsigned short Nombre2, unsigned short Nombre3, unsigned short Nombre4, unsigned short Nombre5, unsigned short Nombre6) { digit1[0] = (Nombre1/10)%10 + 48; // Extract tens digit digit1[1] = Nombre1%10 + 48; // Extract ones digit digit2[0] = (Nombre2/10)%10 + 48; // Extract tens digit digit2[1] = Nombre2%10 + 48; // Extract ones digit digit3[0] = (Nombre3/10)%10 + 48; // Extract tens digit digit3[1] = Nombre3%10 + 48; // Extract ones digit digit4[0] = (Nombre4/10)%10 + 48; // Extract tens digit digit4[1] = Nombre4%10 + 48; // Extract ones digit digit5[0] = (Nombre5/10)%10 + 48; // Extract tens digit digit5[1] = Nombre5%10 + 48; // Extract ones digit digit6[0] = (Nombre6/10)%10 + 48; // Extract tens digit digit6[1] = Nombre6%10 + 48; // Extract ones digit // Lcd_Out(1,1, "Vos resultats :"); // delay_ms(200); Clear_me(); Lcd_Out(1,1, digit1); Lcd_Out(1,4, digit2); Lcd_Out(1,7, digit3); Lcd_Out(1,10, digit4); Lcd_Out(1,13, digit5); Lcd_Out(2,1, digit6); delay_ms(5000); } void main() { CMCON = 0x07; // Disable Comparators TRISB = 0b00000001; // RB0 INPUT (PIC 6) TRISA = 0; PORTA = 0; PORTB = 0; cpt = 1; // initialisation du compteur à 0 OPTION_REG = 0b00000000; // activation des résistances de pull-off sur le PORTB Lcd_Init(); AfficheMessageDepart(); Sound_Init(&PORTB, 3); // initialisé la pin du pic pour utiliser le buzzer (PIC 9) delay_ms(2500); // pause pour 2.5 secondes Clear_me(); // efface l'écran Read_EEPROM(); // lit le dernier résultat du tirage do { if (transition_bp_afficher_nombre == 0) { Lcd_Out(1,1, "Appuyer sur le"); Lcd_Out(2,1, "bouton"); } transition_bp_afficher_nombre = test_bp_afficher_nombre(); if (transition_bp_afficher_nombre == 1) { Clear_me(); while (cpt < 7) { if (cpt == 1) Nombre1 = (rand()%49)+1; // Génère un nombre entre 1 et 49 ce qui devient le Nombre1 if (cpt == 2) { // Génère un nombre entre 1 et 49 ce qui devient le Nombre2 Nombre2 = (rand()%49)+1; // on test pour voir si les autres nombres ne sont pas égaux au Nombre2 while (Nombre2 == Nombre1) Nombre2 = (rand()%49)+1; } if (cpt == 3) { // Génère un nombre entre 1 et 49 ce qui devient le Nombre3 Nombre3 = (rand()%49)+1; // on test pour voir si les autres nombres ne sont pas égaux au Nombre3 while ( (Nombre3 == Nombre1) || (Nombre3 == Nombre2)) Nombre3 = (rand()%49)+1; } if (cpt == 4) { // Génère un nombre entre 1 et 49 ce qui devient le Nombre4 Nombre4 = (rand()%49)+1; // on test pour voir si les autres nombres ne sont pas égaux au Nombre4 while ((Nombre4 == Nombre1) || (Nombre4 == Nombre2) || (Nombre4 == Nombre3)) Nombre4 = (rand()%49)+1; } if (cpt == 5) { Nombre5 = (rand()%49)+1; // Génère un nombre entre 1 et 49 ce qui devient le Nombre5 // on test pour voir si les autres nombres ne sont pas égaux au Nombre5 while ((Nombre5 == Nombre1) || (Nombre5 == Nombre2) || (Nombre5 == Nombre3) || (Nombre5 == Nombre4)) Nombre5 = (rand()%49)+1; } if (cpt == 6) { // Génère un nombre entre 1 et 49 ce qui devient le Nombre6 Nombre6 = (rand()%49)+1; // on test pour voir si les autres nombres ne sont pas égaux au Nombre6 while ( (Nombre6 == Nombre1) || (Nombre6 == Nombre2) || (Nombre6 == Nombre3) || (Nombre6 == Nombre4) || (Nombre6 == Nombre5)) Nombre6 = (rand()%49)+1; } cpt++; } // on affiche les 6 chiffres Display_Digits(Nombre1, Nombre2, Nombre3, Nombre4, Nombre5, Nombre6); cpt = 1; // on remet le compteur à 0 Nombre1=0;Nombre2=0;Nombre3=0;Nombre4=0;Nombre5=0;Nombre6=0; // on réinitialise tout les nombres à 0s transition_bp_afficher_nombre = 0; // Write_EEPROM(); } } while(1); // Infinite Loop }
Si j'ai bien compris pour l'extraction des bits utilisant des masques.
Si j'ai une valeur de unsigned short i = 9; donc en binaire : 1001, je veux savoir si le bouton poussoir a été appuyé sur la pin RB7 du PIC.
J'applique l'opérande XOR (^) de 0 au chiffre 9, donc :
unsigned short resultat;
resultat = 9 ^ 0, ce qui donne : 1001 ^ 0000, j'ai dans résultat : 1001, le même chiffre... si je veux SPÉCIFIQUEMENT savoir le bit 7 exactement je m'y prends comment?
Merci beaucoup!!
Bonne Journée!
Vous êtes d'une aide indispensable
A+!
marC
J'ai fais un petit programme de test pour allumer la led correspondant au bouton poussoir associé à chaque port: RB7 à RB4 respectivement, dis moi si c'est okay!
Merci!
A+!Code:/************************** * Test interruption RBIF * * PIC16f628a * * Date : 25-04-2013 * * Auteur : Marc Paradis * **************************/ // PORTA # define BIT_LED_RB7 F0 // RA0 PIC 17 # define BIT_LED_RB6 F1 // RA1 PIC 18 # define BIT_LED_RB5 F2 // RA2 PIC 1 # define BIT_LED_RB4 F3 // RA3 PIC 2 unsigned short resultatrb7 = 0, resultatrb6 = 0, resultatrb5 = 0, resultatrb4 = 0; void interrupt() { if ( (INTCON.T0IF == 1) && (INTCON.RBIF == 1) ) // débordement du TMR0 et changement d'état du port RB7-RB4 { resultatrb7 = PORTB >> 8; resultatrb6 = PORTB >> 9; resultatrb5 = PORTB >> 10; resultatrb4 = PORTB >> 11; if (resultatrb7 == 1) { delay_ms(200); PORTA.BIT_LED_RB7 = 1; // on allume la led du port rb7 delay_ms(5000); PORTA.BIT_LED_RB7 = 0; } if (resultatrb6 == 1) // on allume la led du port rb6 { delay_ms(200); PORTA.BIT_LED_RB6 = 1; delay_ms(5000); PORTA.BIT_LED_RB6 = 0; } if (resultatrb5 == 1) // on allume la led du port rb5 { delay_ms(200); PORTA.BIT_LED_RB5 = 1; delay_ms(5000); PORTA.BIT_LED_RB5 = 0; } if (resultatrb4 == 1) // on allume la led du port rb4 { delay_ms(200); PORTA.BIT_LED_RB4 = 1; delay_ms(5000); PORTA.BIT_LED_RB4 = 0; } INTCON.T0IF = 0; INTCON.RBIF = 0; } } void main() { CMCON = 0x07; // Désactivation des comparateurs analogiques TRISA = 11110000; // RB7, RB6, RB5, RB4 EN INPUT TRISB = 0; PORTA = 0; PORTB = 0; OPTION_REG = 0b00000111; // Bit 7 : Port B Pull-up Enable (0) // Bit 6 : Interrupt edge select Disable (0) // Bit 5 : TMR0 Clock Source Select Enable (1) // Bit 4 : TMR0 Source edge select Disable (0) // Bit 3 : Prescaler assignment // Bit 2 : 1 (Prescaler 1:256) // Bit 1 : 1 "" // Bit 0 : 1 "" INTCON = 0b10101001; // Bit 7 : Global Interrupt Enable (1) // Bit 6 : EEPROM write complete interrupt Disable (0) // Bit 5 : TMR0 overflow interrupt Enable (1) // Bit 4 : RB0/INT external interrupt // Bit 3 : RB port change interrupt Enable (1) // Bit 2 : TMR0 overflow interrupt flag Disable (0) // Bit 1 : RB0/INT external interrupt flag Disable (0) // Bit 0 : RB port change interrupt flag Enable (1) do { // on attend le débordement du timer0 ce qui provoque une interruption et puis dans l'interruption on // test le flag RBIF } while(1); }
marC
Bonjour à tous!
Je voudrais faire un petit programme avec un PIC16f688 qui lit la lumière. Quand la lumière est détectée, je voudrais partir un compteur qui compte exactement 25 secondes, après ce temps, il joue une mélodie. Et si il fait noir, la mélodie arrête de jouer. Le problème c'est qu'on dirait que après 25 secondes il joue la mélodie et puis arrête tout à coup. Moi je voudrais qu'il continue à jouer jusqu'à détection de la noirceur.
Voici mon code :
Code:/*************************************************** * Reminder de fermer la porte du frigo après le * * écrai dans la constante * * NB_SECONDES_POUR_PORTE_FRIGO sinon on joue une * * mélodie jusqu'à ce que l'utilisateur ait fermé * * Microcontrolleur PIC utilisé : PIC16F688 * * Utilisation du module ADC et ENTRÉE/SORTIE * * Date 28-04-2013 * * Auteur : Marc Paradis * * Copyright (C) Marc Paradis 2013 * ***************************************************/ // PORTC # define BIT_LED F3 // RC3 PIC 7 # define BIT_UM66 F2 // RC2 PIC 8 unsigned int adc_value; // valeur ADC de la noirceur lit par le PIC à travers la photocell unsigned short Num = 0, OneSec = 0; // utilisé dans la routine d'interruption unsigned short flag_noirceur = 0; volatile unsigned short compteur_porte = 0; char message_EEPROM[] = "Copyright 2013 Marc Paradis"; char Edata[] = "000000000000000000000000000"; unsigned int ADD; // Start EEPROM Location char temp; unsigned short i; const unsigned short int NB_SECONDES_POUR_PORTE_FRIGO = 25; // contient le nombre de secondes a attendre quand le frigo est ouvert pour faire jouer la musique // Écrit mon nom dans la EEPROM du PIC void WriteToEEPROM() { ADD = 0; for (i = 0; i < 27; i++) { // 27 caractères temp = message_EEPROM[i]; EEPROM_Write(ADD+i,temp); } } // Routine d'interruption, on arrive ici quand il fait clair, le frigo est ouvert void interrupt() { adc_value = ADC_Read(2); if (adc_value/50 < 10) // il fait noir { PORTC.BIT_LED = 0; // on éteint la led témoin flag_noirceur = 1; compteur_porte = 0; } if (adc_value/50 > 10) // il fait clair { PORTC.BIT_LED = 1; // on allume la led témoin flag_noirceur = 0; } if ((INTCON.T0IE == 1) && (INTCON.T0IF == 1) && (flag_noirceur == 0)) // Si autorisation de l'interruption TMR0, débordement du TMR0 et qu'il fait clair { Num++; if (Num == 16) // 1 seconde passée dans la clartée { Num = 0; // On réinitialise Num à 0 pour pouvoir ravoir 1 seconde OneSec++; // On ajoute 1 on nombre de seconde } if (OneSec == NB_SECONDES_POUR_PORTE_FRIGO) // On est rendu à NB_SECONDES_POUR_PORTE_FRIGO max pour fermeture de porte du frigo { OneSec = 0; // On remet la valeur de OneSec à 0 pour qu'on puisse revenir pour compter le nombre de seconde écoulées PORTC.BIT_UM66 = 1; // compteur_porte = 1; } INTCON.T0IF = 0; // Mise du drapeau du débordement du TMR0 à OFF TMR0 = 12; // On remet le TMR0 à son nombre initial 12 } } // fonction principale void main() { ANSEL = 0b00000100; // RA2/AN2 is analog input ADCON0 = 0b00001000; // Analog channel select @ AN2 //ADCON1 = 0x00; // Voltage reference VDD CMCON0 = 0b00000111; // Désactivation des comparateurs analogiques TRISA = 0b00000100; // Photocell en entrée @ RA2 TRISC = 0b00000000; // Tous en sortie PORTA = 0b00000000; // Tous en sortie PORTC = 0b00000000; // Tous en sortie ADC_Init(); // Initialisation du module ADC du PIC WriteToEEPROM(); // Écrit le message dans la EEPROM, voir plus haut PORTC.BIT_LED = 0; // On éteint la led témoin PORTC.BIT_UM66 = 0; // On ne joue pas de musique pour l'instant OPTION_REG = 0x07; // 0b00000111 // bit 7 (/RBPU) = 0 : activation des résistances de pull-up du port B // bit 6 (INTEDG)= 0 : (non utilisée) // bit 5 (T0CS) = 0 : TMR0 Clock Source Select mode timer // bit 4 (T0SE) = 0 : RA4/T0CKI actif sur front montant // bit 3 (PSA) = 0 : module TMR0 // bit 2 (PS2)= 1 // bit 1 (PS1) = 1 // bit 0 (PS0) = 1 : Facteur de division du prescaler = 1:256 INTCON = 0xA0; // 0b10100000 // bit 7 (GIE) = 1 : autorisation globale des interruptions // bit 5 (T0IE) = 1 : autorisation de l'interruption TMR0 // bit 2 (T0IF)= 0 : on efface le drapeau de l'interruption TMR0 // les autres bits sont inutilisés (valeur par défaut = 0) TMR0 = 12; // Timer TMR0 compte de 12 à 255 do { // on attend le débordement du TMR0 ce qui va provoquer une interruption } while(1); }
Merci bien de m'aider.
A+!
marC
Bonjour!
Quelqu'un serait en mesure de m'expliquer ce code pour le ds1307?
Code:hour = BCD2Binary(hour); hour = hour + set; hour = Binary2BCD(hour); if((hour & 0x1F) >= 0x13) { hour = hour & 0b11100001; hour = hour ^ 0x20; } else if((hour & 0x1F) <= 0x00) { hour = hour | 0b00010010; hour = hour ^ 0x20; } write_ds1307(2, hour); //write hour break;
Merci beaucoup!
A+!
marC
Sans le reste du code, je doute que qui que ce soit puisse expliquer ce code.
ok, je poste :
Merci!Code:// LCD module connections sbit LCD_RS at RB2_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 TRISB2_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 short read_ds1307(unsigned short address) { unsigned short r_data; I2C1_Start(); I2C1_Wr(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 I2C1_Wr(address); I2C1_Repeated_Start(); I2C1_Wr(0xD1); //0x68 followed by 1 --> 0xD1 r_data=I2C1_Rd(0); I2C1_Stop(); return(r_data); } void write_ds1307(unsigned short address,unsigned short w_data) { I2C1_Start(); // issue I2C start signal //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0 I2C1_Wr(0xD0); // send byte via I2C (device address + W) I2C1_Wr(address); // send byte (address of DS1307 location) I2C1_Wr(w_data); // send data (data to be written) I2C1_Stop(); // issue I2C stop signal } unsigned char BCD2UpperCh(unsigned char bcd) { return ((bcd >> 4) + '0'); } unsigned char BCD2LowerCh(unsigned char bcd) { return ((bcd & 0x0F) + '0'); } int Binary2BCD(int a) { int t1, t2; t1 = a%10; t1 = t1 & 0x0F; a = a/10; t2 = a%10; t2 = 0x0F & t2; t2 = t2 << 4; t2 = 0xF0 & t2; t1 = t1 | t2; return t1; } int BCD2Binary(int a) { int r,t; t = a & 0x0F; r = t; a = 0xF0 & a; t = a >> 4; t = 0x0F & t; r = t*10 + r; return r; } int second; int minute; int hour; int hr; int day; int dday; int month; int year; int ap; unsigned short set_count = 0; short set; char time[] = "00:00:00 PM"; char date[] = "00/00/2000"; void main() { I2C1_Init(100000); //DS1307 I2C is running at 100KHz CMCON = 0x07; // To turn off comparators ADCON1 = 0x06; // To turn off analog to digital converters TRISA = 0x07; PORTA = 0x00; Lcd_Init(); // Initialize LCD Lcd_Cmd(_LCD_CLEAR); // Clear display Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off Lcd_out(1,1,"Time: "); Lcd_out(2,1,"Date: "); do { set = 0; if(PORTA.F0 == 0) { Delay_ms(100); if(PORTA.F0 == 0) { set_count++; if(set_count >= 7) { set_count = 0; } } } if(set_count) { if(PORTA.F1 == 0) { Delay_ms(100); if(PORTA.F1 == 0) set = 1; } if(PORTA.F2 == 0) { Delay_ms(100); if(PORTA.F2 == 0) set = -1; } if(set_count && set) { switch(set_count) { case 1: hour = BCD2Binary(hour); hour = hour + set; hour = Binary2BCD(hour); if((hour & 0x1F) >= 0x13) // simplification { hour = hour & 0b11100001; hour = hour ^ 0x20; } else if((hour & 0x1F) <= 0x00) { hour = hour | 0b00010010; hour = hour ^ 0x20; } write_ds1307(2, hour); //write hour break; case 2: minute = BCD2Binary(minute); minute = minute + set; if(minute >= 60) minute = 0; if(minute < 0) minute = 59; minute = Binary2BCD(minute); write_ds1307(1, minute); //write min break; case 3: if(abs(set)) write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator break; case 4: day = BCD2Binary(day); day = day + set; day = Binary2BCD(day); if(day >= 0x32) day = 1; if(day <= 0) day = 0x31; write_ds1307(4, day); // write date 17 break; case 5: month = BCD2Binary(month); month = month + set; month = Binary2BCD(month); if(month > 0x12) month = 1; if(month <= 0) month = 0x12; write_ds1307(5,month); // write month 6 June break; case 6: year = BCD2Binary(year); year = year + set; year = Binary2BCD(year); if(year <= -1) year = 0x99; if(year >= 0x50) year = 0; write_ds1307(6, year); // write year break; } } } second = read_ds1307(0); minute = read_ds1307(1); hour = read_ds1307(2); hr = hour & 0b00011111; ap = hour & 0b00100000; dday = read_ds1307(3); day = read_ds1307(4); month = read_ds1307(5); year = read_ds1307(6); time[0] = BCD2UpperCh(hr); time[1] = BCD2LowerCh(hr); time[3] = BCD2UpperCh(minute); time[4] = BCD2LowerCh(minute); time[6] = BCD2UpperCh(second); time[7] = BCD2LowerCh(second); date[0] = BCD2UpperCh(day); date[1] = BCD2LowerCh(day); date[3] = BCD2UpperCh(month); date[4] = BCD2LowerCh(month); date[8] = BCD2UpperCh(year); date[9] = BCD2LowerCh(year); if(ap) { time[9] = 'P'; time[10] = 'M'; } else { time[9] = 'A'; time[10] = 'M'; } Lcd_out(1, 6, time); Lcd_out(2, 6, date); Delay_ms(50); }while(1); }
A+!
marC
attends.. ou as-tu trouvé la valeur 62500 comme OFFSET??
merci beaucoup!
A+!
marC