Sari la conținut
ELFORUM - Forumul electronistilor

Ceas digital cu PIC16F876A si DS1307


Vlad Mihai

Postări Recomandate

Buna seara, astazi mi-am facut timp sa testez un ceas digital realizat cu un pic low cost si DS1307 la care adaug si un senzor de temperatura LM35Z si afisez informatia pe un LCD2x16.

Montajul e destul de compact si are dimensiunile de 100mm x50mm x30mm.

Tensiunea de alimentare poate fi cuprinsa intre 7.5V si 15V cc.

Mi-a luat de astazi dimineata de pe la 9 si pana acum sa il fac cap coada(realizare pcb fizic, plantare piese si soft). Cel mai probabil il voi amplasa pe biroul meu intr-o carcasa metalica.

Cateva imagini:

Schema electrica:

Posted Image

subir fotos gratis

Proiectare PCB:

Posted Image

imagen jpg

Reprezentare 3D:

Posted Image

subefotos

Proiectul finalizat:

Posted Image

 

Posted Image

 

Posted Image

 

Posted Image

 

Codul sursa:

//Conexiuni LCDsbit LCD_RS at RB7_bit;sbit LCD_EN at RB6_bit;sbit LCD_D4 at RB5_bit;sbit LCD_D5 at RB4_bit;sbit LCD_D6 at RB3_bit;sbit LCD_D7 at RB2_bit;sbit LCD_RS_Direction at TRISB7_bit;sbit LCD_EN_Direction at TRISB6_bit;sbit LCD_D4_Direction at TRISB5_bit;sbit LCD_D5_Direction at TRISB4_bit;sbit LCD_D6_Direction at TRISB3_bit;sbit LCD_D7_Direction at TRISB2_bit;// End LCD module connectionsunsigned 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 int val1,t;unsigned short set_count = 0;short set;  unsigned char ch;char time[] = "00:00:00 PM";char date[] = "00-00-00";void main(){   I2C1_Init(100000); //DS1307 I2C is running at 100KHz   CMCON = 0x07;   // To turn off comparators   ADCON1     = 0x80;                       // configure Vref, and analog channels   TRISA      = 0xFF;                       // designate PORTA as input   TRISC.F0=1;     //SET   TRISC.F1=1;    //+   TRISC.F2=1;    //-   TRISC.F6=0;    //LED   PORTC.F6=0;  //LED   Lcd_Init();                        // Initialize LCD   Lcd_Cmd(_LCD_CLEAR);               // Clear display   Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off   Lcd_out(2,4,"C");   Lcd_out(1,1,"V-M");   do   {     set = 0;     if(PORTC.F0 == 0)     {         Delay_ms(100);         if(PORTC.F0 == 0)         {             set_count++;             if(set_count >= 7)             {                set_count = 0;             }         }     }     if(set_count)     {        if(PORTC.F1 == 0)        {          Delay_ms(100);          if(PORTC.F1 == 0)              set = 1;        }        if(PORTC.F2 == 0)        {          Delay_ms(100);          if(PORTC.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)                    {                      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[6] = BCD2UpperCh(year);      date[7] = 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(100);            // Grade Celsius      val1=ADC_read(1);                // citim    tensiunea  generata de seznor in portul ADC1     t=(val1*0.48876);//conversia   tensiunii citite in grade celsius   ch = (t/10)%10;               //=> afisez zecile       LCD_chr(2,1,'0'+ch);   ch = t%10;       LCD_chr(2,2,'0'+ch);       //=> afisez unitatile         Lcd_Chr(2,3,223);        Delay_ms(100);   }while(1);}
Mai jos este o arhiva cu toate cele necesare realizarii acestui proiect. Multumesc, o seara buna!
Link spre comentariu
  • Răspunsuri 8
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Vlad Mihai

    4

  • Marian

    2

  • Mircea

    2

  • pop_ady44

    1

Top autori în acest subiect

Ceva frumos, felicitari @Vlad.PS: Banuiesc ca se monitorizeaza temperatura ambientala cu acel senzor nu? si daca da cum faci asta mai exact, adica pui senzorul pe un radiator sau il lasi asa "in aer"?

Link spre comentariu

Buna ziua, multumesc de aprecieri, senzorul e pus pe cablaj si e in capsula TO-92 fiind lasat in aer, e mai bine asa decat sa il pun pe un radiator, ar introduce erori.

Link spre comentariu

Ok am inteles, pai daca folosesti o carcasa cu ventilatie naturala cat de cat in regula atunci intr-adevar e mai bine asa.PS: Sper sa nu te superi de intrebare, eram doar curios penca mi se pare foarte interesant proiectul. :da

Link spre comentariu

Cand voi face carcasa voi face o gaura in zona senzorului ca sa aibe ventilatie naturala si sa fie cat mai precis referitor la masurarea temperaturii, e in regula nu ma supar din asa ceva, esti curios ca si mine, e bine. Numai bine!

Link spre comentariu

Pai daca carcasa este metalica, ii mai bine sa fie lipit de carcasa, ca sa masoare temperatura carcasei = ambientala. Eu zic ca asa este mai stabila valoarea masurata. Carcasa nu se incalzeste de la electronica (zic eu) si nici nu-si schimba temperatura brusc cu orice variatie de scurta durata.In fine, proiectul tau conceptia ta si satisfactia ta :ciuda: .

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