myiic.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #include "myiic.h"
  2. #include "delay.h"
  3. //////////////////////////////////////////////////////////////////////////////////
  4. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  5. //ALIENTEK STM32F103开发板
  6. //IIC驱动代码
  7. //正点原子@ALIENTEK
  8. //技术论坛:www.openedv.com
  9. //创建日期:2017/5/30
  10. //版本:V1.0
  11. //版权所有,盗版必究。
  12. //Copyright(C) 广州市星翼电子科技有限公司 2014-2024
  13. //All rights reserved
  14. //////////////////////////////////////////////////////////////////////////////////
  15. //IIC初始化
  16. void IIC_Init(void)
  17. {
  18. GPIO_InitTypeDef GPIO_Initure;
  19. __HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟
  20. __HAL_RCC_GPIOC_CLK_ENABLE(); //使能GPIOB时钟
  21. //PB6,7初始化设置
  22. GPIO_Initure.Pin=GPIO_PIN_6|GPIO_PIN_7;
  23. GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
  24. GPIO_Initure.Pull=GPIO_PULLUP; //上拉
  25. GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速
  26. HAL_GPIO_Init(GPIOB,&GPIO_Initure);
  27. GPIO_Initure.Pin=GPIO_PIN_9; //PC9
  28. GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
  29. GPIO_Initure.Pull=GPIO_PULLUP; //上拉
  30. GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //高速
  31. HAL_GPIO_Init(GPIOC,&GPIO_Initure);
  32. IIC_SDA=1;
  33. IIC_SCL=1;
  34. IIC_WP=0;
  35. }
  36. //产生IIC起始信号
  37. void IIC_Start(void)
  38. {
  39. SDA_OUT(); //sda线输出
  40. IIC_SDA=1;
  41. IIC_SCL=1;
  42. delay_us(4);
  43. IIC_SDA=0;//START:when CLK is high,DATA change form high to low
  44. delay_us(4);
  45. IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
  46. }
  47. //产生IIC停止信号
  48. void IIC_Stop(void)
  49. {
  50. SDA_OUT();//sda线输出
  51. IIC_SCL=0;
  52. IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
  53. delay_us(4);
  54. IIC_SCL=1;
  55. IIC_SDA=1;//发送I2C总线结束信号
  56. delay_us(4);
  57. }
  58. //等待应答信号到来
  59. //返回值:1,接收应答失败
  60. // 0,接收应答成功
  61. u8 IIC_Wait_Ack(void)
  62. {
  63. u8 ucErrTime=0;
  64. SDA_IN(); //SDA设置为输入
  65. IIC_SDA=1;delay_us(1);
  66. IIC_SCL=1;delay_us(1);
  67. while(READ_SDA)
  68. {
  69. ucErrTime++;
  70. if(ucErrTime>250)
  71. {
  72. IIC_Stop();
  73. return 1;
  74. }
  75. }
  76. IIC_SCL=0;//时钟输出0
  77. return 0;
  78. }
  79. //产生ACK应答
  80. void IIC_Ack(void)
  81. {
  82. IIC_SCL=0;
  83. SDA_OUT();
  84. IIC_SDA=0;
  85. delay_us(2);
  86. IIC_SCL=1;
  87. delay_us(2);
  88. IIC_SCL=0;
  89. }
  90. //不产生ACK应答
  91. void IIC_NAck(void)
  92. {
  93. IIC_SCL=0;
  94. SDA_OUT();
  95. IIC_SDA=1;
  96. delay_us(2);
  97. IIC_SCL=1;
  98. delay_us(2);
  99. IIC_SCL=0;
  100. }
  101. //IIC发送一个字节
  102. //返回从机有无应答
  103. //1,有应答
  104. //0,无应答
  105. void IIC_Send_Byte(u8 txd)
  106. {
  107. u8 t;
  108. SDA_OUT();
  109. IIC_SCL=0;//拉低时钟开始数据传输
  110. for(t=0;t<8;t++)
  111. {
  112. IIC_SDA=(txd&0x80)>>7;
  113. txd<<=1;
  114. delay_us(2); //对TEA5767这三个延时都是必须的
  115. IIC_SCL=1;
  116. delay_us(2);
  117. IIC_SCL=0;
  118. delay_us(2);
  119. }
  120. }
  121. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  122. u8 IIC_Read_Byte(unsigned char ack)
  123. {
  124. unsigned char i,receive=0;
  125. SDA_IN();//SDA设置为输入
  126. for(i=0;i<8;i++ )
  127. {
  128. IIC_SCL=0;
  129. delay_us(2);
  130. IIC_SCL=1;
  131. receive<<=1;
  132. if(READ_SDA)receive++;
  133. delay_us(1);
  134. }
  135. if (!ack)
  136. IIC_NAck();//发送nACK
  137. else
  138. IIC_Ack(); //发送ACK
  139. return receive;
  140. }