打印
[其他ST产品]

stm32硬件I2C调试

[复制链接]
183|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lvuu|  楼主 | 2023-8-20 15:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

I2C初始化


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



使用特权

评论回复
沙发
lvuu|  楼主 | 2023-8-20 15:27 | 只看该作者
I2C写寄存器
        //发送开始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
        //发送从设备地址-写
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    //发送寄存器地址
    I2C_SendData(I2C1,D_MenAddress);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
    //重新发送开始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    //发送从设备地址-读
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    //循环读取数据
    while(bufferSize)
    {
        bufferSize--;
        if(bufferSize == 0)
        {
                //关闭自动应答
            I2C_AcknowledgeConfig(I2C1, DISABLE);
        }
        
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
        *pBuffer = I2C_ReceiveData(I2C1);
        pBuffer++;
    }
        //发送停止信号
    I2C_GenerateSTOP(I2C1,ENABLE);
    //重新打开自动应答
    I2C_AcknowledgeConfig(I2C1, ENABLE);

使用特权

评论回复
板凳
lvuu|  楼主 | 2023-8-20 15:27 | 只看该作者
I2C读寄存器
        //发送开始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
        //发送从设备地址-写
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    //发送寄存器地址
    I2C_SendData(I2C1,D_MenAddress);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
    //重新发送开始信号
    I2C_GenerateSTART(I2C1,ENABLE);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
    //发送从设备地址-读
    I2C_Send7bitAddress(I2C1,DevAddress,I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    //循环读取数据
    while(bufferSize)
    {
        bufferSize--;
        if(bufferSize == 0)
        {
                //关闭自动应答
            I2C_AcknowledgeConfig(I2C1, DISABLE);
        }
        
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
        *pBuffer = I2C_ReceiveData(I2C1);
        pBuffer++;
    }
        //发送停止信号
    I2C_GenerateSTOP(I2C1,ENABLE);
    //重新打开自动应答
    I2C_AcknowledgeConfig(I2C1, ENABLE);

使用特权

评论回复
地板
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者

需要注意6点

使用特权

评论回复
5
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者
GPIO必须设置为开漏复用模式

使用特权

评论回复
6
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者
测试时一直停在busy状态时检查是否开启I2C时钟,通信器件之间是否可靠连接,I2C是否有被强制拉低

使用特权

评论回复
7
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者
读写寄存器时设置从机地址时I2C_Send7bitAddress最后一个参数区分读写

使用特权

评论回复
8
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者
读寄存器之前需对寄存器先进行从机地址和寄存器地址写入

使用特权

评论回复
9
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者
读寄存器最后一个字节时需关闭自动应答,发送停止信号后一定要重新打开

使用特权

评论回复
10
lvuu|  楼主 | 2023-8-20 15:28 | 只看该作者
可以添加一些返回值,如果(I2Cx->SR2 & 1<<1)提示I2C_Busy,进入发送或者接收后可以添加计时,超时返回I2C_Timeout

使用特权

评论回复
11
帛灿灿| | 2024-2-21 07:27 | 只看该作者

不影响线路正常工作

使用特权

评论回复
12
Bblythe| | 2024-2-21 08:30 | 只看该作者

然而它的作用又可以分为阻抗匹配和减少信号边沿的陡峭程度两点

使用特权

评论回复
13
周半梅| | 2024-2-21 10:26 | 只看该作者

变压器副边不对负载供电

使用特权

评论回复
14
Pulitzer| | 2024-2-21 11:29 | 只看该作者

其定义为温度每升高1℃时电阻值发生变化的百分数

使用特权

评论回复
15
童雨竹| | 2024-2-21 13:25 | 只看该作者

最常见的是用它们来创建PCB独立模块,比如Wi-Fi、蓝牙或者核心板模块,

使用特权

评论回复
16
Wordsworth| | 2024-2-21 14:28 | 只看该作者

让电子产品电路免受瞬态雷击浪涌与ESD静电的损害。

使用特权

评论回复
17
Clyde011| | 2024-2-21 15:31 | 只看该作者

固有的ESD钳位二极管。

使用特权

评论回复
18
公羊子丹| | 2024-2-21 16:24 | 只看该作者

在完成测试后,需要分析测试结果并进行评估

使用特权

评论回复
19
万图| | 2024-2-21 17:27 | 只看该作者

不打坏仪器内部

使用特权

评论回复
20
Uriah| | 2024-2-21 18:30 | 只看该作者

具体采用灌封胶的种类的性能参数,主要看对电源模块的灌封用的胶的要求

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

414

帖子

0

粉丝