Sari la conținut
ELFORUM - Forumul electronistilor

Real Time Clock DS1307 & DS18B20 & PIC16F876A & MAX 7219


ducu

Postări Recomandate

Salutare,
Va prezint in continuare un proiect tot cu ceas dar de aceasta data informatia este afisata 
pe un display cu digiti (7 segmente), controlat de catre driver-ul serial IC max 7219.
 
S-a dorit:
Realizarea unui ceas de precizie cu functie de memorare chiar si atunci cand acesta nu este alimentat.
Adaugarea unui senzor de temperatura (ds18b20) cu o precizie de masurare de 0,1 grade Celsius.
Afisarea informatiei pe un display cu 8 digiti (7 segmente).
 
Sa realizat:
Un panou cu 3 butoane prin care ceasul intra in functia de modificare ora si minut (RB0 Enter,RB1 +Minut, RB2 +Ora).
Ca si microcontroller s-a ales pic16f876a. Limbajul de programare este Mikroc Pro for PIC.
Comunicatia intre microcontroller si circuitul de ceas este asigurata prin protocolul I2C.
Comunicatia intre microcontroller si max7219 este asigurata prin protocolul SPI.
Schema electronica este realizata pe o placa de test "breadboard" cu 2420 de gauri. Circuitul de ceas este proiectat separat pe un pcb.
Pcb-ul cu cei 8 digit si max7219 este achizitionata deasemenea, separat.
 
Schema electronica integrala:
post-176187-0-52117400-1415114228_thumb.jpg
 
si in format pdf: Real Time Clock.pdf
 
Explicatia schemei electronice:
Butonul S1 asigura resetul intregului circuit, R1 este rezistenta de pull-up pentru butonul S1.
Cristal de cuarț folosit este de 8 MHz. 
Conectorul ICSP este folosit pentru a programa microcontroller-ul (eu folosesc PicKit2). 
R1,R3-R5,R10 sunt rezistente de pull-up.
Dioda D1 are rol de protectie.
Cele trei butoane au rol de: incrementare ora, incrementare minut, enter.
Comunicatia intre circuitul DS1307 si placa "breadboard" este stabilita prin cinci pini astfel (GND, SQW, SCL, SDA, 5VDC).Nu am folosit aici pinul SQW.
Am folosit o baterie de 3vcc pentru a asigura functionarea clock-ului intern al IC-ului ds1307, chiar daca acesta nu este alimentat (la 5vcc).
Comunicatia intre circuitul max7219 si microcontroller este stabilita prin pinii RC0 (CS),RC1 (CLK) si RC2 (MOSI) folositi pentru protocolul software-spi.
Pinul RC7 asigura comunicatia cu senzorul de temperatura DS18B20.
Grupul de condensatoare C8-C11 au rol de filtrare pe ramura de alimentare.De preferat fiecare grup sa fie cat mai aproape de IC. 
 
Software-ul:
/*'*******************************************************************************'  Project name: Real Time Clock [DS1307 with Set Functions] & DS18B20 & max7219'  Description:'          With this experiment we wish to succed the next task:'          Display on 6 digits with 7 segment leds, the clock and the room temperature.'          Setting the time helped by three buttons: hours, minutes and enter.''          The sign "-" to the negative temperature and the hundreds for the'          temperature value are displayed just if are used.'          The time is displayed 5 second then he display the temperature value '          in Celsius Degrees for other 5 seconds and the loop goes to infinite.'          Our clock, displays as shown below(but just in display time,'          not in set mode).'          Ex. of viewing in 7 segment display,6 digits :'          Display time, mode:             Display temperature mode:'               __________                         _________'              |__24.59.59|     ~5 sec delay      |____23.6C|''          Hardware configuration is:'             IC ds1307 is connected with our microcontroller trough RC3=SCL,'             RC4=SDA (I2C Connections), '             max7219 as follow:(CS at RC0, CLK at RC1 and MOSI(SDO) at RC2)'             DS18B20 is assigned to RC7,'             RB0,RB1 and RB3 are assigned to the buttons'             Buttons Menu: RB0= Enter,  (It goes to set functions or exit from set functions)'                           RB1= Minutes,'                           RB2= Hours,''  Written by:'          Aureliu Raducu Macovei, 2014.'  Test configuration:'    MCU:                        PIC16F876A;'    Test.Board:                 WB-106 Breadboard 2420 dots;'    SW:                         MikroC PRO for PIC 2013 (version v6.4.0);'  Configuration Word:'    Oscillator:                 HS (8Mhz)on pins 9 and 10;'    Watchdog Timer:             OFF;'    Power up Timer:             OFF;'    Browun Out Detect:          ON;'    Low Voltage Program:        Disabled;'    Data EE Read Protect:       OFF;'    Flash Program Write:        Write Protection OFF;'    Background Debug:           Disabled;'    Code Protect:               OFF'********************************************************************************/// Software SPI module connections for max7219sbit SoftSpi_SDI at RC6_bit;sbit SoftSpi_SDO at RC2_bit;                   // MOSIsbit SoftSpi_CLK at RC1_bit;sbit Chip_Select at RC0_bit;sbit SoftSpi_SDI_Direction at TRISC6_bit;sbit SoftSpi_SDO_Direction at TRISC2_bit;sbit SoftSpi_CLK_Direction at TRISC1_bit;sbit Chip_Select_Direction at TrisC0_bit;// End Software SPI module connections for max7219const unsigned short TEMP_RESOLUTION = 12;     //This is resolution for ds18b20unsigned temp;unsigned sec, min1, hr, week_day, day, mn, year;unsigned short mask(unsigned short num){ switch (num)               // Define switch cases {  case  0 : return 0x7E;    // 0 for those values please study the datasheet max7219  case  1 : return 0x30;    // 1  case  2 : return 0x6D;    // 2  case  3 : return 0x79;    // 3  case  4 : return 0x33;    // 4  case  5 : return 0x5B;    // 5  case  6 : return 0x5F;    // 6  case  7 : return 0x70;    // 7  case  8 : return 0x7F;    // 8  case  9 : return 0x7B;    // 9  case 10 : return 0x01;    // Symbol '-'  case 11 : return 0x00;    // Blank  case 12 : return 0x80;    // Comma "," symbol  case 13 : return 0x43;    // C  } //case end}void max7219_init(){ Chip_Select = 0;           // SELECT MAX Soft_Spi_write(0x09);      // Decode-Mode Register Soft_Spi_write(0x00);      // No decode for digits 7–0 Chip_Select = 1;           // DESELECT MAX  Chip_Select = 0;           // SELECT MAX Soft_Spi_write(0x0A);      // Intensity Register Format Soft_Spi_write(0x01);      // Segment luminosity intensity set to 3/32 Chip_Select = 1;           // DESELECT MAX Chip_Select = 0;           // SELECT MAX Soft_Spi_write(0x0B);      // Scan-Limit Register Format Soft_Spi_write(0x05);      // Display digits 0 1 2 3 4 5 Chip_Select = 1;           // DESELECT MAX Chip_Select = 0;           // SELECT MAX Soft_Spi_write(0x0C);      // Shutdown Register Format Soft_Spi_write(0x01);      // Normal Operation Chip_Select = 1;           // DESELECT MAX Chip_Select = 0;           // SELECT MAX Soft_Spi_write(0x00);      // No-Op Soft_Spi_write(0xFF);      // No test Chip_Select = 1;           // DESELECT MAX}char minute2,hour2;void max7219_display_set_mode(unsigned minute2, unsigned hour2){ Chip_Select = 0;                                // select max7219 Soft_Spi_write(6);                              // digit 6 Soft_Spi_write(mask((hour2/10)%10));            // assign tens of hours Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(5);                              // digit 5 Soft_Spi_write ((mask(hour2%10))+ mask(12));    // assign units of hours Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(4);                              // digit 4 Soft_Spi_write(mask((minute2/10)%10));          // assign tens of minutes Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(3);                              // digit 3 Soft_Spi_write((mask(minute2%10))+mask(12));    // assign units of minutes Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;           // select max7219 Soft_Spi_write(2);         // digit 2 Soft_Spi_write (0);        // set as blank Chip_Select = 1;           // deselect max7219 Chip_Select = 0;           // select max7219 Soft_Spi_write(1);         // digit 1 Soft_Spi_write (0);        // set as blank Chip_Select = 1;           // deselect max7219}void max7219_display (unsigned sec, unsigned min, unsigned hr){ Chip_Select = 0;                                // select max7219 Soft_Spi_write(6);                              // digit 6 Soft_Spi_write(mask((hr/10)%10));               // assign tens of hours Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(5);                              // digit 5 Soft_Spi_write ((mask(hr%10))+ mask(12));       // assign units of hours Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(4);                              // digit 4 Soft_Spi_write(mask((min/10)%10));              // assign tens of minutes Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(3);                              // digit 3 Soft_Spi_write((mask(min%10))+mask(12));        // assign units of minutes Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(2);                              // digit 2 Soft_Spi_write (mask((sec/10)%10));             // assign tens of seconds Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(1);                              // digit 1 Soft_Spi_write (mask(sec%10));                  // assign units of seconds Chip_Select = 1;                                // deselect max7219}//-----Reads time and date information from RTC (DS1307)void Read_Time(unsigned *sec, unsigned *min, unsigned *hr, unsigned *week_day,                unsigned *day, unsigned *mn, unsigned *year){ I2C1_Start(); I2C1_Wr(0xD0); I2C1_Wr(0); I2C1_Repeated_Start(); I2C1_Wr(0xD1); *sec =I2C1_Rd(1); *min =I2C1_Rd(1); *hr =I2C1_Rd(1); *week_day =I2C1_Rd(1); *day =I2C1_Rd(1); *mn =I2C1_Rd(1); *year =I2C1_Rd(0); I2C1_Stop();}//~//-----------------start write time routine------------------void Write_Time(unsigned minute, unsigned hour){ unsigned tmp1, tmp2;  tmp1 = minute / 10;           // assign values from variables tmp2 = minute % 10;           // assign values from variables minute = tmp1 * 16 + tmp2;    // assign values from variables tmp1 = hour / 10;             // assign values from variables tmp2 = hour % 10;             // assign values from variables hour = tmp1 * 16 + tmp2;      // assign values from variables I2C1_Start();          // issue start signal I2C1_Wr(0xD0);         // address DS1307 I2C1_Wr(0);            // start from word at address (REG0) I2C1_Wr(0x80);         // write $80 to REG0. (pause counter + 0 sec) I2C1_Wr(minute);       // write minutes word to (REG1) I2C1_Wr(hour);         // write hours word (24-hours mode)(REG2) I2C1_Wr(0x00);         // write 6 - Saturday (REG3) I2C1_Wr(0x00);         // write 14 to date word (REG4) I2C1_Wr(0x00);         // write 5 (May) to month word (REG5) I2C1_Wr(0x00);         // write 01 to year word (REG6) I2C1_Wr(0x80);         // write SQW/Out value (REG7) I2C1_Stop();           // issue stop signal I2C1_Start();          // issue start signal I2C1_Wr(0xD0);         // address DS1307 I2C1_Wr(0);            // start from word at address 0 I2C1_Wr(0);            // write 0 to REG0 (enable counting + 0 sec) I2C1_Stop();           // issue stop signal}//-----------------end write time routine------------------//-------------------- Formats date and timevoid Transform_Time(unsigned *sec, unsigned *min, unsigned *hr,                     unsigned *week_day, unsigned *day, unsigned *mn, unsigned *year){ *sec  =  ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F); *min  =  ((*min & 0xF0) >> 4)*10 + (*min & 0x0F); *hr   =  ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F); *week_day =(*week_day & 0x07); *day  =  ((*day & 0xF0) >> 4)*10 + (*day & 0x0F); *mn   =  ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F); *year =  ((*year & 0xF0)>>4)*10+(*year & 0x0F);}//~void blink_min(){ Chip_Select = 0;               // select max7219 Soft_Spi_write(4);             // digit 4 Soft_Spi_write(0);             // set as blank Chip_Select = 1;               // deselect max7219 Chip_Select = 0;               // select max7219 Soft_Spi_write(3);             // digit 3 Soft_Spi_write(0);             // set as blank Chip_Select = 1; delay_ms(50);                               // 50ms delay max7219_display_set_mode(minute2,hour2);    // display those values delay_ms(50);                               // 50ms delay}void blink_hr(){ Chip_Select = 0;               // select max7219 Soft_Spi_write(6);             // digit 6 Soft_Spi_write(0);             // set as blank Chip_Select = 1;               // deselect max7219 Chip_Select = 0;               // select max7219 Soft_Spi_write(5);             // digit 5 Soft_Spi_write(0);             // set as blank Chip_Select = 1;               // deselect max7219 delay_ms(50);                               // 50ms delay max7219_display_set_mode(minute2,hour2);    // display those values delay_ms(50);                               // 50ms delay}char setuptime=0;unsigned count=0;void Press_Switch(){ if(button(&portb,0,1,0))        // check if button RB0 is pressed {  Delay_ms(200);  setuptime = !setuptime;        // switch that value;  if(setuptime)  {  hour2=hr;  minute2=min1;  max7219_display_set_mode(minute2,hour2);   // display those values  }  else  {   hr=hour2;   min1=minute2;   Write_Time(min1,hr);   max7219_display_set_mode(minute2,hour2);  } }  if(Setuptime) {  if(button(&portb,1,1,0))  {   Delay_ms(150);   minute2++;   if(minute2 > 59)   minute2=0;   blink_min();   }  if(button(&portb,2,1,0))  {   Delay_ms(150);   hour2++;   if(hour2 > 23)   hour2=0;   blink_hr();   }  }}// Starts ds18b20 declarationsvoid ds18b20(unsigned int temp2write){ const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8; unsigned temp_whole; unsigned int temp_fraction; unsigned short isNegative = 0x00; // Check if temperature is negative if (temp2write & 0x8000) {  temp2write = ~temp2write + 1;  isNegative = 1;  } // Extract temp_whole temp_whole = temp2write >> RES_SHIFT ; // Extract temp_fraction and convert it to unsigned int temp_fraction  = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625;          // 625 for ds18b20 and 5000 for ds1820; Chip_Select = 0;               // select max7219 Soft_Spi_write(1);             // digit 1 Soft_Spi_write(mask(13));      // write C symbol Chip_Select = 1;               // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(2);                              // Set digit number 3 Soft_Spi_write(mask(temp_fraction /1000));      // assigne as fraction Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(3);                              // Set digit number 3 Soft_Spi_write((mask(temp_whole%10))+mask(12)); // Assigne as ones Chip_Select = 1;                                // deselect max7219 Chip_Select = 0;                                // select max7219 Soft_Spi_write(4);                              // Set digit number 4 Soft_Spi_write (mask((temp_whole/10)%10));      // Assigne as tens Chip_Select = 1;                                // deselect max7219   if (isNegative == 1) {  Chip_Select = 0;               // select max7219  Soft_Spi_write(5);             // Set digit number 5  Soft_Spi_write(mask(10));      // Assigne as symbol "-"  Chip_Select = 1;               // deselect max7219  } else {  if(isNegative ==0 && temp_whole/100==0)  {   Chip_Select = 0;               // select max7219   Soft_Spi_write(5);             // Set digit number 5   Soft_Spi_write(mask(11));      // Assign as blank   Chip_Select = 1;               // deselect max7219   }  else  {   Chip_Select = 0;                         // select max7219   Soft_Spi_write(5);                       // Set digit number 5   Soft_Spi_write(mask(temp_whole/100));    // Assign the hundreds   Chip_Select = 1;                         // deselect max7219   }  }   Chip_Select = 0;                 // select max7219 Soft_Spi_write(6);               // Set digit number 6 Soft_Spi_write(0);               // Assign value 0 Chip_Select = 1;                 // deselect max7219}// End ds18b20 declarationsvoid interrupt(){ if(setuptime) count=0; else count++;                  // Interrupt causes count to be incremented by 1 TMR0 = 0;                 // Timer TMR0 is returned its initial value INTCON = 0x20;            // Bit T0IE is set, bit T0IF is cleared}void main() { CMCON  |= 7;                  // Disable Comparators OPTION_REG = 0x84;            // Prescaler Rate Selected at 1:32; TMR0 = 0;                     // Reset timer; INTCON = 0xA0;                // Disable interrupt PEIE,INTE,RBIE,T0IE Chip_Select_Direction = 0;    // Set RC0 pin as output Soft_Spi_init();              // Initialize software SPI module max7219_init();               // initialize  max7219 I2C1_Init(100000);            // initialize I2C while (1)                     // and here, our while loope {  Press_Switch();       if(!setuptime)  {   if(count<=1400)                    // ~ 5 seconds   {    Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);      // read time from RTC(DS1307)    Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year); // format date and time    max7219_display(sec,min1, hr);    }   else   {    if(count>1400)                     // ~ 5 seconds    {     //Perform temperature reading     Ow_Reset(&PORTC, 7);          // Onewire reset signal     Ow_Write(&PORTC, 7, 0xCC);    // Issue command SKIP_ROM     Ow_Write(&PORTC, 7, 0x44);    // Issue command CONVERT_T          Ow_Reset(&PORTC, 7);     Ow_Write(&PORTC, 7, 0xCC);    // Issue command SKIP_ROM     Ow_Write(&PORTC, 7, 0xBE);    // Issue command READ_SCRATCHPAD     temp =  Ow_Read(&PORTC, 7);   // Next Read Temperature and Read Byte 0 from Scratchpad     // Then read Byte 1 from Scratchpad and shift 8 bit left and add the Byte 0     temp = (Ow_Read(&PORTC, 7) << 8) + temp;     ds18b20(temp);                  //Format and display result on digits.     }    }   if(count>2800)   count = 0;   }  }}

Demonstractiile practice:

post-176187-0-05788100-1415114664_thumb.jpgpost-176187-0-07972600-1415114676_thumb.jpg
post-176187-0-21102300-1415114708_thumb.jpgpost-176187-0-70087000-1415114722_thumb.jpg
 

Daca aveti intrebari, va stau la dispozitie.

Editat de ducu
Link spre comentariu
  • 3 săptămâni mai târziu...
  • 5 luni mai târziu...
  • 5 ani mai târziu...
La 11.06.2020 la 1:05, ducu a spus:

Salut,

@minel in aceasta arhiva poti regasi toate fisierele necesare pentru a putea reproduce acest proiect.

 

 

 

 

 

 

 

Va multumesc mult,display-ul atasat de mine este in regula pt. constructia acestui ceas?

disp.jpg

Editat de minel
Link spre comentariu
Acum 6 ore, minel a spus:

Va multumesc mult,display-ul atasat de mine este in regula pt. constructia acestui ceas?

Imi puteti trimite un link catre produs?

 

Daca PCB-ul foloseste ca si circuit integrat MAX7219 ar trebui sa functioneze foarte bine.

 

 

Radu.

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