中级会员
 
- 积分
- 497
- 金钱
- 497
- 注册时间
- 2016-9-5
- 在线时间
- 79 小时
|
5金钱
本帖最后由 猴子 于 2025-5-7 17:54 编辑
最近在调试SMBus时序,测试的时候发现跑一段时间后软件会死机,检查后发现在接收最后一个字节的时候IIC的DR寄存器收到数了,但是RxNE状态标志没有置位,导致卡在那个判断中了,现在加了超时计数,还在测试 但我不理解的是为什么会DR有数但是标志没置位,与固件库有关还是STM32F1芯片的缺陷?又或者是我理解错了?
- u16 readResult = 0;
- u32 count = DF_I2C_WAITCHECK_TIME;
- u8 PECData[6] = {0};
- u8 idx = 0;
- u8 NumByteToRead = 3;
- u8 PECResult = 0; //校验码值
- pObj->checkFlg = 0;
- PECData[0] = pObj->deviceAddress_Write;
- PECData[1] = command;
- PECData[2] = pObj->deviceAddress_Read;
- //I2C_ClearFlag(pObj->I2Cx, I2C_FLAG_AF);
- while(I2C_GetFlagStatus(pObj->I2Cx, I2C_FLAG_BUSY))
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }
- count = DF_I2C_WAITCHECK_TIME;
- //产生起始信号
- I2C_GenerateSTART(pObj->I2Cx,ENABLE);
- while(!I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) // 测试和清除EV5
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }
- /*while (!I2C_GetFlagStatus(pObj->I2Cx,I2C_FLAG_SB))
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }*/
- //发送从机地址,写
- count = DF_I2C_WAITCHECK_TIME;
- I2C_Send7bitAddress(pObj->I2Cx, pObj->deviceAddress, I2C_Direction_Transmitter);
- while(!I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) // 测试和清除EV6
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }
- //发送命令数据
- count = DF_I2C_WAITCHECK_TIME;
- I2C_SendData(pObj->I2Cx, command);
- //while(!I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) // 测试和清除EV8
- /*{
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }*/
- while ((!I2C_GetFlagStatus(pObj->I2Cx,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(pObj->I2Cx,I2C_FLAG_BTF)))
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }
- //产生起始信号
- count = DF_I2C_WAITCHECK_TIME;
- I2C_GenerateSTART(pObj->I2Cx,ENABLE);
- while(!I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) // 测试和清除EV5
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }
- /*while (!I2C_GetFlagStatus(pObj->I2Cx,I2C_FLAG_SB))
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }*/
-
- //发送从机地址,读
- count = DF_I2C_WAITCHECK_TIME;
- I2C_Send7bitAddress(pObj->I2Cx, pObj->deviceAddress, I2C_Direction_Receiver);
- while(!I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) // 测试和清除EV6
- {
- if(0 == (count--))
- {
- BSP_bq40z50_SmBusTimeOutHandle(pObj);
- return 0;
- }
- }
-
- I2C_AcknowledgeConfig(pObj->I2Cx, ENABLE); //SMBus除了接收最后一个字节,其余字节接收后主机需要接收方需要发出应答
- idx = 3;
- count = DF_I2C_WAITCHECK_TIME;
- if(NumByteToRead > 2) //参考手册中接收方时序方式2,按字节数N>2,N=2,N=1分别处理
- {
- while(NumByteToRead)
- {
- if(NumByteToRead <= 3) //剩余3个字节接收时需要特殊处理
- {
- if(NumByteToRead > 1)
- {
- if(I2C_GetFlagStatus(pObj->I2Cx,I2C_FLAG_BTF)) //移位寄存器和数据寄存器满了,BTF位被置1
- {
- I2C_AcknowledgeConfig(pObj->I2Cx, DISABLE); //清除ACK位
- PECData[idx] = I2C_ReceiveData(pObj->I2Cx); //读取第N-2个字节,移位寄存器接收第N个字节
- idx++;
- NumByteToRead--;
- I2C_GenerateSTOP(pObj->I2Cx, ENABLE);
- PECData[idx] = I2C_ReceiveData(pObj->I2Cx); //读取第N-1个字节,
- idx++;
- NumByteToRead--;
- }
- }
- else if(1 == NumByteToRead)
- {
- count--;
- if(I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) || (0 == count)) // 测试和清除EV7
- {
- PECData[idx] = I2C_ReceiveData(pObj->I2Cx); //读取第N个字节
- idx++;
- NumByteToRead--;
- }
- }
- }
- else
- {
- if(I2C_CheckEvent(pObj->I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)) // 测试和清除EV7
- {
- PECData[idx] = I2C_ReceiveData(pObj->I2Cx); //读取一个字节
- idx++; //下一个读取的数据
- NumByteToRead--; //递减字节计数
- }
- }
- }
- }
- else if(2 == NumByteToRead)
- {
-
- }
- else if(1 == NumByteToRead)
- {
- }
- else
- {
- }
-
-
- PECResult = calculate_crc8(PECData,(sizeof(PECData) - 1));
- readResult = PECData[4];
- readResult = (readResult << 8) | PECData[3];
- if(PECData[5] != PECResult) //校验码错误
- {
- pObj->checkFlg = 1;
- }
- return readResult;
复制代码
|
|