[程序源码] 【原创】日历芯片PCF8563驱动层代码分享

[复制链接]
1928|3
 楼主| blust5 发表于 2020-3-14 12:03 | 显示全部楼层 |阅读模式
这份代码是我以前用到这款芯片时写的,后面又整理了一下,弄成方便移植的模块型代码结构,现分享如下:

calendar.c
  1. /*
  2. * calendar.c
  3. *
  4. * Created: 2018/3/30 9:08:12
  5. *  Author: blust
  6. */
  7. #include "calendar.h"

  8. PCF8563_Time_Buff real_time_buff;
  9. PCF8563_Time_Buff pcf8563_time_buff;

  10. /*
  11. main函数初始化时调用如下函数即可,其余函数在该使用时调用即可。
  12. iic_pin_Init();
  13. pcf8563_init();
  14. pcf8563_clear_alarm_flag();
  15. */
  16. //引脚初始化程序需按照对应单片机和硬件引脚连接做响应调整
  17. void iic_pin_Init(void)
  18. {
  19.         struct port_config pin_conf;
  20.         port_get_config_defaults(&pin_conf);
  21.        
  22.         pin_conf.direction  = PORT_PIN_DIR_OUTPUT;
  23.         port_pin_set_config(SCL_PIN, &pin_conf);
  24.         port_pin_set_output_level(SCL_PIN, true);        // 时钟信号SCL配置为输出口

  25.         pin_conf.input_pull =PORT_PIN_PULL_UP;
  26.         pin_conf.direction  = PORT_PIN_DIR_OUTPUT_WTH_READBACK;
  27.         port_pin_set_config(SDA_PIN, &pin_conf);
  28.         port_pin_set_output_level(SDA_PIN, true);        // 数据信号SDA配置为双向口
  29. }

  30. /****************************************************************************
  31. FUNCTION                : iic_start
  32. DESCRIPTION                : IIC通讯起始位(专用函数)
  33. INPUT                        : None
  34. OUTPUT                        : None
  35. UPDATE                        :
  36. AUTHOR                        : blust
  37. DATE                        : 2018/03/30
  38. *****************************************************************************/
  39. void iic_start(void)
  40. {            //时钟保持高,数据线从高到低一次跳变,I2C通信开始
  41.         SDA_PIN_High();
  42.         SCL_PIN_High();
  43.         delay_us(5);      // 延时5us
  44.         SDA_PIN_Low();
  45.         delay_us(5);
  46.         SCL_PIN_Low();
  47. }
  48. /****************************************************************************
  49. FUNCTION                : iic_stop
  50. DESCRIPTION                : IIC通讯停止位(专用函数)
  51. INPUT                        : None
  52. OUTPUT                        : None
  53. UPDATE                        :
  54. AUTHOR                        : blust
  55. DATE                        : 2018/03/30
  56. *****************************************************************************/
  57. void iic_stop(void)
  58. {
  59.         SDA_PIN_Low();       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
  60.         SCL_PIN_High();
  61.         delay_us(5);
  62.         SDA_PIN_High();
  63.         delay_us(5);
  64.         SCL_PIN_Low();
  65. }
  66. /****************************************************************************
  67. FUNCTION                : slave_ACK
  68. DESCRIPTION                : 从机发送应答位子程序(专用函数)
  69. INPUT                        : None
  70. OUTPUT                        : None
  71. UPDATE                        :
  72. AUTHOR                        : blust
  73. DATE                        : 2018/03/30
  74. *****************************************************************************/
  75. void slave_ACK(void)
  76. {
  77.         SDA_PIN_Low();
  78.         SCL_PIN_High();
  79.         delay_us(5);
  80.         SCL_PIN_Low();
  81.         SDA_PIN_High();
  82. }
  83. /****************************************************************************
  84. FUNCTION                : slave_NOACK
  85. DESCRIPTION                : 从机发送非应答位子程序,迫使数据传输过程结束(专用函数)
  86. INPUT                        : None
  87. OUTPUT                        : None
  88. UPDATE                        :
  89. AUTHOR                        : blust
  90. DATE                        : 2018/03/30
  91. *****************************************************************************/
  92. void slave_NOACK(void)
  93. {
  94.         SDA_PIN_High();
  95.         SCL_PIN_High();
  96.         delay_us(5);
  97.         SDA_PIN_Low();
  98.         SCL_PIN_Low();
  99. }
  100. /****************************************************************************
  101. FUNCTION                : check_ACK
  102. DESCRIPTION                : 主机应答位检查子程序,迫使数据传输过程结束(专用函数)
  103. INPUT                        : None
  104. OUTPUT                        : 非应答标志位
  105. UPDATE                        :
  106. AUTHOR                        : blust
  107. DATE                        : 2018/03/30
  108. *****************************************************************************/
  109. bool check_ACK(void)
  110. {
  111.         bool err = false;
  112.         uint8_t i = 100;
  113.         //SDA_PIN_High();      // 将SDA设置成输入,必须先向端口写1
  114.         SCL_PIN_High();
  115.         err = false;
  116.         while(i--)
  117.         {
  118.                 if(SDA_Read()==0)    // 若SDA=0表明有应答
  119.                 {
  120.                         break;
  121.                 }
  122.         }
  123.         if(SDA_Read() == 1)    // 若SDA=1表明非应答,置位非应答标志
  124.                 err = true;
  125.         SCL_PIN_Low();
  126.        
  127.         return err;
  128. }
  129. /****************************************************************************
  130. FUNCTION                : iic_send_byte
  131. DESCRIPTION                : 发送一个字节(专用函数)
  132. INPUT                        : para
  133. OUTPUT                        :
  134. UPDATE                        :
  135. AUTHOR                        : blust
  136. DATE                        : 2018/03/30
  137. *****************************************************************************/
  138. void iic_send_byte(uint8_t para)
  139. {
  140.         uint8_t n=8;     // 向SDA上发送一位数据字节,共八位
  141.         while(n--)
  142.         {
  143.                 if((para&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  144.                 {
  145.                         SDA_PIN_High();    // 传送位1
  146.                         SCL_PIN_High();
  147.                         delay_us(5);
  148.                         SCL_PIN_Low();
  149.                         delay_us(1);
  150.                 }
  151.                 else
  152.                 {
  153.                         SDA_PIN_Low();    // 否则传送位0
  154.                         SCL_PIN_High();
  155.                         delay_us(5);
  156.                         SCL_PIN_Low();
  157.                         delay_us(1);
  158.                 }
  159.                 para = para << 1;    // 数据左移一位
  160.         }
  161. }
  162. /****************************************************************************
  163. FUNCTION                : iic_receive_byte
  164. DESCRIPTION                : 接收一字节子程序(专用函数)
  165. INPUT                        : None
  166. OUTPUT                        : 接收到的数据
  167. UPDATE                        :
  168. AUTHOR                        : blust
  169. DATE                        : 2018/03/30
  170. *****************************************************************************/
  171. uint8_t iic_receive_byte(void)
  172. {
  173.         uint8_t i;    // 从SDA线上读取一上数据字节,共八位
  174.         uint8_t rdata = 0;
  175.         //SDA_PIN_High();
  176.         for(i=0;i<8;i++)
  177.         {
  178.                 delay_us(5);
  179.                 SCL_PIN_High();
  180.                 rdata = rdata<<1;    // 左移一位,或_crol_(temp,1)
  181.                 delay_us(5);
  182.                 if(SDA_Read() == 1)
  183.                         rdata |= 0x01;    // 若接收到的位为1,则数据的最后一位置1
  184.                 else
  185.                         rdata &= 0xfe;    // 否则数据的最后一位置0
  186.                 SCL_PIN_Low();
  187.         }
  188.         return rdata;
  189. }
  190. /****************************************************************************
  191. FUNCTION                : write_CFGbyte
  192. DESCRIPTION                : 写PCF8563寄存器配置(专用函数)
  193. INPUT                        : CFG_add寄存器地址,CFG_data要写入寄存器的数值
  194. OUTPUT                        : 成功返回0 失败返回1
  195. UPDATE                        :
  196. AUTHOR                        : blust
  197. DATE                        : 2018/03/30
  198. *****************************************************************************/
  199. uint8_t write_CFGbyte(uint8_t CFG_add, uint8_t CFG_data)
  200. {
  201.         iic_start();                // 启动I2C
  202.         iic_send_byte(PCF8563_WRITE_ADDR);     // 发送器件写地址
  203.         if(check_ACK() == 1)        // 检查应答位
  204.         {
  205.                 iic_stop();
  206.                 return 1;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  207.         }
  208.         iic_send_byte(CFG_add);       // 发送寄存器地址
  209.         if(check_ACK() == 1)        // 检查应答位
  210.         {
  211.                 iic_stop();
  212.                 return 1;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  213.         }
  214.         iic_send_byte(CFG_data);       // 发送寄存器数据
  215.         if(check_ACK() == 1)        // 检查应答位
  216.         {
  217.                 iic_stop();
  218.                 return 1;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  219.         }
  220.         iic_stop();         // 全部发完则停止
  221.         return 0;
  222. }
  223. /****************************************************************************
  224. FUNCTION                : receive_CFGbyte
  225. DESCRIPTION                : 读取某个寄存器数据(专用函数)
  226. INPUT                        : CFG_add寄存器地址,* CFG_data读取到的寄存器值存放位置
  227. OUTPUT                        : 成功返回0 失败返回1
  228. UPDATE                        :
  229. AUTHOR                        : blust
  230. DATE                        : 2018/03/30
  231. *****************************************************************************/
  232. uint8_t receive_CFGbyte(uint8_t CFG_add, uint8_t * CFG_data)
  233. {
  234.         uint8_t receive_da;
  235.         iic_start();
  236.         iic_send_byte(PCF8563_WRITE_ADDR); //器件写地址
  237.         if(check_ACK() == 1)
  238.         {
  239.                 iic_stop();
  240.                 return 1;
  241.         }
  242.         iic_send_byte(CFG_add); //寄存器地址
  243.         if(check_ACK() == 1)
  244.         {
  245.                 iic_stop();
  246.                 return 1;
  247.         }
  248.         iic_start();
  249.         iic_send_byte(PCF8563_READ_ADDR); //器件读地址
  250.         if(check_ACK() == 1)
  251.         {
  252.                 iic_stop();
  253.                 return 1;
  254.         }
  255.         receive_da=iic_receive_byte();
  256.         slave_NOACK();       // 收到最后一个字节后发送一个非应答位
  257.         iic_stop();
  258.         *CFG_data = receive_da;
  259.         return 0;
  260. }
  261. /****************************************************************************
  262. FUNCTION                : receive_CFGNbyte
  263. DESCRIPTION                : 读取n个寄存器数据(专用函数)
  264. INPUT                        : CFG_add寄存器地址地址,n连续读数位,* buff存储区地址
  265. OUTPUT                        : 成功返回0 失败返回1
  266. UPDATE                        :
  267. AUTHOR                        : blust
  268. DATE                        : 2018/03/30
  269. *****************************************************************************/
  270. uint8_t receive_CFGNbyte(uint8_t CFG_add, uint8_t n, uint8_t * buff)
  271. {
  272.         uint8_t i=0;
  273.         iic_start();
  274.         iic_send_byte(PCF8563_WRITE_ADDR); //器件写地址
  275.         if(check_ACK() == 1)
  276.         {
  277.                 iic_stop();
  278.                 return 1;
  279.         }
  280.         //check_ACK();
  281.         iic_send_byte(CFG_add); //寄存器地址
  282.         if(check_ACK() == 1)
  283.         {
  284.                 iic_stop();
  285.                 return 1;
  286.         }
  287.         //check_ACK();
  288.         iic_start();
  289.         iic_send_byte(PCF8563_READ_ADDR); //器件读地址
  290.         if(check_ACK() == 1)
  291.         {
  292.                 iic_stop();
  293.                 return 1;
  294.         }
  295.         //check_ACK();
  296.         for(i=0;i<n;i++)
  297.         {
  298.                 buff[i]=iic_receive_byte();
  299.                 if(i < n-1)
  300.                         slave_ACK();    // 收到一个字节后发送一个应答位
  301.         }
  302.         slave_NOACK();    // 收到最后一个字节后发送一个非应答位
  303.         iic_stop();
  304.         return 0;
  305. }
  306. /****************************************************************************
  307. FUNCTION                : reset_pcf8563_time
  308. DESCRIPTION                : 复位时钟时间值,用以初次配置时钟
  309. INPUT                        : None
  310. OUTPUT                        : None
  311. UPDATE                        :
  312. AUTHOR                        : blust
  313. DATE                        : 2018/03/30
  314. *****************************************************************************/
  315. void reset_pcf8563_time(void)
  316. {
  317.         pcf8563_time_buff.val.seconds = 0x00;
  318.         pcf8563_time_buff.val.minutes = 0x00;
  319.         pcf8563_time_buff.val.hours   = 0x00;
  320.         pcf8563_time_buff.val.days    = 0x30;
  321.         pcf8563_time_buff.val.weeks   = 0x05;
  322.         pcf8563_time_buff.val.months  = 0x03;
  323.         pcf8563_time_buff.val.years   = 0x18;
  324. }
  325. /****************************************************************************
  326. FUNCTION                : pcf8563_read_time
  327. DESCRIPTION                : 读出时间信息
  328. INPUT                        : None
  329. OUTPUT                        : None
  330. UPDATE                        :
  331. AUTHOR                        : blust
  332. DATE                        : 2018/03/30
  333. *****************************************************************************/
  334. void pcf8563_read_time(void)
  335. {
  336.         receive_CFGNbyte(PCF8563_TIME_ADD,7,pcf8563_time_buff.data);
  337.        
  338.         pcf8563_time_buff.val.seconds &= 0x7F;
  339.         pcf8563_time_buff.val.minutes &= 0x7F;
  340.         pcf8563_time_buff.val.hours   &= 0x3F;
  341.         pcf8563_time_buff.val.days    &= 0x3F;
  342.         pcf8563_time_buff.val.weeks   &= 0x07;
  343.         pcf8563_time_buff.val.months  &= 0x1F;
  344.         pcf8563_time_buff.val.years   &= 0xFF;
  345. }
  346. /****************************************************************************
  347. FUNCTION                : pcf8563_set_time
  348. DESCRIPTION                : 写时间修改值
  349. INPUT                        : None
  350. OUTPUT                        : None
  351. UPDATE                        :
  352. AUTHOR                        : blust
  353. DATE                        : 2018/03/30
  354. *****************************************************************************/
  355. void pcf8563_set_time(void)
  356. {
  357.         uint8_t i;
  358.         for(i=0;i<7;i++)
  359.         {
  360.                 write_CFGbyte(PCF8563_TIME_ADD+i,pcf8563_time_buff.data[i]);
  361.         }
  362. }
  363. /****************************************************************************
  364. FUNCTION                : pcf8563_alarm_set
  365. DESCRIPTION                : 设置报警时间
  366. INPUT                        : min_alarm报警分,hour_alarm报警时,day_alarm报警日,week_alarm报警周
  367. OUTPUT                        : None
  368. UPDATE                        :
  369. AUTHOR                        : blust
  370. DATE                        : 2018/03/30
  371. *****************************************************************************/
  372. void pcf8563_alarm_set(uint8_t min_alarm, uint8_t hour_alarm, uint8_t day_alarm, uint8_t week_alarm)
  373. {
  374.         write_CFGbyte(PCF8563_MIN_ALARM_ADD,min_alarm);                // 分钟报警配置 每小时报警一次
  375.         write_CFGbyte(PCF8563_HOUR_ALARM_ADD,hour_alarm);        // 小时报警配置 每天报警一次
  376.         write_CFGbyte(PCF8563_DAY_ALARM_ADD,day_alarm);                // 日报警配置 每月报警一次
  377.         write_CFGbyte(PCF8563_WEEK_ALARM_ADD,week_alarm);        // 星期报警配置 每周报警一次
  378. }
  379. /****************************************************************************
  380. FUNCTION                : pcf8563_clear_alarm_flag
  381. DESCRIPTION                : 清除报警时间
  382. INPUT                        : None
  383. OUTPUT                        : None
  384. UPDATE                        :
  385. AUTHOR                        : blust
  386. DATE                        : 2018/04/02
  387. *****************************************************************************/
  388. void pcf8563_clear_alarm_flag(void)
  389. {
  390.         write_CFGbyte(PCF8563_CTRL2_ADD,0x12);                // 清除报警标志位
  391. }
  392. /****************************************************************************
  393. FUNCTION                : pcf8563_init
  394. DESCRIPTION                : PCF8563初始化
  395. INPUT                        : None
  396. OUTPUT                        : None
  397. UPDATE                        :
  398. AUTHOR                        : blust
  399. DATE                        : 2018/03/30
  400. *****************************************************************************/
  401. void pcf8563_init(void)
  402. {
  403.         uint8_t temp;
  404.         if(receive_CFGbyte(PCF8563_TIME_ADD, &temp)==0)
  405.         {
  406.                 if((temp&0x80) == 0x80) /*检查是否第一次启动,是则初始化时间*/
  407.                 {
  408.                         reset_pcf8563_time();
  409.                         pcf8563_set_time();
  410.                         write_CFGbyte(PCF8563_CTRL1_ADD,0x00);        // 启动PCF8563
  411.                         write_CFGbyte(PCF8563_CTRL2_ADD,0x12);        // 报警允许中断输出
  412.                         write_CFGbyte(PCF8563_CLKOUT_ADD,0x00);        // CLKOUT输出禁止
  413.                         write_CFGbyte(PCF8563_TIMER_CTRL_ADD,0x00);        // 定时器禁止
  414.                         write_CFGbyte(PCF8563_MIN_ALARM_ADD,0x80);        // 分钟报警配置 每小时报警一次
  415.                         write_CFGbyte(PCF8563_HOUR_ALARM_ADD,0x80);        // 小时报警配置 每天报警一次
  416.                         write_CFGbyte(PCF8563_DAY_ALARM_ADD,0x80);        // 日报警配置 每月报警一次
  417.                         write_CFGbyte(PCF8563_WEEK_ALARM_ADD,0x80);        // 星期报警配置 每周报警一次
  418.                 }
  419.         }
  420. }

  421. /****************************************************************************
  422. FUNCTION                : ymd_to_week
  423. DESCRIPTION                : 通过年月日计算出当天的星期数(专用函数)
  424. INPUT                        : year:年份,month:月份,day:日期
  425. OUTPUT                        : 星期数(0:周日 1:周一 …… 6:周六)
  426. UPDATE                        :
  427. AUTHOR                        : blust
  428. DATE                        : 2018/03/30
  429. *****************************************************************************/
  430. uint8_t ymd_to_week(uint16_t year,uint8_t month,uint8_t day)
  431. {
  432.         int8_t week;
  433.         int8_t c, y;
  434.         if (month <= 2)
  435.         {
  436.                 month += 12;
  437.                 year -= 1;
  438.         }
  439.         c = year/100;
  440.         y = year%100;
  441.         week = c/4 + y + y/4 + 13*(month+1)/5 + day - 2*c - 1;
  442.         week = week > 0 ? (week % 7):((week % 7) + 7);
  443.        
  444.         return week;
  445. }

  446. /****************************************************************************
  447. FUNCTION                : time_to_real
  448. DESCRIPTION                : 将PCF8563读取的寄存器值转换为实时时间
  449. INPUT                        : None
  450. OUTPUT                        : None
  451. UPDATE                        :
  452. AUTHOR                        : blust
  453. DATE                        : 2018/03/30
  454. *****************************************************************************/
  455. void time_to_real(void)
  456. {
  457.         real_time_buff.val.seconds = ((pcf8563_time_buff.val.seconds)/16)*10 + pcf8563_time_buff.val.seconds % 16;
  458.         real_time_buff.val.minutes = ((pcf8563_time_buff.val.minutes)/16)*10 + pcf8563_time_buff.val.minutes % 16;
  459.         real_time_buff.val.hours = ((pcf8563_time_buff.val.hours)/16)*10 + pcf8563_time_buff.val.hours % 16;
  460.         real_time_buff.val.days = ((pcf8563_time_buff.val.days)/16)*10 + pcf8563_time_buff.val.days % 16;
  461.         real_time_buff.val.months = ((pcf8563_time_buff.val.months)/16)*10 + pcf8563_time_buff.val.months % 16;
  462.         real_time_buff.val.years = ((pcf8563_time_buff.val.years)/16)*10 + pcf8563_time_buff.val.years % 16;
  463.        
  464.         real_time_buff.val.weeks = ymd_to_week(real_time_buff.val.years+2000,real_time_buff.val.months,real_time_buff.val.days);
  465. }

  466. /****************************************************************************
  467. FUNCTION                : time_to_pcf8563
  468. DESCRIPTION                : 将实时时间转换为PCF8563读取的寄存器值
  469. INPUT                        : None
  470. OUTPUT                        : None
  471. UPDATE                        :
  472. AUTHOR                        : blust
  473. DATE                        : 2018/03/30
  474. *****************************************************************************/
  475. void time_to_pcf8563(void)
  476. {
  477.         real_time_buff.val.weeks = ymd_to_week(real_time_buff.val.years+2000,real_time_buff.val.months,real_time_buff.val.days);
  478.        
  479.         pcf8563_time_buff.val.seconds = (real_time_buff.val.seconds/10)*16 + real_time_buff.val.seconds%10;
  480.         pcf8563_time_buff.val.minutes = (real_time_buff.val.minutes/10)*16 + real_time_buff.val.minutes%10;
  481.         pcf8563_time_buff.val.hours = (real_time_buff.val.hours/10)*16 + real_time_buff.val.hours%10;
  482.         pcf8563_time_buff.val.days = (real_time_buff.val.days/10)*16 + real_time_buff.val.days%10;
  483.         pcf8563_time_buff.val.months = (real_time_buff.val.months/10)*16 + real_time_buff.val.months%10;
  484.         pcf8563_time_buff.val.years = (real_time_buff.val.years/10)*16 + real_time_buff.val.years%10;
  485.         pcf8563_time_buff.val.weeks = real_time_buff.val.weeks;
  486. }

  487. /****************************************************************************
  488. FUNCTION                : leap_year
  489. DESCRIPTION                : 判断是否是闰年(专用函数)
  490. INPUT                        : year:需要判断的年份数
  491. OUTPUT                        : 闰年返回1,否则返回0
  492. UPDATE                        :
  493. AUTHOR                        : blust
  494. DATE                        : 2018/03/30
  495. *****************************************************************************/
  496. uint8_t leap_year(uint16_t year)
  497. {
  498.     if ((year % 400) == 0)
  499.         {
  500.         return 1;
  501.     }
  502.         else if ((year % 100) == 0)
  503.         {
  504.         return 0;
  505.     }
  506.         else if ((year % 4) == 0)
  507.         {
  508.         return 1;
  509.     }
  510.         else
  511.         {
  512.         return 0;
  513.     }
  514. }
  515. /*
  516. * 功能:
  517. *     得到每个月有多少天
  518. * 参数:
  519. *     month:需要得到天数的月份数
  520. *     year:该月所对应的年份数
  521. *
  522. * 返回值:
  523. *     该月有多少天
  524. *
  525. */
  526. /****************************************************************************
  527. FUNCTION                : days_of_month
  528. DESCRIPTION                : 计算每月的天数(专用函数)
  529. INPUT                        : month:月份,year:年份
  530. OUTPUT                        : 返回该月份的天数
  531. UPDATE                        :
  532. AUTHOR                        : blust
  533. DATE                        : 2018/03/30
  534. *****************************************************************************/
  535. uint8_t days_of_month(uint8_t month, uint16_t year)
  536. {
  537.         const uint8_t day_per_month[MONTH_PER_YEAR] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  538.     if ((month == 0) || (month > 12))
  539.         {
  540.         return day_per_month[1] + leap_year(year);
  541.     }
  542.     if (month != 2)
  543.         {
  544.         return day_per_month[month - 1];
  545.     }
  546.         else
  547.         {
  548.         return day_per_month[1] + leap_year(year);
  549.     }
  550. }

  551. /****************************************************************************
  552. FUNCTION                : ymd_to_week
  553. DESCRIPTION                : UNIX时间戳转换为实时时间(只适用于20xx年)
  554. INPUT                        : UNIX时间戳
  555. OUTPUT                        : 无(转换结果存储在 real_time_buff )
  556. UPDATE                        : 如果需要扩大年份包含范围,需要将年份定义为U16,并将 “real_time_buff.val.years = y % 100”的“% 100”删掉
  557. AUTHOR                        : blust
  558. DATE                        : 2018/03/30
  559. *****************************************************************************/
  560. void unix_to_realtime(uint32_t utc_sec)
  561. {
  562.         uint32_t temp;
  563.         uint16_t y, d;
  564.         uint8_t m;
  565.         utc_sec += SEC_PER_HOUR*8;        // 时区调整
  566.         /*  小时  */
  567.         temp = utc_sec % SEC_PER_DAY;
  568.         real_time_buff.val.hours = temp / SEC_PER_HOUR;
  569.         /*  分钟  */
  570.         temp %= SEC_PER_HOUR;
  571.         real_time_buff.val.minutes = temp / SEC_PER_MIN;
  572.         /*  秒  */
  573.         real_time_buff.val.seconds = temp % SEC_PER_MIN;
  574.        
  575.         /*  年  */
  576.         temp = utc_sec / SEC_PER_DAY;
  577.         for (y = UTC_BASE_YEAR; temp > 0; y++)
  578.         {
  579.                 d = (DAY_PER_YEAR + leap_year(y));
  580.                 if (temp >= d)
  581.                 {
  582.                         temp -= d;
  583.                 }
  584.                 else
  585.                 {
  586.                         break;
  587.                 }
  588.         }
  589.         real_time_buff.val.years = y % 100;
  590.         /*  月  */
  591.         for (m = 1; m < MONTH_PER_YEAR; m++)
  592.         {
  593.                 d = days_of_month(m, y);
  594.                 if (temp >= d)
  595.                 {
  596.                         temp -= d;
  597.                 }
  598.                 else
  599.                 {
  600.                         break;
  601.                 }
  602.         }

  603.         real_time_buff.val.months = m;
  604.         /*  日  */
  605.         real_time_buff.val.days = (uint8_t)(temp + 1);
  606.         real_time_buff.val.weeks = ymd_to_week(y, m, real_time_buff.val.days);
  607. }



 楼主| blust5 发表于 2020-3-14 12:05 | 显示全部楼层
calendar.h
  1. /*
  2. * calendar.h
  3. *
  4. * Created: 2018/3/30 9:08:39
  5. *  Author: blust
  6. */


  7. #ifndef CALENDAR_H_
  8. #define CALENDAR_H_

  9. #include "../src/asf.h"

  10. /************************** PCF8563地址宏定义 ***********************************/
  11. #define  PCF8563_WRITE_ADDR                        0xA2        // PCF8563设备写地址
  12. #define  PCF8563_READ_ADDR                        0xA3        // PCF8563设备读地址

  13. #define  PCF8563_CTRL1_ADD                        0x00        // 控制寄存器1地址
  14. #define  PCF8563_CTRL2_ADD                        0x01        // 控制寄存器2地址
  15. #define  PCF8563_CLKOUT_ADD                        0x0D        // CLKOUT输出寄存器地址
  16. #define  PCF8563_TIMER_CTRL_ADD                0x0E        // 定时器控制寄存器地址

  17. #define  PCF8563_TIME_ADD                        0x02        // 时间地址
  18. #define  PCF8563_MIN_ALARM_ADD                0x09        // 分钟报警地址
  19. #define  PCF8563_HOUR_ALARM_ADD                0x0A        // 小时报警地址
  20. #define  PCF8563_DAY_ALARM_ADD                0x0B        // 日报警地址
  21. #define  PCF8563_WEEK_ALARM_ADD                0x0C        // 星期报警地址

  22. /************************ UNIX时间戳转换用宏定义 ******************************/
  23. #define UTC_BASE_YEAR                                1970        // UNIX时间戳起始年份
  24. #define MONTH_PER_YEAR                                12                // 每年的月数
  25. #define DAY_PER_YEAR                                365                // 每年的天数
  26. #define SEC_PER_DAY                                        86400        // 每天的秒数
  27. #define SEC_PER_HOUR                                3600        // 每小时的秒数
  28. #define SEC_PER_MIN                                        60                // 每分钟的秒数

  29. //引脚定义需按照对应单片机和硬件引脚连接做响应调整
  30. /********************************* SDA **********************************************/
  31. #define SCL_PIN                                                PIN_PB17
  32. #define SCL_PIN_Low()                                port_pin_set_output_level(SCL_PIN, false)
  33. #define SCL_PIN_High()                                port_pin_set_output_level(SCL_PIN, true)
  34. #define SCL_PIN_Toggle()                        port_pin_toggle_output_level(SCL_PIN)


  35. /********************************* SCL  **********************************************/
  36. #define SDA_PIN                                                PIN_PB16
  37. #define SDA_Read()                                        port_pin_get_input_level(SDA_PIN)
  38. #define SDA_PIN_Low()                                port_pin_set_output_level(SDA_PIN, false)
  39. #define SDA_PIN_High()                                port_pin_set_output_level(SDA_PIN, true)
  40. #define SDA_PIN_Toggle()                        port_pin_toggle_output_level(SDA_PIN)

  41. // 时间数组结构体定义 blust 20180330
  42. typedef union
  43. {
  44.         struct
  45.         {
  46.                 uint8_t seconds;        // 秒
  47.                 uint8_t minutes;        // 分钟
  48.                 uint8_t hours;                // 小时
  49.                 uint8_t days;                // 日
  50.                 uint8_t weeks;                // 星期
  51.                 uint8_t months;                // 月/世纪
  52.                 uint8_t years;                // 年
  53.         }val;
  54.         uint8_t data[7];
  55. }PCF8563_Time_Buff;
  56. extern PCF8563_Time_Buff real_time_buff;
  57. extern PCF8563_Time_Buff pcf8563_time_buff;



  58. extern void iic_pin_Init(void);
  59. extern uint8_t receive_CFGNbyte(uint8_t CFG_add, uint8_t n, uint8_t * buff);
  60. extern void pcf8563_read_time(void);
  61. extern void pcf8563_set_time(void);
  62. extern void pcf8563_alarm_set(uint8_t min_alarm,uint8_t hour_alarm,uint8_t day_alarm,uint8_t week_alarm);
  63. extern void pcf8563_clear_alarm_flag(void);
  64. extern void pcf8563_init(void);
  65. extern void time_to_real(void);
  66. extern void time_to_pcf8563(void);
  67. extern void unix_to_realtime(uint32_t unix_time);

  68. #endif /* CALENDAR_H_ */
 楼主| blust5 发表于 2020-3-14 12:11 | 显示全部楼层
文件下载:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
robertwang126 发表于 2020-4-15 20:19 | 显示全部楼层
谢谢分享学习一下,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:业精于勤荒于嬉,行成于思毁于随。

72

主题

2977

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部