|
|
STM32硬件I2c是不是有问题啊,我把AHT30温湿传感器接到PB8、PB9上,用软件模拟就是成功,但是用硬件的就出问题了,写变成读,自己摸索几天也问了豆包,但是都没解决
- #include "delay.h"
- #include "AHT30.h"
- int main(void)
- {
- uint8_t da[2] = {0xaa, 0x00};
- delay_init(); // 延时初始化
- AHT30_I2C_Init(); // I2C初始化
- while(1)
- {
- I2C_WriteBytes(0x70, 0xac, da, 0);
- delay_ms(100);
- }
- }
- void AHT30_I2C_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- I2C_InitTypeDef I2C_InitStructure;
-
- // 1. 使能时钟(GPIO、AFIO、I2C1)
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
-
- // 2. I2C1引脚重映射(PB8=SCL, PB9=SDA)
- GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
-
- // 3. 配置I2C引脚为复用开漏输出
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // I2C必须用开漏输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- // 4. 复位并初始化I2C1外设
- I2C_DeInit(I2C1); // 官方标准复位方式
- I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
- I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
- I2C_InitStructure.I2C_OwnAddress1 = 0x00; // 主机模式无需设置自身地址
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
- I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
- I2C_InitStructure.I2C_ClockSpeed = 400000; // 400KHz高速模式
-
- I2C_Init(I2C1, &I2C_InitStructure);
- I2C_Cmd(I2C1, ENABLE); // 使能I2C1
- }
- // 【写操作】硬件I2C写多个字节(原有代码修复)
- // addr:设备7位地址 reg:寄存器/命令 data:数据缓冲区 len:长度
- // 返回1:成功 0:失败
- u8 I2C_WriteBytes(u8 addr, u8 reg, u8 *data, u8 len)
- {
- u16 timeout = 0xFFFF;
-
- // 等待I2C总线空闲(恢复关键步骤)
- while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) && timeout--);
- if(timeout == 0) return 1;
- // 发送起始信号
- I2C_GenerateSTART(I2C1, ENABLE);
-
- // 等待起始条件发送完成
- timeout = 0xFFFF;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) && timeout--);
- if(timeout == 0) return 2;
-
- // 发送设备写地址(7位地址+写位)
- I2C_Send7bitAddress(I2C1, addr, I2C_Direction_Transmitter);
-
- // 等待地址发送完成并收到应答
- timeout = 0xFFFF;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) && timeout--);
- if(timeout == 0) return 3;
-
- // 发送寄存器/命令字节
- I2C_SendData(I2C1, reg);
- timeout = 0xFFFF;
- // 修复:使用正确的发送完成事件
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
- if(timeout == 0) return 4;
-
- // 发送数据字节
- for(u8 i=0; i<len; i++)
- {
- I2C_SendData(I2C1, data[i]);
- timeout = 0xFFFF;
- while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) && timeout--);
- if(timeout == 0) return 5;
- }
-
- // 发送停止信号
- I2C_GenerateSTOP(I2C1, ENABLE);
- return 6; // 成功
- }
复制代码
|
-
1.png
(22.5 KB, 下载次数: 0)
硬件逻辑分析
-
2.png
(37.86 KB, 下载次数: 0)
软件逻辑分析
|