找回密码
 注册

QQ登录

只需一步,快速开始

搜索

stm32模拟IIC驱动RX8025时钟芯片C语言参考程序

[复制链接]
coolice 发表于 2021-8-13 17:46:55 | 显示全部楼层 |阅读模式
  1. /* Includes--------------------------------------------------------------*/
  2. //#include        "sysconfig.h"
  3. #include "stm32f10x.h"
  4. //#include        "bsp_SIIC.h"
  5. #include "bsp_RX8025.h"
  6. /*
  7. Private define-----------------------------------------------------------------------------*/
  8. // 设备读写地址
  9. #define        RX8025_ADDR_READ                0x65
  10. #define        RX8025_ADDR_WRITE                0x64
  11. // 设备寄存器地址
  12. #define        RX8025_ADDR_SECONDS                0x00
  13. #define        RX8025_ADDR_WEEK                0x30
  14. #define        RX8025_ADDR_DATES                0x40
  15. #define        RX8025_ADDR_MONTH                0x50
  16. #define        RX8025_ADDR_MINUTES                0x80
  17. #define        RX8025_ADDR_CONTROL1        0xE0
  18. #define        RX8025_ADDR_CONTROL2        0xF0
  19. // 设备操作模式
  20. #define        RX8025_WRITE_MODE                0xF0
  21. #define        RX8025_READ_MODE                0xF0
  22. #define        RX8025_SIMP_READ_MODE        0x04
  23. #define u8BAND(addr, u8num) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(u8num<<2))
  24. #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
  25. #define u8_ADDR(addr, u8num)   MEM_ADDR(u8BAND(addr, u8num))
  26. //IO口地址映射
  27. #define GPIOA_ODR_Addr    (GPIOA_BASE+12) //0x4001080C
  28. #define GPIOB_ODR_Addr    (GPIOB_BASE+12) //0x40010C0C
  29. #define GPIOC_ODR_Addr    (GPIOC_BASE+12) //0x4001100C
  30. #define GPIOD_ODR_Addr    (GPIOD_BASE+12) //0x4001140C
  31. #define GPIOE_ODR_Addr    (GPIOE_BASE+12) //0x4001180C
  32. #define GPIOF_ODR_Addr    (GPIOF_BASE+12) //0x40011A0C   
  33. #define GPIOG_ODR_Addr    (GPIOG_BASE+12) //0x40011E0C   
  34. #define GPIOA_IDR_Addr    (GPIOA_BASE+8) //0x40010808
  35. #define GPIOB_IDR_Addr    (GPIOB_BASE+8) //0x40010C08
  36. #define GPIOC_IDR_Addr    (GPIOC_BASE+8) //0x40011008
  37. #define GPIOD_IDR_Addr    (GPIOD_BASE+8) //0x40011408
  38. #define GPIOE_IDR_Addr    (GPIOE_BASE+8) //0x40011808
  39. #define GPIOF_IDR_Addr    (GPIOF_BASE+8) //0x40011A08
  40. #define GPIOG_IDR_Addr    (GPIOG_BASE+8) //0x40011E08
  41. //IO口操作,只对单一的IO口!
  42. //确保n的值小于16!
  43. #define PAout(n)   u8_ADDR(GPIOA_ODR_Addr,n)  //输出
  44. #define PAin(n)    u8_ADDR(GPIOA_IDR_Addr,n)  //输入
  45. #define PBout(n)   u8_ADDR(GPIOB_ODR_Addr,n)  //输出
  46. #define PBin(n)    u8_ADDR(GPIOB_IDR_Addr,n)  //输入
  47. #define PCout(n)   u8_ADDR(GPIOC_ODR_Addr,n)  //输出
  48. #define PCin(n)    u8_ADDR(GPIOC_IDR_Addr,n)  //输入
  49. #define PDout(n)   u8_ADDR(GPIOD_ODR_Addr,n)  //输出
  50. #define PDin(n)    u8_ADDR(GPIOD_IDR_Addr,n)  //输入
  51. #define PEout(n)   u8_ADDR(GPIOE_ODR_Addr,n)  //输出
  52. #define PEin(n)    u8_ADDR(GPIOE_IDR_Addr,n)  //输入
  53. #define PFout(n)   u8_ADDR(GPIOF_ODR_Addr,n)  //输出
  54. #define PFin(n)    u8_ADDR(GPIOF_IDR_Addr,n)  //输入
  55. #define PGout(n)   u8_ADDR(GPIOG_ODR_Addr,n)  //输出
  56. #define PGin(n)    u8_ADDR(GPIOG_IDR_Addr,n)  //输入
  57. /////////////////////////////////////////////////////////////////
  58. //Ex_NVIC_Config专用定义
  59. #define GPIO_A 0
  60. #define GPIO_B 1
  61. #define GPIO_C 2
  62. #define GPIO_D 3
  63. #define GPIO_E 4
  64. #define GPIO_F 5
  65. #define GPIO_G 6

  66. //IO操作函数
  67. #define IIC_SCL PBout(15) //SCL
  68. #define IIC_SDA PBout(14) //SDA
  69. #define READ_SDA PBin(14) //输入SDA
  70. void I2C_Configuration(void);
  71. /* Private typedef----------------------------------------------------------------------------*/
  72. // 寄存器结构
  73. // CONTROL1,结构定义
  74. typedef struct
  75. {
  76.         u8 CT:3;
  77.         u8 TEST:1;
  78.         u8 nCLEN2:1;
  79.         u8 HOUR24:1;
  80.         u8 DALE:1;
  81.         u8 WALE:1;
  82. }_RX8025_REG_CONTROL1_BITS;
  83. typedef union
  84. {
  85.         u8 byte;
  86.         _RX8025_REG_CONTROL1_BITS bits;
  87. }_RX8025_REG_CONTROL1;
  88. /* Private macro------------------------------------------------------------------------------*/
  89. /* Private variables--------------------------------------------------------------------------*/
  90. /* Private function prototypes----------------------------------------------------------------*/
  91. /* Private functions--------------------------------------------------------------------------*/

  92. void I2C_Configuration(void)
  93. {
  94.         GPIO_InitTypeDef  GPIO_InitStructure;
  95.         
  96.         RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO ,ENABLE);
  97.         
  98.         
  99.         /* Configure I2C2 pins: PB15 -> SCL and PB14 -> SDA */
  100.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  101.         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14 | GPIO_Pin_15;
  102.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  103.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  
  104.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  105. }

  106. void SDA_IN(void) //sda线输入 ,PA11
  107. {
  108.         GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构体                        
  109.         // Configure I2C1 pins:SDA
  110.         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14;
  111.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  112.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  113.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  114. }

  115. void SDA_OUT(void) //sda线输出
  116. {
  117.         GPIO_InitTypeDef GPIO_InitStructure;//声明GPIO初始化结构体
  118.         GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14;
  119.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  120.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  121.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  122. }
  123. //   延时总时间=cnt*16+24us
  124. void delay(u16 cnt)
  125. {
  126.         u8 i;
  127. for(;cnt>0;cnt--)
  128.         for(i=0;i<100;i++);
  129. }
  130. //产生IIC起始信号
  131. void IIC_Start(void)
  132. {
  133.         SDA_OUT(); //sda线输出
  134.         IIC_SDA=1;
  135.         IIC_SCL=1;
  136.         delay(4);
  137.         IIC_SDA=0;//START:when CLK is high,DATA change form high to low
  138.         delay(4);
  139.         IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  140. }
  141. //产生IIC停止信号
  142. void IIC_Stop(void)
  143. {
  144.         SDA_OUT();//sda线输出
  145.         IIC_SCL=0;
  146.         IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  147.         delay(4);
  148.         IIC_SCL=1;
  149.         IIC_SDA=1;//发送I2C总线结束信号
  150.         delay(4);
  151. }
  152. //等待应答信号到来
  153. //返回值:1,接收应答失败
  154. // 0,接收应答成功
  155. u8 IIC_Wait_Ack(void)
  156. {
  157.         u8 ucErrTime=0;
  158.         SDA_IN(); //SDA设置为输入
  159.         IIC_SDA=1;delay(1);
  160.         IIC_SCL=1;delay(1);
  161.         while(READ_SDA)
  162.         {
  163.                 ucErrTime++;
  164.                 if(ucErrTime>250)
  165.                 {
  166.                         IIC_Stop();
  167.                         return 1;
  168.                 }
  169.         }
  170.         IIC_SCL=0;//时钟输出0
  171.         return 0;
  172. }
  173. //产生ACK应答
  174. void IIC_ACK(void)
  175. {
  176.         IIC_SCL=0;
  177.         SDA_OUT();
  178.         IIC_SDA=0;
  179.         delay(2);
  180.         IIC_SCL=1;
  181.         delay(2);
  182.         IIC_SCL=0;
  183. }
  184. //不产生ACK应答
  185. void IIC_NAck(void)
  186. {
  187.         IIC_SCL=0;
  188.         SDA_OUT();
  189.         IIC_SDA=1;
  190.         delay(2);
  191.         IIC_SCL=1;
  192.         delay(2);
  193.         IIC_SCL=0;
  194. }
  195. //IIC发送一个字节
  196. //返回从机有无应答
  197. //1,有应答
  198. //0,无应答
  199. u8 IIC_Send_Byte(u8 txd)
  200. {
  201.         u8 t;
  202.         SDA_OUT();
  203.         IIC_SCL=0;//拉低时钟开始数据传输
  204.         for(t=0;t<8;t++)
  205.         {
  206.                 IIC_SDA=(txd&0x80)>>7;
  207.                 txd<<=1;
  208.                 delay(2); //对TEA5767这三个延时都是必须的
  209.                 IIC_SCL=1;
  210.                 delay(2);
  211.                 IIC_SCL=0;
  212.                 delay(2);
  213.         }
  214.         t=IIC_Wait_Ack();
  215.         return (t);
  216. }
  217. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  218. u8 IIC_Read_Byte(u8 ack)
  219. {
  220.         u8 i,receive=0;
  221.         SDA_IN();//SDA设置为输入
  222.         for(i=0;i<8;i++ )
  223.         {
  224.                 IIC_SCL=0;
  225.                 delay(2);
  226.                 IIC_SCL=1;
  227.                 receive<<=1;
  228.                 if(READ_SDA)receive++;
  229.                 delay(1);
  230.         }
  231.         if (!ack)
  232.         IIC_NAck();//发送nACK
  233.         else
  234.         IIC_ACK(); //发送ACK
  235.         return receive;
  236. }
  237. void RX8025Write(u8 addr,u8 *pData,u8 len)
  238. {
  239.         u8 i;
  240.         IIC_Start();
  241.         if(IIC_Send_Byte(RX8025_ADDR_WRITE)==1)
  242.         {
  243.                 IIC_Stop();
  244.                 return;
  245.         }
  246.         if(IIC_Send_Byte(addr)==1)
  247.         {
  248.                 IIC_Stop();
  249.                 return;
  250.         }
  251.         for(i=0;i<len;i++)
  252.         {
  253.                 if(IIC_Send_Byte(pData)==1)
  254.                 {
  255.                         IIC_Stop();
  256.                         return;
  257.                 }
  258.         }
  259.         IIC_Stop();
  260. }
  261. void RX8025Read(u8 addr,u8 *pData,u8 len)
  262. {
  263.         u8 i;
  264.         IIC_Start();
  265.         if(IIC_Send_Byte(RX8025_ADDR_WRITE)==1)
  266.         {
  267.                 IIC_Stop();
  268.                 return;
  269.         }
  270.         if(IIC_Send_Byte(addr)==1)
  271.         {
  272.                 IIC_Stop();
  273.                 return;
  274.         }
  275.         IIC_Start();
  276.         if(IIC_Send_Byte(RX8025_ADDR_READ)==1)
  277.         {
  278.                 IIC_Stop();
  279.                 return;
  280.         }
  281.         for(i=0;i<len-1;i++)
  282.         {
  283.                 pData = IIC_Read_Byte(1);
  284. //                IIC_ACK();
  285.         }
  286.         pData = IIC_Read_Byte(0);
  287. //        IIC_NAck();
  288.         IIC_Stop();
  289. }
  290. /***********************************************************************************************
  291. * Function                : BSP_RX8025Write
  292. * Description        : 向时钟芯片写数据
  293. * Input                        :
  294. * Output                :
  295. * Note(s)                :
  296. * Contributor        : 081218        andydriver
  297. ***********************************************************************************************/
  298. void BSP_RX8025Write(u8 *pData,u8 len)
  299. {
  300.         RX8025Write((RX8025_ADDR_SECONDS&RX8025_WRITE_MODE),pData,len);
  301. }
  302. /***********************************************************************************************
  303. * Function                : BSP_RX8025Read
  304. * Description        : 从时钟芯片读取数据
  305. * Input                        :
  306. * Output                :
  307. * Note(s)                :
  308. * Contributor        : 081218        andydriver
  309. ***********************************************************************************************/
  310. void BSP_RX8025Read(u8 *pData,u8 len)
  311. {
  312.         RX8025Read((RX8025_ADDR_SECONDS&RX8025_READ_MODE),pData,len);
  313. }
  314. /***********************************************************************************************
  315. * Function                : BSP_RX8025ControlINTA
  316. * Description        : 控制芯片的INTA脚状态
  317. * Input                        : state:状态(_BSPRX8025_INTAOUT)
  318.                                         BSPRX8025_INTAOUT_HIZ:高阻
  319.                                         BSPRX8025_INTAOUT_LOW:输出低
  320.                                         BSPRX8025_INTAOUT_2HZ:输出2Hz(50%)的脉冲
  321.                                         BSPRX8025_INTAOUT_1HZ:输出1Hz(50%)的脉冲
  322.                                         BSPRX8025_INTAOUT_SEC:每秒的第0秒翻转?还是脉冲?
  323.                                         BSPRX8025_INTAOUT_MIN:每分的第0秒翻转?还是脉冲?
  324.                                         BSPRX8025_INTAOUT_HOUR:每时的第0秒翻转?还是脉冲?
  325.                                         BSPRX8025_INTAOUT_MONTH:每月的第0秒翻转?还是脉冲?
  326. * Output                :
  327. * Note(s)                :
  328. * Contributor        : 081218        andydriver
  329. ***********************************************************************************************/
  330. //void BSP_RX8025ControlINTA(_BSPRX8025_INTAOUT state)
  331. //{
  332. //        _RX8025_REG_CONTROL1 data;
  333. //        
  334. //        RX8025Read((RX8025_ADDR_CONTROL1&RX8025_READ_MODE),(u8 *)(&data),1);
  335. //        data.bits.CT = state;                                                        // INTA输出1Hz方波
  336. //        RX8025Write((RX8025_ADDR_CONTROL1&RX8025_WRITE_MODE),(u8 *)(&data),1);
  337. //}
  338. /***********************************************************************************************
  339. * Function                : BSP_RX8025Init
  340. * Description        : RX8025初始化
  341. * Input                        :
  342. * Output                :
  343. * Note(s)                :
  344. * Contributor        : 081210        andydriver
  345. ***********************************************************************************************/
  346. void BSP_RX8025Init(void)
  347. {
  348.     u8 buf[16];         
  349.         u8 i;
  350. //        iic_init();
  351.         RX8025Read((RX8025_ADDR_SECONDS&RX8025_READ_MODE),buf,8);
  352.         buf[0] = 0x20;
  353.         RX8025Write((RX8025_ADDR_CONTROL1&RX8025_WRITE_MODE),buf,1);        //24小时制
  354.         RX8025Read((RX8025_ADDR_SECONDS&RX8025_READ_MODE),buf,16);
  355.         i++;
  356. }
复制代码


您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-9-17 04:38

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表