Jump to content
ELFORUM - Forumul Electronistilor
Sign in to follow this  
Vlad Mihai

Ceas digital cu PIC16F876A si DS1307

Recommended Posts

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!

Share this post


Link to post
Share on other sites

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"?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites

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: .

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.