PIC18 LaurTec Library  3.3.1
Open Source C Library for PIC18 Microcontrollers based on C18 - XC8 Compilers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
MCP7940.c
Go to the documentation of this file.
1 /*******************************************************************************
2 
3 Author : Mauro Laurenti
4 Version : 1.0
5 Created on Date : 23/9/2015
6 Last update : 23/9/2015
7 
8 CopyRight 2006-2015 all rights are reserved
9 
10 ********************************************************
11 SOFTWARE LICENSE AGREEMENT
12 ********************************************************
13 
14 The usage of the supplied software imply the acceptance of the following license.
15 
16 The software supplied herewith by Mauro Laurenti (the Author) is intended for
17 use solely and exclusively on Microchip PIC Microcontroller (registered mark).
18 The software is owned by the Author, and is protected under applicable
19 copyright laws. All rights are reserved.
20 Any use in violation of the foregoing restrictions may subject the
21 user to criminal sanctions under applicable laws, as well as to civil liability
22 for the breach of the terms and conditions of this license.
23 Commercial use is forbidden without a written acknowledgement with the Author.
24 Personal or educational use is allowed if the application containing the
25 following software doesn't aim to commercial use or monetary earning of any kind.
26 
27 THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
28 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
29 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT,
31 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
32 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
33 
34 ********************************************************
35 PURPOSES
36 ********************************************************
37 
38 This library supports the Real Time Clock Calendar MCP7940 or compatible
39 devices. The library is kept compatible with the PCF8563
40 
41 The following functions have been added:
42 
43  set_seconds_alarm_RTCC (seconds associated to the first alarm)
44 
45  The second alarm is not handled but it can be easily implemented.
46 
47 *******************************************************************************/
48 
49 
50 #ifdef __XC8
51  #include <xc.h>
52  #ifndef _PIC18
53  #error The MCP7940 Library supports only PIC18 devices
54  #endif
55 #endif
56 
57 #include "MCP7940.h"
58 
59 
60 //************************************************************
61 // MCP7940_initialize function implementation
62 //************************************************************
63 void MCP7940_initialize (unsigned char crystal_frequency_MHz, unsigned int baud_rate_KHz){
64 
65  unsigned char enable_buffer;
66 
67  OpenI2C(MASTER, SLEW_ON);
68 
69  SSPADD = (((crystal_frequency_MHz *1000)/4)/baud_rate_KHz)-1;
70 
71  //Enable the 32KHz Oscillator, writing 0x08 to the seconds register
72  // It is necessary to set bit 7 to 1 to enable the 32KHz oscillator buffer
73  // Without it the external crystal will not oscillate.
74  //EEByteWrite (RTCC_WRITE_ADD,RTCC_SECONDS_ADDR,0b10000000);
75 
76  RTCC_set_seconds (0x00);
77 }
78 
79 
80 //************************************************************
81 // RTCC_set_seconds function implementation
82 //************************************************************
83 signed char RTCC_set_seconds (unsigned char seconds) {
84 
85  seconds |= 0b10000000;
86 
87  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_SECONDS_ADDR,seconds));
88 }
89 
90 
91 //************************************************************
92 // RTCC_get_seconds function implementation
93 //************************************************************
94 unsigned char RTCC_get_seconds (void) {
95 
96  unsigned char seconds;
97 
98  seconds = EERandomRead (RTCC_WRITE_ADD,RTCC_SECONDS_ADDR);
99 
100  // I set to 0 the bits which are not significant
101  seconds = seconds & 0b01111111;
102  return (seconds);
103 }
104 
105 
106 
107 //************************************************************
108 // RTCC_set_minutes function implementation
109 //************************************************************
110 
111 signed char RTCC_set_minutes (unsigned char minutes) {
112 
113  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_MINUTES_ADDR,minutes));
114 
115 }
116 
117 
118 //************************************************************
119 // RTCC_get_minutes function implementation
120 //************************************************************
121 unsigned char RTCC_get_minutes (void) {
122 
123  unsigned char minutes;
124  minutes = EERandomRead (RTCC_WRITE_ADD,RTCC_MINUTES_ADDR);
125 
126  // I set to 0 the bits which are not significant
127  minutes = minutes & 0b01111111;
128  return (minutes);
129 }
130 
131 
132 //************************************************************
133 // RTCC_set_hours function implementation
134 //************************************************************
135 signed char RTCC_set_hours (unsigned char hours) {
136 
137  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_HOURS_ADDR,hours));
138 }
139 
140 
141 //************************************************************
142 // RTCC_get_hours function implementation
143 //************************************************************
144 unsigned char RTCC_get_hours (void){
145 
146  unsigned char hours;
147  hours = EERandomRead (RTCC_WRITE_ADD,RTCC_HOURS_ADDR);
148 
149  // I set to 0 the bits which are not significant
150  hours = hours & 0b00111111;
151  return (hours);
152 }
153 
154 
155 //************************************************************
156 // RTCC_get_time_seconds function implementation
157 //************************************************************
158 unsigned char* RTCC_get_time_seconds (void) {
159 
160  static unsigned char time[9];
161  unsigned char value;
162 
163  value = RTCC_get_hours();
164 
165  // with +48 I convert the number in ASCII number
166  time[1] = (value & 0b00001111)+48;
167  time[0] = (value >> 4)+48;
168 
169  time[2] = ':';
170 
171  value = RTCC_get_minutes();
172  time[4] = (value & 0b00001111)+48;
173  time[3] = (value >> 4)+48;
174 
175  time[5] = '.';
176 
177  value = RTCC_get_seconds();
178  time[7] = (value & 0b00001111)+48;
179  time[6] = (value >> 4)+48;
180 
181  time[8] = '\0';
182 
183  return (time);
184 
185 }
186 
187 
188 //************************************************************
189 // RTCC_get_time function implementation
190 //************************************************************
191 unsigned char* RTCC_get_time (void) {
192 
193  static unsigned char time[6];
194  unsigned char value;
195 
196  value = RTCC_get_hours();
197 
198  // with +48 I convert the number in ASCII number
199  time[1] = (value & 0b00001111)+48;
200  time[0] = (value >> 4)+48;
201 
202  time[2] = ':';
203 
204  value = RTCC_get_minutes();
205  time[4] = (value & 0b00001111)+48;
206  time[3] = (value >> 4)+48;
207 
208 
209  time[5] = '\0';
210 
211  return (time);
212 
213 }
214 
215 
216 //************************************************************
217 // RTCC_set_days function implementation
218 //************************************************************
219 signed char RTCC_set_days (unsigned char days) {
220 
221  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_DAYS_ADDR,days));
222 }
223 
224 
225 //************************************************************
226 // RTCC_get_days function implementation
227 //************************************************************
228 unsigned char RTCC_get_days (void) {
229 
230  unsigned char days;
231  days = EERandomRead (RTCC_WRITE_ADD,RTCC_DAYS_ADDR);
232 
233  // I set to 0 the bits which are not significant
234  days = days & 0b00111111;
235  return (days);
236 }
237 
238 
239 //************************************************************
240 // RTCC_set_months function implementation
241 //************************************************************
242 signed char RTCC_set_months (unsigned char months) {
243 
244  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_MONTHS_ADDR,months));
245 
246 }
247 
248 
249 //************************************************************
250 // RTCC_get_months function implementation
251 //************************************************************
252 unsigned char RTCC_get_months (void) {
253 
254  unsigned char months;
255  months = EERandomRead (RTCC_WRITE_ADD,RTCC_MONTHS_ADDR);
256 
257  // I set to 0 the bits which are not significant
258  months = months & 0b00011111;
259  return (months);
260 }
261 
262 
263 //************************************************************
264 // RTCC_set_years function implementation
265 //************************************************************
266 signed char RTCC_set_years (unsigned char years) {
267 
268  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_YEARS_ADDR,years));
269 }
270 
271 
272 //************************************************************
273 // RTCC_get_years function implementation
274 //************************************************************
275 unsigned char RTCC_get_years (void) {
276 
277  unsigned char years;
278  years = EERandomRead (RTCC_WRITE_ADD,RTCC_YEARS_ADDR);
279  return (years);
280 }
281 
282 
283 //************************************************************
284 // RTCC_get_date function implementation
285 //************************************************************
286 unsigned char* RTCC_get_date (void) {
287 
288  static unsigned char date[9];
289  unsigned char value;
290 
291  value = RTCC_get_days();
292 
293  // with +48 I convert the number in ASCII number
294  date[1] = (value & 0b00001111)+48;
295  date[0] = (value >> 4)+48;
296 
297  date[2] = '/';
298 
299  value = RTCC_get_months();
300  date[4] = (value & 0b00001111)+48;
301  date[3] = (value >> 4)+48;
302 
303  date[5] = '/';
304 
305 
306  value = RTCC_get_years();
307  date[7] = (value & 0b00001111)+48;
308  date[6] = (value >> 4)+48;
309 
310  date[8] = '\0';
311 
312  return (date);
313 
314 }
315 
316 
317 //************************************************************
318 // RTCC_set_seconds_alarm function implementation
319 //************************************************************
320 signed char RTCC_set_seconds_alarm (unsigned char seconds, unsigned char alarm_enable) {
321  unsigned char value;
322 
323  if (alarm_enable == RTCC_ENABLE_ON) {
324 
325  value = EERandomRead (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR);
326  value = value | 0b01110000;
327  EEByteWrite (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR,value);
328  }
329 
330  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_SECONDS_ALARM_ADDR,seconds));
331 
332 }
333 
334 
335 //************************************************************
336 // RTCC_set_minutes_alarm function implementation
337 //************************************************************
338 signed char RTCC_set_minutes_alarm (unsigned char minutes, unsigned char alarm_enable) {
339  unsigned char value;
340 
341  if (alarm_enable == RTCC_ENABLE_ON) {
342 
343  value = EERandomRead (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR);
344  value = value | 0b01110000;
345  EEByteWrite (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR,value);
346  }
347 
348  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_MINUTS_ALARM_ADDR,minutes));
349 
350 }
351 
352 
353 //************************************************************
354 // RTCC_set_hours_alarm function implementation
355 //************************************************************
356 signed char RTCC_set_hours_alarm (unsigned char hours, unsigned char alarm_enable) {
357 
358  unsigned char value;
359 
360  if (alarm_enable == RTCC_ENABLE_ON) {
361 
362  value = EERandomRead (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR);
363  value = value | 0b01110000;
364  EEByteWrite (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR,value);
365  }
366 
367  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_HOURS_ALARM_ADDR,hours));
368 }
369 
370 
371 //************************************************************
372 // RTCC_set_days_alarm function implementation
373 //************************************************************
374 signed char RTCC_set_days_alarm (unsigned char days, unsigned char alarm_enable) {
375 
376  unsigned char value;
377 
378  if (alarm_enable == RTCC_ENABLE_ON) {
379 
380  value = EERandomRead (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR);
381  value = value | 0b01110000;
382  EEByteWrite (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR,value);
383  }
384 
385  return (EEByteWrite (RTCC_WRITE_ADD,RTCC_DAYS_ALARM_ADDR,days));
386 
387 }
388 
389 
390 //************************************************************
391 // RTCC_enable_alarm_interrupt function implementation
392 //************************************************************
393 signed char RTCC_enable_alarm_interrupt (void) {
394 
395  unsigned char value;
396  value = EERandomRead (RTCC_WRITE_ADD,RTCC_CONFIGURATION_REG_ADDR);
397  value = value | 0b10000000;
398  EEByteWrite (RTCC_WRITE_ADD,RTCC_CONFIGURATION_REG_ADDR,value);
399 
400 
401 }
402 
403 
404 //************************************************************
405 // RTCC_disable_alarm_interrupt function implementation
406 //************************************************************
407 signed char RTCC_disable_alarm_interrupt (void) {
408 
409  unsigned char value;
410 
411  value = EERandomRead (RTCC_WRITE_ADD,RTCC_CONFIGURATION_REG_ADDR);
412  value = value & 0b01111111;
413  EEByteWrite (RTCC_WRITE_ADD,RTCC_CONFIGURATION_REG_ADDR,value);
414 
415 }
416 
417 
418 //************************************************************
419 // RTCC_is_alarm_ON function implementation
420 //************************************************************
421 unsigned char RTCC_is_alarm_ON (void) {
422 
423  unsigned char value;
424  value = EERandomRead (RTCC_WRITE_ADD,RTCC_CONFIGURATION_REG_ADDR);
425 
426  // Just ALM1 and ALM2 bits are controlled
427  //If one alarm is set I reset both flag. Currently only one alarm is suspported
428  if (value & 0b00110000) {
429 
430  value = EERandomRead (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR);
431  //Reset the flags
432  value = value & 0b11110111;
433  // I clean the flag bits without changing the other bits
434  EEByteWrite (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_1_ADDR,value);
435 
436  value = EERandomRead (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_2_ADDR);
437  //Reset the flags
438  value = value & 0b11110111;
439  // I clean the flag bits without changing the other bits
440  EEByteWrite (RTCC_WRITE_ADD,RTCC_ALARM_CONTROL_REG_2_ADDR,value);
441 
442  return (1);
443 
444  } else {
445  return (0);
446  }
447 
448 }
449 
450 
451 //************************************************************
452 // RTCC_increment_minutes function implementation
453 //************************************************************
454 signed char RTCC_increment_minutes (void) {
455 
456  unsigned char minutes;
457  signed char error;
458 
459  // Read the current minutes
460  minutes = RTCC_get_minutes ();
461 
462  // Increment the minutes
463  minutes++;
464 
465  // Check the minute limits
466 
467  if ((minutes&0x0F) > (unsigned char) 9 ) {
468  minutes &= 0xF0;
469  minutes += 0x10;
470  }
471 
472  if (minutes == (unsigned char) RTCC_MAX_MINUTES) {
473 
474  minutes = 0;
475  }
476 
477  // Update the minutes
478  error = RTCC_set_minutes (minutes);
479 
480  return (error);
481 
482 }
483 
484 
485 //************************************************************
486 // RTCC_increment_hours function implementation
487 //************************************************************
488 
489 signed char RTCC_increment_hours (void) {
490 
491  unsigned char hours;
492  signed char error;
493 
494  // Read the current hours
495  hours = RTCC_get_hours ();
496 
497  // Increment the hours
498  hours++;
499 
500  // Check the hour limits
501 
502  if ((hours&0x0F) > (unsigned char) 9 ) {
503  hours &= 0xF0;
504  hours += 0x10;
505  }
506 
507  if (hours == (unsigned char) RTCC_MAX_HOURS) {
508 
509  hours = 0;
510  }
511 
512  // Update the hours
513  error = RTCC_set_hours (hours);
514 
515  return (error);
516 
517 }
518 
519 
520 //************************************************************
521 // RTCC_increment_years function implementation
522 //************************************************************
523 
524 signed char RTCC_increment_years (void) {
525 
526  unsigned char years;
527  signed char error;
528 
529  // Read the current years
530  years = RTCC_get_years ();
531 
532  // Increment the years
533  years++;
534 
535  // Check the year limits
536 
537  if ((years&0x0F) > (unsigned char) 9 ) {
538  years &= 0xF0;
539  years += 0x10;
540  }
541 
542  if (years == (unsigned char) RTCC_MAX_YEARS) {
543 
544  years = 0;
545  }
546 
547  // Update the years
548  error = RTCC_set_years (years);
549 
550  return (error);
551 
552 }
553 
554 
555 //************************************************************
556 // RTCC_increment_months function implementation
557 //************************************************************
558 
559 signed char RTCC_increment_months (void) {
560 
561  unsigned char months;
562  signed char error;
563 
564  // Read the current months
565  months = RTCC_get_months ();
566 
567  // Increment the months
568  months++;
569 
570  // Check the month limits
571 
572  if ((months&0x0F) > (unsigned char) 9 ) {
573  months &= 0xF0;
574  months += 0x10;
575  }
576 
577  if (months == (unsigned char) RTCC_MAX_MONTHS) {
578 
579  months = 1;
580  }
581 
582  // Update the months
583  error = RTCC_set_months (months);
584 
585  return (error);
586 
587 }
588 
589 //************************************************************
590 // RTCC_increment_days function implementation
591 //************************************************************
592 
593 signed char RTCC_increment_days (void) {
594 
595  unsigned char days;
596  signed char error;
597 
598  // Read the current days
599  days = RTCC_get_days ();
600 
601  // Increment the days
602  days++;
603 
604  // Check the day limits
605 
606  if ((days&0x0F) > (unsigned char) 9 ) {
607  days &= 0xF0;
608  days += 0x10;
609  }
610 
611  if (days == (unsigned char) RTCC_MAX_DAYS) {
612 
613  days = 1;
614  }
615 
616  // Update the days
617  error = RTCC_set_days (days);
618 
619  return (error);
620 }
621