Sari la conținut

Real Time Clock DS1307 & DS18B20 & LCD2x16 & PIC16F876A [+Meniu Setari]


mducu

Postări Recomandate

Salut,

voi prezenta doua dintre proiectele mele, concepute cu ceva timp in urma, dar de actualitate, pentru a exemplifica modul de proiectare si programare folosind  microcontrollere PIC.

S-a dorit:

Realizarea unui ceas de precizie cu functie de memorare, chiar daca circuitul nu este alimentat.

Adaugarea unui senzor de temperatura (DS18B20) cu o precizie de masurare de 0,1 grade Celsius.

Afisarea pe un display cu 2 linii a cate 16 caractere, compatibil cu standardul HD44780.

Sa realizat un meniu prin care informatiile sunt modificate si inregistrate in IC DS1307.

Ca si microcontroller s-a ales pic16f876a (dar poate fi folosit oricare altul).

Limbajul de programare ales este Mikroc Pro for PIC.

Comunicatia intre microcontroller si circuitul de ceas este asigurata prin protocolul I2C.

Patru butoane ne permit explorarea meniului.

Intregul circuit este realizat pe o placa de test "breadboard" cu 2420 de gauri, mai putin circuitul de ceas care este proiectat separat pe o placa de circuit imprimat.

Schema electronica:

Circuit+Diagram.png

 

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/3). Rezistenta multitura R7 este folosita pentru a regla contrastul display-ului LCD. R6 ajusteaza curentul de consum prin ledurile care asigura iluminarea display-ului. R2-R5, R8-R10 sunt rezistențe de pull-up.

Dioda D1 are rol de protectie (alimentez circuitul si cu programatorul si s-a dorit evitarea diferentei de potential in punctele de alimentare pozitive).

Cele patru butoane au rol de: Incrementare, Decrementare, Schimbare Pozitie Cursor si 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.

Diagrama de timp a comunicatiei I2C transmise de DS1307:

Timing+Diagram.png

Modelul semnalului la transferul de date:

Data+Transfer+on+I2C+Serial+Bus.png

Diagrama bloc:

the+diagram+block.png

Software-ul:

/*
'*******************************************************************************
'  Project name: Real Time Clock [DS1307 with Set Functions] & DS18B20
'  Description:
'          Trough the current experiment we wish to succed the next task:
'          Display on LCD 2x16 character the clock and room temperature.
'          Setting trough four buttons: the minutes, hours, date of the month,
'          month, day of the week, and year.
'
'          Our clock displays as shown below(but just in display time,
'          not in set mode).
'          Ex. of viewing on 2x16 LCD characters:
'          Display time, mode:             Set time, mode (cursor on):
'          ------------------              ------------------
'          |Sat, 03 Dec 2011|              |Sat, 03 12  2011|
'          |21:32:03 +26,1*C|              |21:32:03        |
'          ------------------              ------------------
'
'          Hardware configuration is:
'             IC ds1307 is connected with our microcontroller trough RC3=SCL,
'             RC4=SDA (I2C Connections), RB0,RB1,RB4-RB7 are assigned to LCD (2x16)
'             DS18B20 is assigned to RC7,
'             Buttons Menu: RC0= Increment value,
'                           RC1= Decrement value,
'                           RC2= Change cursor position,
'                           RC5= Enter.(It goes to set functions or exit from set
'                                functions)
'  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.0.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
'*******************************************************************************
*/

// LCD module connections
sbit LCD_RS at RB0_bit;                 // LCD_RS assigned to PORT RB0;
sbit LCD_EN at RB1_bit;                 // LCD_EN assigned to PORT RB1;
sbit LCD_D4 at RB4_bit;                 // LCD_D4 assigned to PORT RB4;
sbit LCD_D5 at RB5_bit;                 // LCD_D5 assigned to PORT RB5;
sbit LCD_D6 at RB6_bit;                 // LCD_D6 assigned to PORT RB6;
sbit LCD_D7 at RB7_bit;                 // LCD_D7 assigned to PORT RB7;

sbit LCD_RS_Direction at TRISB0_bit;    // LCD_RS assigned to TRIS B0;
sbit LCD_EN_Direction at TRISB1_bit;    // LCD_EN assigned to TRIS B1;
sbit LCD_D4_Direction at TRISB4_bit;    // LCD_D4 assigned to TRIS B4;
sbit LCD_D5_Direction at TRISB5_bit;    // LCD_D5 assigned to TRIS B5;
sbit LCD_D6_Direction at TRISB6_bit;    // LCD_D6 assigned to TRIS B6;
sbit LCD_D7_Direction at TRISB7_bit;    // LCD_D7 assigned to TRIS B7;
// End LCD module connections

unsigned char sec,min1,hr,week_day,day,mn,year;
//--------------------- Reads time and date information from RTC (DS1307)
void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year)
{
 I2C1_Start();                    // Issue start signal
 I2C1_Wr(0xD0);                   // Address DS1307, see DS1307 datasheet
 I2C1_Wr(0);                      // Start from address 0
 I2C1_Repeated_Start();           // Issue repeated start signal
 I2C1_Wr(0xD1);                   // Address DS1307 for reading R/W=1
 *sec =I2C1_Rd(1);                // Read seconds byte
 *min =I2C1_Rd(1);                // Read minutes byte
 *hr =I2C1_Rd(1);                 // Read hours byte
 *week_day =I2C1_Rd(1);           // Read week day byte
 *day =I2C1_Rd(1);                // Read day byte
 *mn =I2C1_Rd(1);                 // Read mn byte
 *year =I2C1_Rd(0);               // Read Year byte
 I2C1_Stop();                     // Issue stop signal
}
//-----------------write time routine------------------
void Write_Time(char minute, char hour ,char weekday,char day,char month,char year)
{
 char tmp1, tmp2;

 tmp1 = minute / 10;               //Write tens of minute
 tmp2 = minute % 10;               //Write unit of minute
 minute = tmp1 * 16 + tmp2;        //Includes all value

 tmp1 = hour / 10;                 //Write tens of hour
 tmp2 = hour % 10;                 //Write unit of hour
 hour = tmp1 * 16 + tmp2;          //Includes all value

 tmp1 = weekday / 10;              //Write tens of weekday
 tmp2 =  weekday % 10;             //Write unit of weekday
 weekday = tmp1 *16 +tmp2;         //Includes all value

 tmp1 = day / 10;                  //Write tens of day
 tmp2 =  day % 10;                 //Write unit of day
 day = tmp1 *16 +tmp2;             //Includes all value

 tmp1 = month / 10;                //Write tens of month
 tmp2 =  month % 10;               //Write unit of month
 month = tmp1 *16 +tmp2;           //Includes all value

 tmp1 = year / 10;                 //Write tens of year
 tmp2 =  year % 10;                //Write unit of year
 year = tmp1 *16 +tmp2;            //Includes all value

 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(weekday);      // write 6 - Saturday (REG3)
 I2C1_Wr(day);          // write 14 to date word (REG4)
 I2C1_Wr(month);        // write 5 (May) to month word (REG5)
 I2C1_Wr(year);         // 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
}
//-------------------- Formats date and time---------------------
void Transform_Time(char  *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *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);
 }
//------------------------Display time---------------------------
char *txt,*mny;
void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year)
{
 switch(week_day)
 {
  case 1: txt="Mon"; break;       // Monday;
  case 2: txt="Tue"; break;       // Tuesday;
  case 3: txt="Wed"; break;       // Wednesday;
  case 4: txt="Thu"; break;       // Thursday;
  case 5: txt="Fri"; break;       // Friday;
  case 6: txt="Sat"; break;       // Saturday;
  case 7: txt="Sun"; break;       // Sunday;
  }

 LCD_Out(1, 1,txt);
 LCD_chr(1, 4,',');

 switch(mn)
 {
  case  1: mny="Jan"; break;
  case  2: mny="Feb"; break;
  case  3: mny="Mar"; break;
  case  4: mny="Apr"; break;
  case  5: mny="May"; break;
  case  6: mny="Jun"; break;
  case  7: mny="Jul"; break;
  case  8: mny="Aug"; break;
  case  9: mny="Sep"; break;
  case 10: mny="Oct"; break;
  case 11: mny="Nov"; break;
  case 12: mny="Dec"; break;
  }

 Lcd_Chr(1, 6, (day / 10) + 48);    // Print tens digit of day variable
 Lcd_Chr(1, 7, (day % 10) + 48);    // Print oness digit of day variable
 Lcd_Out(1, 9,mny);
 Lcd_out(1,13,"20");
 Lcd_Chr(1,15, (year / 10)  + 48);  // we can set year 00-99 [tens]
 Lcd_Chr(1,16, (year % 10)  + 48);  // we can set year 00-99 [ones]
 Lcd_Chr(2, 1, (hr / 10)  + 48);
 Lcd_Chr(2, 2, (hr % 10)  + 48);
 Lcd_Chr(2, 3,':');
 Lcd_Chr(2, 4, (min / 10) + 48);
 Lcd_Chr(2, 5, (min % 10) + 48);
 Lcd_Chr(2, 6,':');
 Lcd_Chr(2, 7, (sec / 10) + 48);
 Lcd_Chr(2, 8, (sec % 10) + 48);
 }
//-------------------Display Time in Set mode--------------------
char minute1,hour1,weekday1,month1;
char minute,hour,weekday,day1,month,year1;
void Display_Time_SetMode()
{
 switch(weekday1)
 {
  case 1: txt="Mon"; break;       // Monday;
  case 2: txt="Tue"; break;       // Tuesday;
  case 3: txt="Wed"; break;       // Wednesday;
  case 4: txt="Thu"; break;       // Thursday;
  case 5: txt="Fri"; break;       // Friday;
  case 6: txt="Sat"; break;       // Saturday;
  case 7: txt="Sun"; break;       // Sunday;
  }

 LCD_Out(1, 1,txt);
 LCD_chr(1, 4,',');

 Lcd_Chr(1, 6, (day1 / 10)   + 48);    // Print tens digit of day variable
 Lcd_Chr(1, 7, (day1 % 10)   + 48);    // Print oness digit of day variable
 Lcd_chr(1,10, (month1 / 10) + 48);    // Print tens digit of month variable
 Lcd_chr(1,11, (month1 % 10) + 48);    // Print oness digit of month variable
 Lcd_out(1,13,"20");
 Lcd_Chr(1,15, (year1 / 10)  + 48);    // Print tens digit of year variable
 Lcd_Chr(1,16, (year1 % 10)  + 48);    // Print oness digit of year variable
 Lcd_Chr(2, 1, (hour1 / 10)  + 48);    // Print tens digit of hour variable
 Lcd_Chr(2, 2, (hour1 % 10)  + 48);    // Print oness digit of hour variable
 Lcd_Chr(2, 3,':');
 Lcd_Chr(2, 4, (minute1 / 10) + 48);   // Print tens digit of minute variable
 Lcd_Chr(2, 5, (minute1 % 10) + 48);   // Print oness digit of minute variable
 Lcd_Chr(2, 6,':');
 Lcd_Chr(2, 7, (0 / 10) + 48);
 Lcd_Chr(2, 8, (0 % 10) + 48);
}

char SPos;
//----------------------Move cursor routine----------------------
char index;
void movecursor()
{
 char i,moveto;
 if(SPos==0)
 lcd_cmd(_lcd_first_row);  // set weekday;
 if(SPos==1)
 lcd_cmd(_lcd_first_row);  // set day;
 if(SPos==2)
 lcd_cmd(_lcd_first_row);  // set month;
 if(SPos==3)
 lcd_cmd(_lcd_first_row);  // set year;
 if(SPos==4)
 lcd_cmd(_lcd_second_row); // set hours;
 if(SPos==5)
 lcd_cmd(_lcd_second_row); // set minutes;

 moveto = 2;
 switch(index)
 {
  case 0: moveto = 2;break;
  case 1: moveto = 6;break;
  case 2: moveto =10;break;
  case 3: moveto =15;break;
  case 4: moveto = 1;break;
  case 5: moveto = 4;break;
  }
  for(i=1; i<= moveto; i++)
  lcd_cmd(_lcd_move_cursor_right);
}
//------------Start Buttons routine--------------;
char setuptime=0;
void Press_Switch()
{
 if(setuptime)
 {
  if(Button(&portc,2,1,0))         // If buttons at port c2 is pressed
  {
   delay_ms(200);
   SPos++;
   if(SPos>5)
   SPos=0;
   index++;
   if(index > 5)
   index=0;
   movecursor();
   }
  //-----------------------------case mode to set all values---------------------
  switch(SPos)
  {
   case 0: if(button(&portc,0,1,0))       // If buttons at port c0 is pressed
           {
            Delay_ms(200);
            weekday1++;
            if(weekday1 > 7)
            weekday1=1;
            Display_Time_SetMode();
            index=0;
            movecursor();
            }

           if(button(&portc,1,1,0))       // If buttons at port c1 is pressed
           {
            Delay_ms(200);
            weekday1--;
            if(weekday1 < 1)
            weekday1=7;
            Display_Time_SetMode();
            index=0;
            movecursor();
            }
           break;
   case 1: if(button(&portc,0,1,0))       // If buttons at port c0 is pressed
           {
            Delay_ms(200);
            day1++;
            if(day1 > 31)
            day1 = 1;
            Display_Time_SetMode();
            index=1;
            movecursor();
            }

           if(button(&portc,1,1,0))        // If buttons at port c1 is pressed
           {
            Delay_ms(200);
            day1--;
            if(day1 < 1)
            day1 = 31;
            Display_Time_SetMode();
            index=1;
            movecursor();
            }
           break;
   case 2: if(button(&portc,0,1,0))         // If buttons at port c0 is pressed
           {
            Delay_ms(200);
            month1++;
            if(month1 > 12)
            month1 = 1;
            Display_Time_SetMode();
            index=2;
            movecursor();
            }

           if(button(&portc,1,1,0))          // If buttons at port c1 is pressed
           {
            Delay_ms(200);
            month1--;
            if(month1 < 1)
            month1 = 12;
            Display_Time_SetMode();
            index=2;
            movecursor();
            }
           break;
   case 3: if(button(&portc,0,1,0))           // If buttons at port c0 is pressed
           {
            Delay_ms(200);
            year1++;
            if(year1 > 99)
            year1 = 1;
            Display_Time_SetMode();
            index=3;
            movecursor();
            }

           if(button(&portc,1,1,0))           // If buttons at port c1 is pressed
           {
            Delay_ms(200);
            year1--;
            if(year1 < 1)
            year1 = 99;
            Display_Time_SetMode();
            index=3;
            movecursor();
            }
           break;
   case 4: if(button(&portc,0,1,0))            // If buttons at port c0 is pressed
           {
            Delay_ms(200);
            hour1++;
            if(hour1 > 23)
            hour1 = 0;
            Display_Time_SetMode();
            index=4;
            movecursor();
            }

           if(button(&portc,1,1,0))            // If buttons at port c1 is pressed
           {
            Delay_ms(200);
            hour1--;
            if(hour1 > 23)
            hour1 = 0;
            Display_Time_SetMode();
            index=4;
            movecursor();
            }
           break;
   case 5: if(button(&portc,0,1,0))            // If buttons at port c0 is pressed
           {
            Delay_ms(200);
            minute1++;
            if(minute1 > 59)
            minute1 = 0;
            Display_Time_SetMode();
            index=5;
            movecursor();
            }

           if(button(&portc,1,1,0))             // If buttons at port c1 is pressed
           {
            Delay_ms(200);
            minute1--;
            if(minute1 > 59)
            minute1 = 0;
            Display_Time_SetMode();
            index=5;
            movecursor();
            }
           break;
   }                            // end "if is in switch mode"
  }                             // end "if is in setup"

 if(button(&portc,5,1,0))                      // If buttons at port c5 is pressed
 {
  Delay_ms(200);
  setuptime = !setuptime;
  if(SetupTime)
  {
   lcd_cmd(_lcd_clear);
   lcd_cmd(_lcd_blink_cursor_on);
   weekday1=week_day;
   hour1=hr;
   minute1=min1;
   day1=day;
   month1=mn;
   year1=year;
   Display_Time_SetMode();
   SPos=0;
   index=0;
   movecursor();
   }
   else
   {
   Lcd_Cmd(_Lcd_clear);
   lcd_cmd(_lcd_cursor_off);
   weekday=weekday1;
   hour=hour1;
   minute=minute1;
   day=day1;
   month=month1;
   year=year1;
   Write_time(minute,hour,weekday,day,month,year);
   }
  }
 }
//----------------------End Buttons Routine-------------------
//------------------Temperature sensor routines---------------
const unsigned short TEMP_RESOLUTION = 12;     // 9 for DS1820 and 12 for DS18B20
char *text = "000,0";
unsigned temp;
void Display_Temperature(unsigned int temp2write)
{
 const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
 char temp_whole;
 unsigned int temp_fraction;
 unsigned short isNegative = 0x00;

 // Check if temperature is negative
 if (temp2write & 0x8000)
 {
  text[0] = '-';
  temp2write = ~temp2write + 1;
  isNegative = 1;
  }
  // Extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;
  // Convert temp_whole to characters
  if (!isNegative){
  if (temp_whole/100)
  text[0] = temp_whole/100  + 48;                // Extract hundreds digit
  else
  text[0] = '+';
  }
  text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  text[2] =  temp_whole%10     + 48;             // Extract ones digit
  // Extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;
  // Convert temp_fraction to characters
  text[4] =  temp_fraction/1000 + 48;         // Extract thousands digit
  // Print temperature on LCD
  Lcd_Out(2, 10,text);
  lcd_chr(2, 15,0xB2);                        // Ascii code for degrees symbol;
  Lcd_chr(2, 16,'C');                         // Show symbol "C" from Celsius
}
//----------------Read and display Temperature from DS18B20--------------
void Read18b20()
{
 //--- Perform temperature reading
 Ow_Reset(&PORTC, 7);                           // Onewire reset signal;
 Ow_Write(&PORTC, 7, 0xCC);                     // 0xCC Issue command SKIP_ROM;
 Ow_Write(&PORTC, 7, 0x44);                     // Issue command CONVERT_T;
 Delay_us(700);                                 // delay 0,7s (required for signal
                                                // processing);
 Ow_Reset(&PORTC, 7);                           // Onewire reset signal;
 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, read Byte
                                                // 0 from Scratchpad;
 temp = (Ow_Read(&PORTC, 7) << 8) + temp;       // Then read Byte 1 from Scratchpad
                                                // and shift 8 bit left and add the Byte 0;
 //--- Format and display result on Lcd
 Display_Temperature(temp);                     // Call Display_Temperature;
 }
//------------------Temperature sensor routines---------------
void Init_Main()
{
 CMCON |=7;             //TURN OFF ANALOGUE COMPARATOR AND MAKE PORTA TO DIGITAL I/O;

 I2C1_Init(100000);         // initialize I2C
 Lcd_Init();                // Initialize LCD
 Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
 Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off

 Display_Time(sec, min1, hr, week_day, day, mn, year);

 !setuptime=1;
 index=0;
 SPos=0;
 }
//-----------------Here we have the Main Routine----------------
void main()
{
 Init_Main();
 while (1)                                                 // While loop
 {
  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); // Transform time
  Press_Switch();                                          // Check buttons;
  if(!setuptime)
  {
   Display_Time(sec, min1, hr, week_day, day, mn, year);
   Read18b20();
   }
  }
}

Explicatiile liniilor de cod le-am lasat in limba engleza, presupun ca nu este o problema.

Demonstractiile practice:

20140323_201832.jpg

20140323_221017.jpg

20140323_221131.jpg

20140323_221220.jpg

20140327_184222.jpg

20140327_184400.jpg

20140327_184443.jpg

20140327_184527.jpg

...si un filmulet:

 

Proiectul complet (fisierele eagle si mikroc): Real Time Clock DS1307 & DS18B20 & LCD02x16 PIC16F876A

 

Stima.

Editat de mducu
  • Like 3
  • Thanks 2
Link spre comentariu
Distribuie pe alte site-uri

Foarte frumos explicat si construit proiectul. Nota 10 de la mine. 

Totusi, ce precizie in timp ai obtinut cu ceasul ? Adica, daca ramane in urma, ca sigur ramane, si cu cat. Dar consumul montajului ?

  • Thanks 1
Link spre comentariu
Distribuie pe alte site-uri

Multumesc prog.

M-am jucat cu el vreo 6 luni dupa care l-am demontat. In perioada mentionata nu mi-a lasat impresia ca afiseaza eronat valorile. Pe perioade lungi de timp e posibil sa introduca erori, conteza mult si calitatea bateriei de 3 volti.

Ca si consum undeva pe la 65-80mA cred, deoarece aveam si acel display cu backlight care consuma destul.

 

 

Link spre comentariu
Distribuie pe alte site-uri

Proiect frumos, felicitari. Cat despre precizie, depinde de temperatura, DS1307 n e fiind termocompensata. Cu DS3231, avand  oscilatorul intern se poate obtine o precizie mai mare.

Dar nu conteaza, un minut, doua intr-o luna, oricum proiectul este (sau a fost) unul mai mult educativ.

  • Thanks 1
Link spre comentariu
Distribuie pe alte site-uri

Intr-adevar, interesul meu a fost sa proiectez functia de modificare ora si inregistrare in memoria chipului, la acel moment a fost suficient sa folosesc un integrat dedicat, precizia m-a interesat mai putin in timp, dar cu siguranta de inbunatatiri mereu este loc.

DS3231 are un oscilator pentru a compensa termic dar e si de poate 3 ori mai mare fizic. Vreau sa punctez doar faptul ca aproape intotdeauna exista o balanta intre calitate si practicabilitate.

 

Link spre comentariu
Distribuie pe alte site-uri

Am testat de curiozitate ansamblul in Proteus si MikroC for PIC.  Intradevar programul se incarca se compileaza corect si creaza fisierul HEX.

In Proteus ceasul intern functioneaza, sistemul se aduce la zero, temperatura se masoara corect, dar nu pot sa setez datele in nici o combinatie.

Poza arata asa: Ceas-termometru.thumb.png.0c431d3cad1c9355e969fa246e65bd1f.png

Mai am o problema in program, frecventa necesara ceasului este de 4 ori mai mare decit 32,768KHz

Daca se poate, va rog sa imi dati citeva idei, asa ca pentru o distractie de 1 ora.

PS. din timp in timp se schimba si arata asa: image.png.c0242bfa7ab6a259b99c885d8700ad28.png

 

@gsabac

Editat de gsabac
Link spre comentariu
Distribuie pe alte site-uri

D-nul gsabac daca doriti sa imi trimiteti, va rog, fisierul cu simularea in proteus, o voi testa si eu.

Eventual voi reface schema pe breadboard, il am la indemana.

32,768KHz este frecventa de lucru a lui IC DS1307, 8Mhz este frecventa de lucru a PIC-ului, amandoua comunica prin protocolul standard I2C.

Linia de cod: I2C1_Init(100000); // initialize I2C

100000 face referire la frecventa de lucru (clock-ul) la care se doreste a rula protocolul I2C.

La mine a functionat corect cu frecventa aleasa de 100000 hz.

Editat de mducu
Link spre comentariu
Distribuie pe alte site-uri

Cu multa placere si desigur sunt si alti useri interesati. In atasament este atit proiectul in MikroC Pro for PIC cat si proiectul in Proteus.

Folosesc Proteus 8.5 Professional si MikroC Pro for PIC 7.1.0 2017. Obs: poate este nevoie sa reincarcati fisierul HEX, de la noua adresa si

 directorul contine atit fisierul original cit si cel compilat de mine.

Succes!

 @gsabac

Ceas MikroC si Proteus.rar

Editat de gsabac
Link spre comentariu
Distribuie pe alte site-uri

In urma testelor, revin cu rezultatul final:

proba_gsabac_rtc.png

Nu ma declar foarte multumit deoarece nu am facut decat sa testez magistrala I2C in Proteus, cum am urmarit pe internet.

Pentru a functiona am adaugat un modul debugging I2C la reteaua de comunicatii, in simulari, acum afiseaza corect cu fisierul meu hex din arhiva. Am instalat versiunea 8.8 de Proteus, ca si la versiuni mai vechi, in modul de simulare ruleaza circa 40-50 de secunde apoi programul se inchide. Am incercat diferite artificii pentru a-l face mai stabil (am inchis celelalte programe, antivirus, am adus fisierul hex in fisierul sursa al Proteus-ului, schimbat cheia de licenta) fara nici un rezultat pana in momentul de fata.

Am reusit sa testez si meniul (butoanele). Functioneaza dar ruleaza foarte lent simularea iar procesorul urca in 99%.

Fizic proiectul garantat ruleaza fara nici o problema.

Daca doriti sa il construiti de la zero, va ofer suport cu drag.

 

Stima.

Editat de mducu
  • Like 1
Link spre comentariu
Distribuie pe alte site-uri

Multumesc, functioneaza bine, arata ora sincronizata dupa ceasul calculatorului si temperatura din senzor.

Nici eu nu am un computer performant, CPU cam 1000 la Benchmark, la rulare procesorul este ocupat 65% de Proteus, MikroC si Internet.

Sunt satisfacut de rezultatele obtinute, asta ca o experienta interesanta. Pasiunea mea este transmiterea bilaterala a datelor la mare viteza prin USB,

 intre un aparat fizic cu microcontroler si un PC, aceasta deoarece prin folosirea unui limbaj de rang inalt se pot prelucra si afisa datele cum se doreste.

Am inteles ca proiectul fizic functioneaza foarte bine si simularea cu HEX-ul original, felicitari!

   1649398882_CeasTemp.png.dbfbff9f5f964dbe929d3ed694afe5ad.png

@gsabac

  • Thanks 2
Link spre comentariu
Distribuie pe alte site-uri

La 21.02.2019 la 16:33, gsabac a spus:

Multumesc, functioneaza bine, arata ora sincronizata dupa ceasul calculatorului si temperatura din senzor.

Nici eu nu am un computer performant, CPU cam 1000 la Benchmark, la rulare procesorul este ocupat 65% de Proteus, MikroC si Internet.

Sunt satisfacut de rezultatele obtinute, asta ca o experienta interesanta. Pasiunea mea este transmiterea bilaterala a datelor la mare viteza prin USB,

 intre un aparat fizic cu microcontroler si un PC, aceasta deoarece prin folosirea unui limbaj de rang inalt se pot prelucra si afisa datele cum se doreste.

Am inteles ca proiectul fizic functioneaza foarte bine si simularea cu HEX-ul original, felicitari!

Ce versiune de Proteus ati folosit in simulare ?

Link spre comentariu
Distribuie pe alte site-uri

Ansamblul data-ceas-termometru este o aplicatie fizica si simulata ambele functionale.

In proiect @mducu a folosit MikroC 6.0.0 de la MikroElectronica(Mikroe) pentru realizarea programului din schema de principiu cu PIC si generarea fisierului HEX.

Eu am compilat programul cu MikroC 7.1 si nu am reusit sa activez sistemul I2C de legatura cu perifericele, dar cu HEX-ul original functioneaza.

Folosesc programul Proteus 8.5 SP0 unde am desenat schema, am incarcat fisierul HEX din locatia sa si am facut simularea functionarii.

@gsabac

Link spre comentariu
Distribuie pe alte site-uri

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
  • Navigare recentă   0 membri

    • Nici un utilizator înregistrat nu vede această pagină.
×
×
  • Creează nouă...

Informații Importante

Folosim cookie-uri și tehnologii asemănătoare pentru a-ți îmbunătăți experiența pe acest website, pentru a-ți oferi conținut și reclame personalizate și pentru a analiza traficul și audiența website-ului. Înainte de a continua navigarea pe www.tehnium-azi.ro te rugăm să fii de acord cu: Termeni de Utilizare.

ATENTIE !!! Functionarea Tehnium Azi depinde de afisarea de reclame.

Pentru a putea accesa in continuoare site-ul web www.tehnium-azi.ro, va rugam sa dezactivati extensia ad block din browser-ul web al vostru. Dupa ce ati dezactivat extensia ad block din browser dati clic pe butonul de mai jos.

Multumim.

Apasa acest buton dupa dezactivarea extensiei Adblock