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 |   //***************************************************************************** |