[其他ST产品] stm32硬件I2C调试

[复制链接]
753|19
 楼主| lvuu 发表于 2023-8-20 15:27 | 显示全部楼层 |阅读模式

基于标准库StdPeriph_Lib_V3.6.0进行硬件I2C主机调试,通过对从机的寄存器进行读写操作,已通过测试

I2C初始化


  1.     GPIO_InitTypeDef GPIO_InitStruct;
  2.     I2C_InitTypeDef I2C_InitStructure;
  3.     //时钟配置
  4.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  5.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
  6.    
  7.     GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  8.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;                                //复用开漏
  9.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;                              //输出速率随意
  10.     GPIO_Init(GPIOB,&GPIO_InitStruct);
  11.    
  12.     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                                  //I2C模式
  13.     I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;                          //占空比
  14.     I2C_InitStructure.I2C_OwnAddress1 = 0;                                      //本机地址,主模式下无意义
  15.     I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                                 //自动应答使能
  16.     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;   //7位地址
  17.     I2C_InitStructure.I2C_ClockSpeed = 400000;                                  //I2C频率100K~400K
  18.     I2C_Init(I2C1,&I2C_InitStructure);
  19.     I2C_Cmd(I2C1,ENABLE);



 楼主| lvuu 发表于 2023-8-20 15:27 | 显示全部楼层
I2C写寄存器
  1.         //发送开始信号
  2.     I2C_GenerateSTART(I2C1,ENABLE);
  3.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  4.         //发送从设备地址-写
  5.     I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Transmitter);
  6.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  7.     //发送寄存器地址
  8.     I2C_SendData(I2C1,D_MenAddress);
  9.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  10.     //重新发送开始信号
  11.     I2C_GenerateSTART(I2C1,ENABLE);
  12.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  13.     //发送从设备地址-读
  14.     I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Receiver);
  15.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  16.     //循环读取数据
  17.     while(bufferSize)
  18.     {
  19.         bufferSize--;
  20.         if(bufferSize == 0)
  21.         {
  22.                 //关闭自动应答
  23.             I2C_AcknowledgeConfig(I2C1, DISABLE);
  24.         }
  25.         
  26.         while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
  27.         *pBuffer = I2C_ReceiveData(I2C1);
  28.         pBuffer++;
  29.     }
  30.         //发送停止信号
  31.     I2C_GenerateSTOP(I2C1,ENABLE);
  32.     //重新打开自动应答
  33.     I2C_AcknowledgeConfig(I2C1, ENABLE);
 楼主| lvuu 发表于 2023-8-20 15:27 | 显示全部楼层
I2C读寄存器
  1.         //发送开始信号
  2.     I2C_GenerateSTART(I2C1,ENABLE);
  3.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  4.         //发送从设备地址-写
  5.     I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Transmitter);
  6.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
  7.     //发送寄存器地址
  8.     I2C_SendData(I2C1,D_MenAddress);
  9.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
  10.     //重新发送开始信号
  11.     I2C_GenerateSTART(I2C1,ENABLE);
  12.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
  13.     //发送从设备地址-读
  14.     I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Receiver);
  15.     while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
  16.     //循环读取数据
  17.     while(bufferSize)
  18.     {
  19.         bufferSize--;
  20.         if(bufferSize == 0)
  21.         {
  22.                 //关闭自动应答
  23.             I2C_AcknowledgeConfig(I2C1, DISABLE);
  24.         }
  25.         
  26.         while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
  27.         *pBuffer = I2C_ReceiveData(I2C1);
  28.         pBuffer++;
  29.     }
  30.         //发送停止信号
  31.     I2C_GenerateSTOP(I2C1,ENABLE);
  32.     //重新打开自动应答
  33.     I2C_AcknowledgeConfig(I2C1, ENABLE);
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层

需要注意6点
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层
GPIO必须设置为开漏复用模式
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层
测试时一直停在busy状态时检查是否开启I2C时钟,通信器件之间是否可靠连接,I2C是否有被强制拉低
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层
读写寄存器时设置从机地址时I2C_Send7bitAddress最后一个参数区分读写
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层
读寄存器之前需对寄存器先进行从机地址和寄存器地址写入
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层
读寄存器最后一个字节时需关闭自动应答,发送停止信号后一定要重新打开
 楼主| lvuu 发表于 2023-8-20 15:28 | 显示全部楼层
可以添加一些返回值,如果(I2Cx->SR2 & 1<<1)提示I2C_Busy,进入发送或者接收后可以添加计时,超时返回I2C_Timeout
帛灿灿 发表于 2024-2-21 07:27 | 显示全部楼层

不影响线路正常工作
Bblythe 发表于 2024-2-21 08:30 | 显示全部楼层

然而它的作用又可以分为阻抗匹配和减少信号边沿的陡峭程度两点
周半梅 发表于 2024-2-21 10:26 | 显示全部楼层

变压器副边不对负载供电
Pulitzer 发表于 2024-2-21 11:29 | 显示全部楼层

其定义为温度每升高1℃时电阻值发生变化的百分数
童雨竹 发表于 2024-2-21 13:25 | 显示全部楼层

最常见的是用它们来创建PCB独立模块,比如Wi-Fi、蓝牙或者核心板模块,
Wordsworth 发表于 2024-2-21 14:28 | 显示全部楼层

让电子产品电路免受瞬态雷击浪涌与ESD静电的损害。
Clyde011 发表于 2024-2-21 15:31 | 显示全部楼层

固有的ESD钳位二极管。
公羊子丹 发表于 2024-2-21 16:24 | 显示全部楼层

在完成测试后,需要分析测试结果并进行评估
万图 发表于 2024-2-21 17:27 | 显示全部楼层

不打坏仪器内部
Uriah 发表于 2024-2-21 18:30 | 显示全部楼层

具体采用灌封胶的种类的性能参数,主要看对电源模块的灌封用的胶的要求
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

651

帖子

0

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