[STM8] 实时时钟SD30XX读写STM8参考程序

[复制链接]
827|2
 楼主| jiekou001 发表于 2018-1-18 20:33 | 显示全部楼层 |阅读模式
  1. //************************************************************
  2. // 实时时钟SD30XX读写STM8参考程序
  3. // MCU: STM8S103F3
  4. //************************************************************

  5. #include "stm8s103f3p.h"

  6. #define uchar unsigned char
  7. #define SCL_H  PC_ODR |= 0X08
  8. #define SDA_H  PA_ODR |= 0X08
  9. #define SCL_L  PC_ODR &= 0XF7
  10. #define SDA_L  PA_ODR &= 0XF7
  11. #define SDAM  ((PA_IDR & 0X08) >> 3)
  12. #define SET_SCL_OUT()    {PC_DDR |= 0X08; PC_CR1 |= 0X08; PC_CR2 &= 0XF7;}//scl选择管脚为PC3
  13. #define SET_SDA_OUT()    {PA_DDR |= 0X08; PA_CR1 |= 0X08; PA_CR2 &= 0XF7;}//sda选择管脚为PA3
  14. #define SET_SDA_IN()     {PA_DDR &= 0XF7; PA_CR1 &= 0XF7; PA_CR2 &= 0XF7;}//浮空输入

  15. uchar s_data[7] = {0};

  16. void GPIO_I2c_Master_Init(void)
  17. {
  18.   I2C_CR1 &= 0xFE;      
  19.   SET_SCL_OUT();    //PC3 输出;推挽;2MHz时钟;
  20.   SET_SDA_OUT();    //PA3 输出;推挽;2MHz时钟;
  21. }

  22. void Delay_5us(void)
  23. {
  24.   uchar i = 10;    //fcpu 16MHz

  25.   for (; i > 0; i--);
  26. }

  27. void I2C_Start(void)//起始信号
  28. {
  29.   SDA_H;                    
  30.   SCL_H;                    
  31.   Delay_5us();               
  32.   SDA_L;                  
  33.   Delay_5us();               
  34.   SCL_L;                    
  35. }

  36. void I2C_Stop(void)//结束信号
  37. {
  38.   SDA_L;                  
  39.   SCL_H;                  
  40.   Delay_5us();               
  41.   SDA_H;                  
  42.   Delay_5us();               
  43. }

  44. void I2C_SendACK(uchar ack)//应答或者非应答信号
  45. {
  46.   if (ack == 0)
  47.   {
  48.     SDA_L;
  49.   }
  50.   else
  51.   {
  52.     SDA_H;
  53.   }
  54.   SCL_H;                  
  55.   Delay_5us();  
  56.   
  57.   SCL_L;                    
  58.   Delay_5us();     
  59. }

  60. uchar I2C_SendByte(uchar sendDAT)//发送字节
  61. {
  62.   uchar i = 0;
  63.   uchar revack = 0;

  64.   for (i= 0 ; i< 8; i++)         
  65.   {
  66.     SCL_L;               
  67.     Delay_5us();  
  68.   
  69.     if (sendDAT & 0x80)  
  70.     {
  71.       SDA_H;
  72.     }
  73.     else  
  74.     {      
  75.       SDA_L;
  76.     }
  77.     sendDAT <<=  1;
  78.     SCL_H;               
  79.     Delay_5us();     
  80.   }
  81.   SCL_L;               
  82.   Delay_5us();  
  83.   SET_SDA_IN();
  84.   SCL_H;   
  85.   _asm("nop");
  86.   _asm("nop");
  87.   revack = (uchar)SDAM;
  88.   Delay_5us();   
  89.   SCL_L;   
  90.   SET_SDA_OUT();
  91.   Delay_5us();  

  92.   return revack;
  93. }

  94. uchar I2C_RecvByte(void)//接收字节
  95. {
  96.   uchar i = 0;
  97.   uchar revDAT = 0;
  98.   
  99.   SDA_H;  
  100.   SET_SDA_IN();
  101.   for (i = 0; i < 8; i++)         
  102.   {
  103.      revDAT <<= 1;      
  104.      SCL_H;
  105.      _asm("nop");
  106.      _asm("nop");
  107.      if (SDAM)
  108.      {
  109.         revDAT |= 0x01;
  110.      }
  111.      else
  112.      {
  113.         revDAT &= 0xfe;
  114.      }

  115.      Delay_5us();
  116.      SCL_L;               
  117.      Delay_5us();  
  118.   }   
  119.   SET_SDA_OUT();
  120.   
  121.   return revDAT;
  122. }

  123. void WriteOn(void)//打开写保护
  124. {
  125.   I2C_Start();
  126.   I2C_SendByte(0x64);
  127.   I2C_SendByte(0x10);
  128.   I2C_SendByte(0x80);
  129.   I2C_Stop();
  130.   
  131.   I2C_Start();
  132.   I2C_SendByte(0x64);
  133.   I2C_SendByte(0x0f);
  134.   I2C_SendByte(0x84);
  135.   I2C_Stop();
  136. }

  137. void WriteOff(void)//关闭写保护
  138. {
  139.   I2C_Start();
  140.   I2C_SendByte(0x64);
  141.   I2C_SendByte(0x10);
  142.   I2C_SendByte(0x00);
  143.   I2C_Stop();
  144.   
  145.   I2C_Start();
  146.   I2C_SendByte(0x64);
  147.   I2C_SendByte(0x0f);
  148.   I2C_SendByte(0x00);
  149.   I2C_Stop();
  150. }

  151. void read_time_from_sd30xx(void)//从sd30xx读时间
  152. {
  153.   uchar n = 0;

  154.   I2C_Start();
  155.   if (I2C_SendByte(0x65))
  156.   {
  157.     I2C_Stop();

  158.     return;
  159.   }
  160.   for (n = 0; n < 7; n++)
  161.   {
  162.     s_data[n] = I2C_RecvByte();
  163.     if (n == 6)
  164.     {
  165.       I2C_SendACK(1);
  166.     }
  167.     I2C_SendACK(0);
  168.   }
  169.   I2C_Stop();
  170. }



  171. void write_time_to_sd30xx(void)//写时间到sd30xx
  172. {
  173.   uchar n = 0;

  174.   WriteOn();
  175.   
  176.   I2C_Start();
  177.   I2C_SendByte(0x64);
  178.   I2C_SendByte(0x00);
  179.   for (n = 0; n < 7; n++)
  180.   {
  181.     I2C_SendByte(s_data[n]);
  182.   }
  183.   I2C_Stop();
  184.   
  185.   WriteOff();
  186. }


 楼主| jiekou001 发表于 2018-1-18 20:33 | 显示全部楼层
虽然这个不常用,但是找来分享给大家。
yiy 发表于 2018-1-19 15:36 | 显示全部楼层
非常感谢,学到了一招,宏都要用大括号搞起来。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

147

主题

1539

帖子

2

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