myiic.c 2.8 KB

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