IIC.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #include "IIC.h"
  2. #define IIC_SDA_PORT GPIOA
  3. #define IIC_SDA_CLK (RCC_APB2Periph_GPIOA)
  4. #define IIC_SDA_PIN GPIO_Pin_7
  5. #define IIC_SCL_PORT GPIOB
  6. #define IIC_SCL_CLK (RCC_APB2Periph_GPIOB)
  7. #define IIC_SCL_PIN GPIO_Pin_0
  8. #define IIC_SCL_OUT_1 IIC_SCL_PORT->BSRR = (uint32_t)IIC_SCL_PIN // 置1
  9. #define IIC_SCL_OUT_0 IIC_SCL_PORT->BRR = (uint32_t)IIC_SCL_PIN
  10. #define IIC_SDA_OUT_1 IIC_SDA_PORT->BSRR = (uint32_t)IIC_SDA_PIN // 置1
  11. #define IIC_SDA_OUT_0 IIC_SDA_PORT->BRR = (uint32_t)IIC_SDA_PIN
  12. #define IIC_SDA_IN() ((IIC_SDA_PORT->IDR & IIC_SDA_PIN) != 0)
  13. /**
  14. * @brief IIC延时
  15. * @param None
  16. * @retval None
  17. */
  18. static void IIC_Delay(void)
  19. {
  20. uint16_t i;
  21. /* 
  22. 下面的时间是通过逻辑分析仪测试得到的。
  23. 工作条件:CPU主频72MHz ,MDK编译环境,1级优化
  24. 循环次数为10时,SCL频率 = 205KHz
  25. 循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us
  26. 循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us
  27. */
  28. for (i = 0; i < 400; i++);
  29. }
  30. /**
  31. * @brief SDA输出方向配置
  32. * @param None
  33. * @retval None
  34. */
  35. void Set_IIC_SDA_OUT(void)
  36. {
  37. GPIO_InitTypeDef GPIO_InitStructure;
  38. RCC_APB2PeriphClockCmd(IIC_SDA_CLK, ENABLE);
  39. GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
  40. GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  41. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
  42. GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
  43. }
  44. /**
  45. * @brief SDA输入方向配置
  46. * @param None
  47. * @retval None
  48. */
  49. void Set_IIC_SDA_IN(void)
  50. {
  51. GPIO_InitTypeDef GPIO_InitStructure;
  52. RCC_APB2PeriphClockCmd(IIC_SDA_CLK, ENABLE);
  53. GPIO_InitStructure.GPIO_Pin=IIC_SDA_PIN;
  54. GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  55. GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
  56. }
  57. /**
  58. * @brief 模拟IIC初始化
  59. * @param None
  60. * @retval None
  61. */
  62. void IIC_init()
  63. {
  64. GPIO_InitTypeDef GPIO_InitStructure;
  65. RCC_APB2PeriphClockCmd(IIC_SDA_CLK | IIC_SCL_CLK, ENABLE);
  66. GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
  67. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  68. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  69. GPIO_Init(IIC_SDA_PORT, &GPIO_InitStructure);
  70. GPIO_InitStructure.GPIO_Pin = IIC_SCL_PIN;
  71. GPIO_Init(IIC_SCL_PORT, &GPIO_InitStructure);
  72. IIC_stop();
  73. }
  74. /**
  75. * @brief 模拟IIC起始信号
  76. * @param None
  77. * @retval None
  78. */
  79. void IIC_start()
  80. {
  81. Set_IIC_SDA_OUT();
  82. IIC_SCL_OUT_1;
  83. IIC_SDA_OUT_1;
  84. IIC_Delay();
  85. IIC_SDA_OUT_0;
  86. IIC_Delay();
  87. IIC_SCL_OUT_0;
  88. IIC_Delay();
  89. }
  90. /**
  91. * @brief 模拟IIC停止信号
  92. * @param None
  93. * @retval None
  94. */
  95. void IIC_stop()
  96. {
  97. Set_IIC_SDA_OUT();
  98. IIC_SCL_OUT_1;
  99. IIC_SDA_OUT_0;
  100. IIC_Delay();
  101. IIC_SDA_OUT_1;
  102. }
  103. /**
  104. * @brief 模拟IIC主机应答
  105. * @param None
  106. * @retval None
  107. */
  108. void IIC_ack()
  109. {
  110. Set_IIC_SDA_OUT();
  111. IIC_SDA_OUT_0;
  112. IIC_Delay();
  113. IIC_SCL_OUT_1;
  114. IIC_Delay();
  115. IIC_SCL_OUT_0;
  116. IIC_Delay();
  117. IIC_SDA_OUT_1;
  118. }
  119. /**
  120. * @brief 模拟IIC主机不应答
  121. * @param None
  122. * @retval None
  123. */
  124. void IIC_noack()
  125. {
  126. Set_IIC_SDA_OUT();
  127. IIC_SDA_OUT_1;
  128. IIC_Delay();
  129. IIC_SCL_OUT_1;
  130. IIC_Delay();
  131. IIC_SCL_OUT_0;
  132. IIC_Delay();
  133. }
  134. /**
  135. * @brief 模拟IIC等待从机应答
  136. * @param None
  137. * @retval 1: 接收应答失败 0: 接收应答成功
  138. */
  139. uint8_t IIC_wait_ack()
  140. {
  141. uint8_t rec = 0;
  142. Set_IIC_SDA_OUT();
  143. IIC_SDA_OUT_1;
  144. IIC_Delay();
  145. Set_IIC_SDA_IN();
  146. IIC_SCL_OUT_1;
  147. IIC_Delay();
  148. rec = IIC_SDA_IN();
  149. IIC_SCL_OUT_0;
  150. IIC_Delay();
  151. return rec;
  152. }
  153. /**
  154. * @brief 模拟IIC发送一个字节
  155. * @param None
  156. * @retval None
  157. */
  158. void IIC_send_byte(uint8_t txd)
  159. {
  160. uint8_t i=0;
  161. Set_IIC_SDA_OUT();
  162. for(i=0;i<8;i++)
  163. {
  164. if(txd&0x80) IIC_SDA_OUT_1;
  165. else IIC_SDA_OUT_0;
  166. IIC_Delay();
  167. IIC_SCL_OUT_1;
  168. IIC_Delay(); // 发送数据
  169. IIC_SCL_OUT_0;
  170. if(i == 7) IIC_SDA_OUT_1; // 最后一位数据发送完要释放SDA总线
  171. txd <<= 1;
  172. IIC_Delay();
  173. }
  174. }
  175. /**
  176. * @brief 模拟IIC读取一个字节
  177. * @param ack: 0,读完不产生应答 1,读完产生应答
  178. * @retval 返回读取到的字节
  179. */
  180. uint8_t IIC_read_byte(uint8_t ack)
  181. {
  182. uint8_t i,receive=0;
  183. Set_IIC_SDA_IN();
  184. for(i=0;i<8;i++)
  185. {
  186. receive <<= 1;
  187. IIC_SCL_OUT_1;
  188. IIC_Delay();
  189. if(IIC_SDA_IN()) receive++; // 连续读取八位
  190. IIC_SCL_OUT_0;
  191. IIC_Delay();
  192. }
  193. if(!ack) IIC_noack();
  194. else IIC_ack();
  195. return receive; // 返回读取到的字节
  196. }