1   //*****************************************************************************
2   //
3   //  File  Name    :  'rtc.c'
4   //  Title                :  Itronove  hodiny 
5   #define  __PIC18F8720A__
6   //  Author              :  http://www.prochazka.zde.cz  -&rsaquo   hacesoft  2017
7   //  Created            :  05-05-2017,  15:06
8   //  Revised            :  07-09-2017,  10:16
9   //  Version            :  1.1
10   //  Target  MCU   :  PIC  18F8720
11   //
12   //  This  code  is  distributed  under  the  GNU  Public  License
13   //  Vsechny  informace  jsou  zahrnuty  pod  GPL  licenci,  pokud  není  explicitne  uveden  jiný  typ  licence.
14   //  Pouzivání  techto  stránek  ke  komercním  úcelum  lze  jen  se  souhlasem  autora.
15   //  Vsechna  práva  vyhrazena  (c)  1997  -  2017  hacesoft.
16   //
17   //*****************************************************************************
18  
19   #include &lsaquo xc.h&rsaquo
20   #include &lsaquo stdio.h&rsaquo
21   #include &lsaquo stdlib.h&rsaquo
22   #include  "i2c.h"
23   #include  "display.h"
24   #include &lsaquo stdint.h&rsaquo   //uint8_t,  uint16_t,  uint32_t
25   #include  "rtc.h"
26   //*****************************************************************************
27   void  ReadRTC(void)  {
28        __delay_ms(5);
29        I2C_Start(_HW);
30        __delay_ms(5);
31        I2C_Write(_HW,  AddressDS3231_write);  //write  slave  address
32        __delay_ms(5);
33        I2C_Write(_HW,  0);  //zaciname  registrem  0
34        __delay_ms(5);
35       
36        I2C_ReStart(_HW);
37        __delay_ms(5);
38        I2C_Write(_HW,  AddressDS3231_read);  //write  slave  address
39        __delay_ms(5);
40        ParseSecond(I2C_Read(_HW,  ACKNOWLEDGE));  //Seconds
41        ParseMinutes(I2C_Read(_HW,  ACKNOWLEDGE));  //Minutes 
42        ParseHour(I2C_Read(_HW,  ACKNOWLEDGE));  //Hour 
43        _DateTimeDS3231.Day  =  I2C_Read(_HW,  ACKNOWLEDGE);
44        _DateTimeDS3231.Date  =  I2C_Read(_HW,  ACKNOWLEDGE);
45        _DateTimeDS3231.Month_Century  =  I2C_Read(_HW,  ACKNOWLEDGE);
46        _DateTimeDS3231.Year  =  I2C_Read(_HW,  ACKNOWLEDGE);
47        _DateTimeDS3231.Alarm_1_Seconds  =  I2C_Read(_HW,  ACKNOWLEDGE);
48        _DateTimeDS3231.Alarm_1_Minutes  =  I2C_Read(_HW,  ACKNOWLEDGE);
49        _DateTimeDS3231.Alarm_1_Hours  =  I2C_Read(_HW,  ACKNOWLEDGE);
50        _DateTimeDS3231.Alarm_1_Day_Date  =  I2C_Read(_HW,  ACKNOWLEDGE);
51        _DateTimeDS3231.Alarm_2_Minutes  =  I2C_Read(_HW,  ACKNOWLEDGE);
52        _DateTimeDS3231.Alarm_2_Hours  =  I2C_Read(_HW,  ACKNOWLEDGE);
53        _DateTimeDS3231.Alarm_2_Day_Date  =  I2C_Read(_HW,  ACKNOWLEDGE);
54        _DateTimeDS3231.Control  =  I2C_Read(_HW,  ACKNOWLEDGE);
55        _DateTimeDS3231.Control_Status  =  I2C_Read(_HW,  ACKNOWLEDGE);
56        _DateTimeDS3231.Aging_Offset  =  I2C_Read(_HW,  ACKNOWLEDGE);
57        _DateTimeDS3231.MSB_buffer_temp  =  I2C_Read(_HW,  ACKNOWLEDGE);
58        _DateTimeDS3231.LSB_buffer_temp  =  I2C_Read(_HW,  NOT_ACKNOWLEDGE);
59        I2C_Stop(_HW);
60        __delay_ms(5);
61   }
62   //*****************************************************************************
63   void  SetTime(void)  {
64        __delay_ms(5);
65        I2C_Start(_HW);
66        __delay_ms(5);
67        I2C_Write(_HW,  AddressDS3231_write);  //write  slave  address
68        I2C_Write(_HW,  0x0);  //zaciname  registrem  0
69        I2C_Write(_HW,  CodeSeconds  (_DateTimeDS3231.Seconds_10,  _DateTimeDS3231.Seconds));
70        I2C_Write(_HW,  CodeMinutes  (_DateTimeDS3231.Minutes_10,  _DateTimeDS3231.Minutes));
71        I2C_Write(_HW,  CodeHours  (_DateTimeDS3231.Hour_10,  _DateTimeDS3231.Hour));
72        I2C_Stop(_HW);
73        __delay_ms(5);
74   }
75   //*****************************************************************************
76   void  SetDate(void)  {
77        __delay_ms(5);
78        I2C_Start(_HW);
79        __delay_ms(5);
80        I2C_Write(_HW,  AddressDS3231_write);  //write  slave  address
81        I2C_Write(_HW,  0x3);  //zaciname  registrem  3
82        I2C_Write(_HW,  CodeDay  (_DateTimeDS3231.Day));
83        I2C_Write(_HW,  CodeDate  (_DateTimeDS3231.Date));
84        I2C_Write(_HW,  CodeMonth_Century  (_DateTimeDS3231.Month_Century));
85        I2C_Write(_HW,  CodeYear(_DateTimeDS3231.Year));
86        I2C_Stop(_HW);
87        __delay_ms(5);
88   }
89   //*****************************************************************************
90   float  GetTemp(void)  {
91        uint8_t  _msb  =  _DateTimeDS3231.MSB_buffer_temp;
92        uint8_t  _lsb  =  _DateTimeDS3231.LSB_buffer_temp;
93        uint16_t  _nBuffer;
94        _nBuffer  =  (unsigned)((unsigned)_msb  rol  2)  or  ((unsigned)_lsb  ror  6);
95        return  (float)  _nBuffer  *  0.25;
96   }
97   //*****************************************************************************
98   uint8_t  CodeSeconds  (  uint8_t  Seconds_10,  uint8_t   Seconds)  {
99    
100        return  (unsigned)Seconds  or  ((unsigned)Seconds_10  rol  4);
101   }
102   //*****************************************************************************
103   uint8_t  CodeMinutes  (uint8_t  Minutes_10,  uint8_t  Minutes){
104      
105        return  (unsigned)  Minutes  or  ((unsigned)Minutes_10  rol  4);
106   }
107   //*****************************************************************************
108   uint8_t  CodeHours  (uint8_t  Hour_10,uint8_t  Hour)  {
109        uint8_t  nBuffer;
110       
111        nBuffer  =  (unsigned)Hour  or  ((unsigned)Hour_10  rol  4);
112        BitClear  (nBuffer,  6);  //Nastaveni  rezimu  24  hodin
113        //Bit  6  of  the  hours  register  is  defined  as  the  12-  or  24-hour  mode  select  bit. 
114            //When  high,  the  12-hour  mode  is  selected.  In  the  12-hour  mode,  bit  5  is  the  AM/PM  bit  with  logic-high  being  PM. 
115            //In  the  24-hour  mode,  bit  5  is  the  20-hour  bit  (20?23  hours). 
116        return  nBuffer;
117   }
118   //*****************************************************************************
119   uint8_t  CodeDay  (uint8_t  Day)  {
120  
121        return  _DateTimeDS3231.Day;    
122   }
123   //*****************************************************************************
124   uint8_t  CodeDate  (uint8_t  Date){
125  
126        return  _DateTimeDS3231.Date;    
127   }
128   //*****************************************************************************
129   uint8_t  CodeMonth_Century  (uint8_t  Month_Century){
130  
131        return  _DateTimeDS3231.Month_Century;    
132   }
133   //*****************************************************************************
134   uint8_t  CodeYear  (uint8_t  _Year){
135    
136        return  _DateTimeDS3231.Year;
137   }
138   //*****************************************************************************
139  
140   void  ShowTemp(void)  {
141        char  *buff;
142        uint8_t  sBuffer;
143        uint8_t  sBuffer1;
144        uint8_t  a;
145  
146        buff  =  _ftoa(GetTemp());
147        a  =  0;
148        sBuffer  =  buff[a];
149        if  (sBuffer  ==  minus)  {
150            a++;
151            _hour_raw(decode_segment(21),  decode_segment(16));
152        }
153        sBuffer  =  buff[a];
154        a++;
155        sBuffer1  =  buff[a];
156        if  (sBuffer1  ==  tecka)  {
157            _minut_raw(decode_segment(21),  (unsigned)  (decode_segment((unsigned)  sBuffer  -  48)  or  decode_segment(20)));
158        }  else  {
159            _minut_raw(decode_segment((unsigned)  sBuffer  -  48),(unsigned)  (decode_segment((unsigned)  sBuffer1  -  48)  or  decode_segment(20)));
160            a++;
161        }
162        _second_raw(decode_segment((unsigned)buff[a+1]  -  48),  decode_segment((unsigned)buff[a+2]  -  48));
163   }
164   //*****************************************************************************
165   char*  _ftoa(float  f)  {
166        static  char  buf[17];
167        char*  cp  =  buf;
168        unsigned  long  l,  rem;
169  
170        if  (f &lsaquo   0)  {
171            *cp++  =  '-';
172            f  =  -f;
173        }
174        l  =  (unsigned  long)  f;
175        f  -=  (float)  l;
176        rem  =  (unsigned  long)  (f  *  1e2);
177        sprintf(cp,  "%lu.%2.2lu",  l,  rem);
178        return  buf;
179   }
180   //*****************************************************************************
181   void  init_RTC(void)  {
182        init_RST_RTC();
183        init_INT_RTC();
184        ResetRTC();
185   }
186   //*****************************************************************************
187   void  init_RST_RTC(void)  {
188        //CLRF  PORTB  ;  Initialize  PORTB  by
189        //;  clearing  output
190        //;  data  latches
191        //CLRF  LATB  ;  Alternate  method
192        //;  to  clear  output
193        //;  data  latches
194        //MOVLW  0xCF  ;  Value  used  to
195        //;  initialize  data
196        //;  direction
197        //MOVWF  TRISB  ;  Set  RB&lsaquo 3:0&rsaquo   as  inputs
198        //;  RB&lsaquo 5:4&rsaquo   as  outputs
199        //;  RB&lsaquo 7:6&rsaquo   as  inputs
200        //BitClear(RST_RTC,  _RB4);
201        BitSet(RST_RTC,  _RB4);
202        BitClear(LATB_RTC,  _RB4);
203        BitClear(tRTC,  _RB4);
204        BitSet(RST_RTC,  _RB4);
205   }
206   //*****************************************************************************
207   void  init_INT_RTC(void)  {
208        //CLRF  PORTB  ;  Initialize  PORTB  by
209        //;  clearing  output
210        //;  data  latches
211        //CLRF  LATB  ;  Alternate  method
212        //;  to  clear  output
213        //;  data  latches
214        //MOVLW  0xCF  ;  Value  used  to
215        //;  initialize  data
216        //;  direction
217        //MOVWF  TRISB  ;  Set  RB&lsaquo 3:0&rsaquo   as  inputs
218        //;  RB&lsaquo 5:4&rsaquo   as  outputs
219        //;  RB&lsaquo 7:6&rsaquo   as  inputs
220        BitSet(INT_RTC,  _RB3);
221        BitSet(LATB_RTC,  _RB3);
222        BitSet(tRTC,  _RB3);
223   }
224   //*****************************************************************************
225   void  ResetRTC(void)  {
226        BitSet(RST_RTC,  _RB4);
227        __delay_ms(10);
228        BitClear(RST_RTC,  _RB4);
229        __delay_ms(10);
230        BitSet(RST_RTC,  _RB4);
231   }
232   //*****************************************************************************
233   void  ParseSecond(unsigned  char  ParseData)  {
234        _DateTimeDS3231.Seconds  =  (unsigned)  ParseData  and  MaskSeconds;
235        _DateTimeDS3231.Seconds_10  =  (unsigned)  (ParseData  and  MaskSeconds_10) &rsaquo &rsaquo   4;
236   }
237   //*****************************************************************************
238   void  ParseMinutes(unsigned  char  ParseData)  {
239        _DateTimeDS3231.Minutes  =  (unsigned)  ParseData  and  MaskMinutes;
240        _DateTimeDS3231.Minutes_10  =  (unsigned)  (ParseData  and  MaskMinutes_10) &rsaquo &rsaquo   4;
241   }
242   //*****************************************************************************
243   void  ParseHour(unsigned  char  ParseData)  {
244        _DateTimeDS3231.Hour  =  (unsigned)  ParseData  and  MaskHour;
245        _DateTimeDS3231.Hour_10  =  (unsigned)  (ParseData  and  MaskHour_10) &rsaquo &rsaquo   4;
246        _DateTimeDS3231.AM_PM  =  (unsigned)  (ParseData  and  MaskAM_PM) &rsaquo &rsaquo   5;
247        _DateTimeDS3231._12_24  =  (unsigned)  (ParseData  and  Mask_12_24) &rsaquo &rsaquo   6;
248   }
249   //*****************************************************************************