新手上路
- 积分
- 34
- 金钱
- 34
- 注册时间
- 2019-7-17
- 在线时间
- 7 小时
|
在IMX6U裸机实验中的bsp_iic.c有一个repeated_start函数- /* repeated start信号 */
- unsigned char i2c_master_repeated_start(I2C_Type *base, unsigned char address, enum i2c_direction direction)
- {
- /* I2C是否忙或工作在从机模式下 */
- if(base->I2SR & (1 << 5) && (((base->I2CR) & (1 << 5)) == 0))
- return 1;
复制代码
按照左老师视频中讲的,在发送repeat start信号之前,要检查“I2C是否忙或工作在从机模式下”,从字面上理解,首先判断条件中的“&&”应当改为“||”。
于是笔者自作聪明的改了代码,发现程序卡死了,在读数据的时候,卡死在如下所示位置。
- if(xfer->direction == kI2C_Read) /* 读取数据 */
- {
- base->I2SR &= ~(1 << 1); /* 清除中断挂起位 */
- i2c_master_repeated_start(base, xfer->slaveAddress, kI2C_Read); /* 发送重复开始信号和从机地址 */
- while(!(base->I2SR & (1 << 1))){};/* 等待传输完成 */ /*********************************************程序卡死位置**********************************************/
- /* 检查是否有错误发生 */
- ret = i2c_check_and_clear_error(base, base->I2SR);
- if(ret)
- {
- ret = I2C_STATUS_ADDRNAK;
复制代码
于是回到repeat start函数中,找到判断条件,发现有两个,一个是检查IIC总线空闲位,I2SR寄存器的bit5。另一个是检查IIC控制器的主从模式,I2CR寄存器的bit5。
拆分两个条件,发现repeat start函数return 1的主要原因是IIC总线空闲位一直为1,查看参考手册的I2SR寄存器可以看到
I2C bus busy bit. Indicates the status of the bus.
NOTE: When I2C is enabled (I2C_I2CR[IEN] = 1), it continuously polls the bus data (SDA) and clock
(SCL) signals to determine a Start or Stop condition.
0 Bus is idle. If a Stop signal is detected, IBB is cleared.
1 Bus is busy. When Start is detected, IBB is set. |
I2SR寄存器的bit 5只有在控制器检测到stop信号后才会被控制器自动清零,因此检测该位时一直为1。
所以在repeat start函数的开头不应该检测IIC总线忙状态位,只需检测是否工作在从机模式下即可。
|
|