Sari la conținut
ELFORUM - Forumul electronistilor

ds1307 si pic


Vizitator kosmin22

Postări Recomandate

Vizitator kosmin22

vreau sa trimit date catre RTC(ds1307). ele trebuiesc convertite in BCD, si invers daca vreau sa utilizez pentru ceva, datele primite de la ds1307 trebuie convertite din bcd in binar. am codul pentru codificat decodificat; merge convertit dintrun sens in altul incrementat si convertit invers. el este in structura swich: case 1: . dar daca vreau aceeasi structura sa o pun pentru mai multe registre(adica la toate "case" 2,3,4,5..) nu mai merge.Care e problema? va multumesc anticipat!

// Conexiuni I2Csbit Soft_I2C_Scl           at RC3_bit;sbit Soft_I2C_Sda           at RC4_bit;sbit Soft_I2C_Scl_Direction at TRISC3_bit;sbit Soft_I2C_Sda_Direction at TRISC4_bit; // Conexiuni pentru LCD;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;const char character1[] = {0,10,31,31,14,4,0,0};void CustomChar1(char pos_row, char pos_char) {  char i;    LCD_Cmd(64);    for (i = 0; i<=7; i++) LCD_Chr_Cp(character1[i]);    LCD_Cmd(_LCD_RETURN_HOME);    LCD_Chr(pos_row, pos_char, 0);}const char character2[] = {6,9,9,6,0,0,0,0};void CustomChar2(char pos_row, char pos_char) {  char j;    LCD_Cmd(65);    for (j = 0; j<=7; j++) LCD_Chr_Cp(character2[j]);    LCD_Cmd(_LCD_RETURN_HOME);    LCD_Chr(pos_row, pos_char, 0);}#define RTC_ADDR  0xD0unsigned char hours, minutes, seconds, day, week, month, year;    // Global date/time variablesunsigned short hours1,minutes1,seconds1,cc,dd;unsigned char hours_int;int temp;char a; char oldstate0, oldstate1, oldstate2, oldstate3, oldstate4, oldstate5; short incr1;char lcd[] = "000";unsigned short contor0 = 0;unsigned short contor1 = 0;/*************************************************************************************************** Read data from RTC DS1307* input : addres of RTC register* output: value of of RTC register**************************************************************************************************/void Read_Time(unsigned char *p_hours, unsigned char *p_minutes, unsigned char *p_seconds,               unsigned char *p_day, unsigned char *p_week, unsigned char *p_month, unsigned char *p_year){  I2C1_Start();                // Issue start signal  I2C1_Wr(0xD0);               // adresa dispozitivului DS1307 (0x68)urmata de 0 pentru scriere;  I2C1_Wr(0);                  // start de la adresa 0;  I2C1_Repeated_Start();       // echivalent cu stop;  I2C1_Wr(0xD1);               // adresa dispozitivului DS1307 (0x68) urmata de 1 pentru citire;  *p_seconds = I2C1_Rd(1);     // incarc in reg ".." valoare secundelor ce sa gaseste in I2C1_Rd(1);  *p_minutes = I2C1_Rd(1);     // Read minutes byte  *p_hours = I2C1_Rd(1);       // Read hours byte  *p_week =I2C1_Rd(1);  *p_day =I2C1_Rd(1);  *p_month =I2C1_Rd(1);  *p_year =I2C1_Rd(0);  I2C1_Stop();                 // Issue stop signal}/*************************************************************************************************** Write time to RTC DS1307* input : variables with RTC data**************************************************************************************************/void Write_Time(unsigned char c_hours, unsigned char c_minutes, unsigned char c_seconds,                unsigned char c_day, unsigned char c_week, unsigned char c_month, unsigned char c_year){   I2C1_Start();                     // semnal de start;   I2C1_Wr(0xD0);                    // adresa disp DS1307 urmata de 0 pentru scriere;   I2C1_Wr(0);                       // start de la  (REG0)   I2C1_Wr(0x00);                    // scrie 0 in  REG0. (pause counter + 0 sec)   I2C1_Wr(c_minutes);               // write 0 to minutes word to (REG1)   I2C1_Wr(c_hours);                 // write 17 to hours word (24-hours mode)(REG2)   I2C1_Wr(c_week);                  // write 2 - Monday (REG3)   I2C1_Wr(c_day);                   // write 4 to date word (REG4)   I2C1_Wr(c_month);                 // write 5 (May) to month word (REG5)   I2C1_Wr(c_year);                  // write 01 to year word (REG6)   I2C1_Stop();                      // issue stop signal   I2C1_Start();                     // issue start signal   I2C1_Wr(RTC_ADDR);                // address DS1307   I2C1_Wr(0);                       // start from word at address 0   I2C1_Wr(0 | c_seconds);           // write 0 to REG0 (enable counting + 0 sec)   I2C1_Stop();                      // issue stop signal} void  Read_Temp() {    temp = ADC_Read(0);    temp = temp * 0.4887;    a = temp%10;    lcd[2] = a + '0';    temp = temp/10;    a = temp%10;    lcd[1] = a + '0';    temp = temp/10;    a = temp%10;    lcd[0] = a + '0';} void Show_Temp() {    Lcd_out(2,10,lcd);    CustomChar2(2,13);    Lcd_Chr(2,14,'C') ;}void Show_Time(){  char *txt;  seconds  =  ((seconds & 0x70) >> 4)*10 + (seconds & 0x0F);  minutes  =  ((minutes & 0xF0) >> 4)*10 + (minutes & 0x0F);  hours    =  ((hours & 0x30) >> 4)*10 + (hours & 0x0F);  week     =  (week & 0x07);  day      =  ((day & 0xF0) >> 4)*10 + (day & 0x0F);  month    =  ((month & 0x10) >> 4)*10 + (month & 0x0F);  year     =  ((year & 0xF0)>>4)*10+(year & 0x0F);  switch(week)  {    case 1: txt="Sun"; break;    case 2: txt="Mon"; break;    case 3: txt="Tue"; break;    case 4: txt="Wed"; break;    case 5: txt="Thu"; break;    case 6: txt="Fri"; break;    case 7: txt="Sat"; break;  }  LCD_Out(1,1, txt);  Lcd_Chr(1, 5, (day / 10)   + 48);    // Print tens digit of day variable  Lcd_Chr(1, 6, (day % 10)   + 48);    // Print oness digit of day variable  Lcd_Chr(1,7, '.');  Lcd_Chr(1, 8, (month / 10) + 48);  Lcd_Chr(1,9, (month % 10) + 48);  Lcd_Chr(1,10, '.');  Lcd_Chr(1,11, (year / 10)  + 48);  Lcd_Chr(1,12, (year % 10)  + 48);  Lcd_Chr(2, 1, (hours / 10)   + 48);  Lcd_Chr(2, 2, (hours % 10)   + 48);  Lcd_Chr(2, 3, ':');  Lcd_Chr(2, 4, (minutes / 10) + 48);  Lcd_Chr(2,5, (minutes % 10) + 48);  Lcd_Chr(2,6, ':');  Lcd_Chr(2,7, (seconds / 10) + 48);  Lcd_Chr(2,8, (seconds % 10) + 48);} void Show_alarm_display(){   Lcd_Chr(1, 1, 'S');   Lcd_Chr(1, 2, 'e');   Lcd_Chr(1, 3, 't');   Lcd_Chr(1, 5, 'A');   Lcd_Chr(1, 6, 'l');   Lcd_Chr(1, 7, 'a');   Lcd_Chr(1, 8, 'r');   Lcd_Chr(1, 9, 'm');   Lcd_Chr(1, 10, ':'); }    void main(){  I2C1_Init(100000); //DS1307 I2C is running at 100KHz    ADCON1 = 0x04;   CMCON = 0x07;   // To turn off comparators   TRISA = 0x07;   PORTA = 0x00;   TRISD = 0b11111111;   PORTD = 0b00000000;   Lcd_Init();                        // Initialize LCD   Lcd_Cmd(_LCD_CLEAR);               // Clear display   Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off  // Start the test examples  while(1)  {          Read_Time(&hours, &minutes, &seconds, &day, &week, &month, &year);          incr1 = 0;          if (Button(&PORTD, 0, 1, 1))              {                  oldstate0 = 1;               }          if (oldstate0 && Button(&PORTD, 0, 1, 0))              {                  contor0 ++;                  if (contor0 >=7)                      {                            contor0 = 0;                       }                 oldstate0 = 0;               }          if(contor0)              {                  if(Button(&PORTD, 1, 1, 1))                      {                          oldstate1 = 1;                       }                  if(oldstate1 && Button(&PORTD, 1, 1, 0))                      {                          oldstate1 = 0;                          incr1 = 1;                       }                  if(contor0 && incr1)                      {                           switch(contor0)                              {                                   case 1:                                        hours1 = (hours & 0x0F) + 10*((hours >> 4) & 0x0F);                                        hours1 = hours1 + incr1;                                        if(hours1 >= 24)                                           {                                            hours1 = 0;                                            }                                        hours1 = (hours1 % 10) + ((hours1/10) << 4);                                        break;                                   case 2:                                        minutes1 = (minutes & 0x0F) + 10*((minutes >> 4) & 0x0F);                                        minutes1 = minutes1 + incr1;                                        if(minutes1 >= 60)                                           {                                            minutes1 = 0;                                            }                                        minutes1 = (minutes1 % 10) + ((minutes1/10) << 4);                                        break;                                   case 3:                                        break;                                   case 4:                                        break;                                   case 5:                                        break;                                   case 6:                                        break;                             }                           Write_Time(hours1, minutes1, 0x00, 0x00, 0x00,0x00,0x00);                       }              }    Show_Time();    Read_Temp();    Show_Temp();      // Write_Time(0x11, 0x15, 0x00, 0x24, 0x03,   0x04, 0x12);   }}
Link spre comentariu
  • Răspunsuri 13
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

Top autori în acest subiect

Cred ca problema este de la 'contor0' care este mereu 0asta face 'contor0' sa fie 0 sau 1

if(contor0 && incr1)
prea complicat incrementarea in BCDuite aici cum fac eu
hour++;if((hour & 0x0F) >= 0x0A) hour += 0x06;if(hour >= 24) hour = 0;
0x24 sofian, nu?si nu inteleg de ce chinui compilatorul cu ">=".este suficient >0x09 si >0x23
Link spre comentariu
Vizitator kosmin22

nu e de la (if contor0 && incr1) problema. pentru ca contor 0 se incrementeaza mereu, fapt dovedit prin: daca secventa mea pentru convertit(bcd2binary si binary2bcd) o pun doar la un singur registru( ora minut secunda sau oricare altul) funtioneaza. dar daca aceeasi secventa o folosesc pentru toate, sau macar pentru doua registre nu mai merge. si nu stiu ce am gresit sau ce nu e declarat cum trebuie.

Link spre comentariu

nu e de la (if contor0 && incr1) problema. pentru ca contor 0 se incrementeaza mereu, fapt dovedit prin: daca secventa mea pentru convertit(bcd2binary si binary2bcd) o pun doar la un singur registru( ora minut secunda sau oricare altul) funtioneaza. dar daca aceeasi secventa o folosesc pentru toate, sau macar pentru doua registre nu mai merge. si nu stiu ce am gresit sau ce nu e declarat cum trebuie.

ai dreptate (if contor0 && incr1) este corect, este o expresie logica, nu infulenteaza cele doua variabile.nu inteleg: cand activezi doua "case", nu mai merge niciuna ?
Link spre comentariu
Vizitator kosmin22

Da. Daca pun pentru orice orice registru(doar pentru unul), merge, adica incrementeaza, si arata valoarea corespunzatoare pe lcd, timp in care celelalte pot fi :Write_Time(0x00,0x00,seconds1,0x00...). Dar daca vreau sa fac de la doua registre in sus, nu merge(adica sa le decodific =>incrementez =>codific pe toate) adica spre ex. :Write_time(0x00,minutes1,seconds1,0x00,0x00...)

Link spre comentariu

Da. Daca pun pentru orice orice registru(doar pentru unul), merge, adica incrementeaza, si arata valoarea corespunzatoare pe lcd, timp in care celelalte pot fi :Write_Time(0x00,0x00,seconds1,0x00...). Dar daca vreau sa fac de la doua registre in sus, nu merge(adica sa le decodific =>incrementez =>codific pe toate) adica spre ex. :Write_time(0x00,minutes1,seconds1,0x00,0x00...)

ce nu merge? nu mai merge nimic? afiseaza balarii pe ecran?
Link spre comentariu
Vizitator kosmin22

lcd-ul nu mai afiseaza nimic din start, cand pun pentru doua cazuri(nici nu mai e nevoie sa apas pe vreun buton, adica amandoua ca sa incrementez ceva caci nu merge deloc) dar ma refer la ds1307 ca nu se incrementeaza nimic in el(in proteus am o fereastra mica in care vad valoarea reala din ds1307, e fereastra dispozitivului)

Link spre comentariu

daca nu citeam ce ai scris mai sus (fara sa apesi niciun buton, nu mai merge nimic) vroiam sa-ti zic ca:I2C1_Wr(0x00); // scrie 0 in REG0. (pause counter + 0 sec)nu opreste oscilatorul ceasului, corect este 0x80 + secdar asa, habar n-am ce poate sa fie.daca tot ai proteus acolo, incerca sa faci un trace.

Link spre comentariu
Vizitator kosmin22

e de pe teorente(nu mai stiu de pe care),e o versiune full, nu am treaba cu "demo limit", dar la capitolul "cat de multe stie sa faca" mikroc in versiunea instalata la mine in pc fata de o versiune cumparata nu stiu si nu ma pricep sa aflu.

Link spre comentariu

Eu as incerca sa localizez putin problema (pare la functiile de comunicatie cu ds-ul, dar nu e sigur).As dezactiva comunicatiile cu ds-ul si vedea daca asa functioneaza (merge afisarea, merge modificarea parameterilor...).Daca asa merge, problema e la functiile de comunicatie. Daca nu, trebuie continuat cu bucatile de cod dezactivate. De asemenea, as incerca intai sa reduc numarul de comunicatii.La inceput as citi datele din memorie, as modifica toti parametrii de modificat si as salva doar o data, cand termin de modificat.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări