[STM32F1] STM32软件IIC 程序 方便移植

[复制链接]
323|0
 楼主| febgxu 发表于 2023-5-25 16:47 | 显示全部楼层 |阅读模式
  1. #include "myiic.h"
  2. #include "delay.h"

  3. //已删除所有延时 1 - 2us延时        若IIC通信出错或许是没有延时问题
  4. //或者时钟源问题

  5. void IIC_Init()
  6. {
  7.         GPIO_InitTypeDef  GPIO_InitStructure;
  8. /****************************IIC_SDA初始化***********************************************/
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SDA_PORT, ENABLE);        //使能SDA连接端口时钟   /
  10.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SDA;                                                                                //SDA端口配置                                           /
  11.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                          //推挽输出                                                         /
  12.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                        //IO口速度为50MHz                                 /
  13.         GPIO_Init(GPIO_SDA_PORT, &GPIO_InitStructure);                                                                 //根据设定参数初始化SDA /
  14. /****************************IIC_SCL初始化***********************************************/
  15.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_IIC_SCL_PORT, ENABLE);        //使能SCL连接端口时钟          /
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SCL;                                                                                //SCL端口配置                                                 /
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                          //推挽输出                                                         /
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                                        //IO口速度为50MHz                                 /
  19.         GPIO_Init(GPIO_SCL_PORT, &GPIO_InitStructure);                                                                 //根据设定参数初始化SCL /
  20. /****************************************************************************************/
  21. }


  22. /**********************************************/
  23. //                                                IIC Start
  24. //开始信号:在SCL为高电平时,SDA由高电平向低电平跳变,开始传输数据。
  25. /**********************************************/
  26. void IIC_Start()
  27. {
  28.         SDA_OUT();
  29.         IIC_SCL=1;
  30.         IIC_SDA=1;
  31.         delay_us(2);
  32.         IIC_SDA=0;
  33.         delay_us(2);
  34.         IIC_SCL=0;
  35. }


  36. /**********************************************/
  37. //                                                IIC Stop
  38. //结束信号:在SCL为高电平时,SDA由低电平向高电平跳变,结束传输数据。
  39. /**********************************************/
  40. void IIC_Stop()
  41. {
  42.         SDA_OUT();
  43.         IIC_SCL=1;
  44.         IIC_SDA=0;
  45.         delay_us(2);
  46.         IIC_SDA=1;
  47.         delay_us(2);

  48. }

  49. /**********************************************/
  50. //                                                IIC主机产生ACK应答信号
  51. /**********************************************/
  52. void IIC_ACK(void)
  53. {
  54.         SDA_OUT();
  55.         IIC_SCL=0;
  56.         IIC_SDA=0;
  57.         delay_us(2);
  58.         IIC_SCL=1;
  59.         delay_us(2);
  60.         IIC_SCL=0;
  61. }

  62. /**********************************************/
  63. //                                                IIC主机不产生ACK应答信号
  64. /**********************************************/
  65. void IIC_NACK(void)

  66. {
  67.         SDA_OUT();
  68.         IIC_SCL=0;
  69.         IIC_SDA=1;
  70.         delay_us(2);
  71.         IIC_SCL=1;
  72.         delay_us(2);
  73.         IIC_SCL=0;
  74. }


  75. /**********************************************/
  76. //                                                IIC Wait Ack
  77. //等待应答信号到来
  78. //返回值        1,接收应答失败
  79. //        0,接收应答成功
  80. /**********************************************/
  81. unsigned char IIC_Wait_Ack(void)
  82. {
  83.         u8 ucErrTime=0;
  84.         SDA_IN();      //SDA设置为输入  
  85.         IIC_SDA=1;
  86.         IIC_SCL=1;
  87.         delay_us(2);
  88.         while(READ_SDA)
  89.         {
  90.                 ucErrTime++;      
  91.                 if(ucErrTime>250)
  92.                         {
  93.                                 IIC_Stop();
  94.                                 return 1;
  95.                         }
  96.         }
  97.         IIC_SCL=0;//时钟输出0           
  98.         return 0;  
  99. }

  100. /**********************************************
  101. //                                                 IIC Write byte
  102. //IIC写一个字节         
  103. **********************************************/
  104. void IIC_Write_Byte(unsigned char data)
  105. {
  106.         unsigned char i;   
  107.         SDA_OUT();            
  108.         IIC_SCL=0;//拉低时钟开始数据传输
  109.         for(i=0;i<8;i++)
  110.         {              
  111.     IIC_SDA=(data&0x80)>>7;
  112.     data=data<<1;           
  113. //                delay_us(2);   //对TEA5767芯片这三个延时都是必须的
  114.                 IIC_SCL=1;
  115. //        delay_us(2);
  116.                 IIC_SCL=0;      
  117. //        delay_us(2);
  118.         }
  119. }

  120. /**********************************************
  121. // IIC Write Data
  122. **********************************************/
  123. void IIC_Write_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char data)
  124. {
  125.   IIC_Start();
  126.         SDA_OUT();
  127.   IIC_Write_Byte(Device_addr | 0x00);        //器件地址(7位) + 读写位(读1写0)
  128.         IIC_Wait_Ack();      
  129.   IIC_Write_Byte(Reg_addr);                                                //要写入数据的寄存器地址
  130.         IIC_Wait_Ack();      
  131.   IIC_Write_Byte(data);
  132.         IIC_Wait_Ack();      
  133.   IIC_Stop();
  134. }

  135. /**********************************************
  136. //                                                 IIC Read byte
  137. //IIC读一个字节         
  138. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
  139. **********************************************/
  140. unsigned char IIC_Read_Byte(unsigned char Ack_EN)
  141. {
  142.         unsigned char i,receive=0;
  143.         SDA_IN();//SDA设置为输入
  144.         for(i=0;i<8;i++ )
  145.         {
  146.                 IIC_SCL=0;
  147.                 delay_us(2);
  148.                 IIC_SCL=1;
  149.                 receive<<=1;
  150.     if(READ_SDA)receive++;   
  151.                 delay_us(1);
  152.    }                                         
  153.     if (!Ack_EN)
  154.         IIC_NACK();//发送nACK
  155.     else
  156.         IIC_ACK(); //发送ACK   
  157.     return receive;
  158. }


  159. /**********************************************
  160. // IIC Read Data
  161. **********************************************/
  162. unsigned char IIC_Read_Data(unsigned char Device_addr,unsigned char Reg_addr,unsigned char ACK_EN)
  163. {
  164.         unsigned char receive;
  165.         IIC_Start();
  166.   IIC_Write_Byte(Device_addr | 0x00);        //器件地址(7位) + 读写位(写0)
  167.         IIC_Wait_Ack();      
  168.   IIC_Write_Byte(Reg_addr);                                                //要读数据的寄存器地址
  169.         IIC_Wait_Ack();      
  170.   IIC_Start();
  171.         SDA_IN();
  172.   IIC_Write_Byte(Device_addr | 0x01);        //器件地址(7位) + 读写位(读1)
  173.         IIC_Wait_Ack();      
  174.         receive=IIC_Read_Byte(0);
  175.         IIC_Wait_Ack();      
  176.   IIC_Stop();
  177.         return receive;
  178. }


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

本版积分规则

59

主题

5078

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部