参考代码

.C文件

模拟I2C驱动代码,只需要配置好模拟IO的读写即可。

  1. /*******************************************************************************
  2. **函数名称:void I2C_Init()
  3. **功能描述:初始化I2C1接口
  4. **入口参数:
  5. **输出:无
  6. *******************************************************************************/
  7. void IIC_Init()
  8. {
  9. GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_Out_OD_HiZ_Slow); //SDA
  10. GPIO_Init(GPIOC , GPIO_Pin_1 , GPIO_Mode_Out_OD_HiZ_Slow); //SCL
  11. IIC_SCL_HIGH();
  12. IIC_SDA_HIGH();
  13. }
  14. //产生IIC起始信号
  15. void IIC_Start(void)
  16. {
  17. SDA_OUT(); //sda线输出
  18. /* IIC_SCL_LOW();
  19. delay_us(1); */
  20. IIC_SDA_HIGH();
  21. delay_us(1);
  22. IIC_SCL_HIGH();
  23. delay_us(4);//建立时间是I2C_SDA保持时间>4.7us
  24. IIC_SDA_LOW();//START:when CLK is high,DATA change form high to low
  25. delay_us(4);//保持时间是>4us
  26. IIC_SCL_LOW();//钳住I2C总线,准备发送或接收数据
  27. // delay_us(5);
  28. }
  29. //产生IIC停止信号
  30. void IIC_Stop(void)
  31. {
  32. SDA_OUT();//sda线输出
  33. IIC_SCL_LOW();
  34. delay_us(1);
  35. IIC_SDA_LOW();//STOP:when CLK is high DATA change form low to high
  36. // IIC_SCL_HIGH();
  37. delay_us(4);//建立时间大于4.7us
  38. IIC_SCL_HIGH();
  39. delay_us(1);
  40. IIC_SDA_HIGH();//发送I2C总线结束信号
  41. delay_us(4);
  42. }
  43. //等待应答信号到来
  44. //返回值:1,接收应答失败
  45. // 0,接收应答成功
  46. u8 IIC_Wait_Ack(void)
  47. {
  48. u8 ucErrTime=0;
  49. SDA_IN(); //SDA设置为输入
  50. IIC_SDA_HIGH();delay_us(1);
  51. IIC_SCL_HIGH();delay_us(1);
  52. while(READ_SDA)
  53. {
  54. ucErrTime++;
  55. if(ucErrTime>250)
  56. {
  57. IIC_Stop();
  58. printf("device no ack\r\n");
  59. return 1;
  60. }
  61. }
  62. IIC_SCL_LOW();//时钟输出0
  63. // delay_us(5);
  64. return 0;
  65. }
  66. //产生ACK应答
  67. void IIC_Ack(void)
  68. {
  69. IIC_SCL_LOW();
  70. SDA_OUT();
  71. IIC_SDA_LOW();
  72. delay_us(5);
  73. IIC_SCL_HIGH();
  74. delay_us(5);
  75. IIC_SCL_LOW();
  76. // delay_us(5);
  77. }
  78. //不产生ACK应答
  79. void IIC_NAck(void)
  80. {
  81. IIC_SCL_LOW();
  82. SDA_OUT();
  83. IIC_SDA_HIGH();
  84. delay_us(5);
  85. IIC_SCL_HIGH();
  86. delay_us(5);
  87. IIC_SCL_LOW();
  88. // delay_us(5);
  89. }
  90. //IIC发送一个字节
  91. //返回从机有无应答
  92. //1,有应答
  93. //0,无应答
  94. void IIC_Send_Byte(u8 txd)
  95. {
  96. u8 t;
  97. SDA_OUT();
  98. IIC_SCL_LOW(); //拉低时钟开始数据传输
  99. for (t = 0; t < 8; t++)
  100. {
  101. // IIC_SDA = ((txd & 0x80) >> 7);
  102. if (txd & 0x80)
  103. {
  104. IIC_SDA_HIGH();
  105. }
  106. else
  107. {
  108. IIC_SDA_LOW();
  109. }
  110. txd <<= 1;
  111. delay_us(2); //对TEA5767这三个延时都是必须的
  112. IIC_SCL_HIGH();
  113. delay_us(2);
  114. IIC_SCL_LOW();
  115. delay_us(2);
  116. }
  117. }
  118. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  119. u8 IIC_Read_Byte(unsigned char ack)
  120. {
  121. unsigned char i, receive = 0;
  122. // IIC_SCL_LOW();
  123. // IIC_SDA_LOW();
  124. SDA_IN(); //SDA设置为输入
  125. for (i = 0; i < 8; i++)
  126. {
  127. // IIC_SDA_LOW();
  128. IIC_SCL_LOW();
  129. delay_us(3);
  130. IIC_SCL_HIGH();
  131. // delay_us(2);
  132. receive <<= 1;
  133. if (READ_SDA)
  134. receive|= 0x01;
  135. delay_us(3);
  136. }
  137. if (!ack)
  138. IIC_NAck(); //发送nACK
  139. else
  140. IIC_Ack(); //发送ACK
  141. return receive;
  142. }

.H文件

仅包含部分代码,函数接口可视情况暴露出来即可。

  1. #ifndef ___AT24C02_H___
  2. #define ___AT24C02_H___
  3. #include "stm8l15x.h"
  4. #define SLAVE_ADDRESS 0x90
  5. #define IRBUFSIZE 500
  6. //字节转换--1字节x2转2字节
  7. #define BUILD_UINT16(loByte, hiByte) \
  8. ((u16)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))
  9. //IO方向设置-------------因STM8单片机的I2C引脚为OD设计,同时故不需要设置CR1寄存器(详见数据手册及参考手册)
  10. #define SDA_IN() GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_In_FL_No_IT/* GPIO_Mode_Out_OD_HiZ_Slow */);
  11. #define SDA_OUT() GPIO_Init(GPIOC , GPIO_Pin_0 , GPIO_Mode_Out_OD_HiZ_Slow);
  12. // #define SDA_OUT() {GPIOC->DDR |= GPIO_Pin_0;GPIOC->CR1 &= (uint8_t)(~(GPIO_Pin_0)); \
  13. // GPIOC->CR2 &= (uint8_t)(~(GPIO_Pin_0));} /* Set OD Output */
  14. //IO操作函数{GPIOC->DDR &= (uint8_t)(~(GPIO_Pin_0));} /* Set Floating input No Interrupt */
  15. #define IIC_SCL_HIGH() GPIO_SetBits(GPIOC, GPIO_Pin_1);
  16. #define IIC_SCL_LOW() GPIO_ResetBits(GPIOC, GPIO_Pin_1);
  17. #define IIC_SDA_HIGH() GPIO_SetBits(GPIOC, GPIO_Pin_0);
  18. #define IIC_SDA_LOW() GPIO_ResetBits(GPIOC, GPIO_Pin_0);
  19. // STM8系列单片机可在输入或输出模式下读取IO状态------不需要改变IO的模式可读取
  20. #define READ_SDA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_0)