21ic问答首页 - 程序调试没问题 运行就不行
程序调试没问题 运行就不行
en_result_t I2C_TransAddr(M4_I2C_TypeDef* pstcI2Cx, uint8_t u8Addr, en_trans_direction_t enDir, uint32_t u32Timeout)
{
en_result_t enRet;
DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
DDL_ASSERT(IS_VALID_7BIT_ADR(u8Addr));
DDL_ASSERT(IS_VALID_TRANS_DIR(enDir));
enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TEMPTYF, Set, u32Timeout);// TEMPTYE 发送数据空标志位 0:I2C_DTR寄存器满 1:I2C_DTR寄存器空
if(Ok == enRet)
{
/* 发送I2C地址到DTR数据发送寄存器上 u8Addr 0x49 实际发送0x92/0x93 */
I2C_WriteData(pstcI2Cx, (u8Addr << 1u) | (uint8_t)enDir);
if(I2CDirTrans == enDir)//数据传输方向
{
/* 如果在主机传输过程中,需要等待传输结束*/
enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TENDF, Set, u32Timeout);
}
else
{
/* If in master receive process, Need wait TRA flag 如果在主机接收进程中,需要等待TRA标志 */
enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TRA, Reset, u32Timeout);
}
if(enRet == Ok)
{
/* 如果收到应答信号 NACK */
if(I2C_GetStatus(pstcI2Cx, I2C_SR_ACKRF) == Set)
{
enRet = Error;
}
}
}
return enRet;
}
en_result_t I2C_Mem_Read(uint8_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
en_result_t enRet;
//uint16_t u16MemAddrTemp;
//u16MemAddrTemp = ((u16MemAddr >> 8) & 0xFFul) + ((u16MemAddr << 8) & 0xFF00ul);
I2C_Cmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Disable);
enRet = I2C_Start(I2C_UNIT,u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirTrans, u32TimeOut);//向DTR数据发送寄存器发送从机地址
if(Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddr, E2_MEM_ADR_LEN, u32TimeOut);//向DTR数据发送寄存器发送内存地址
if(Ok == enRet)
{ //通过重新开始条件,切换发送/接收模式
enRet = I2C_Restart(I2C_UNIT,u32TimeOut);//I2C复位 先清除之前START的标志位 再重新添加标志位,然后检查
if(Ok == enRet)
{
if(1ul == u32Size)
{
I2C_AckConfig(I2C_UNIT, I2c_NACK);//I2C ACK状态配置
}
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);//向DTR数据发送寄存器发送从机地址
if(Ok == enRet)//如果从机地址发送顺利
{
enRet = I2C_MasterDataReceiveAndStop(I2C_UNIT, pu8Data, u32Size, u32TimeOut);//I2Cx主机接收数据以及停止I2C
}
I2C_AckConfig(I2C_UNIT, I2c_ACK);//I2C ACK状态配置
}
}
}
}
if(Ok != enRet)
{
enRet=I2C_Stop(I2C_UNIT,u32TimeOut);
}
I2C_Cmd(I2C_UNIT, Disable);
return enRet;
}
这是华大HC32F460的I2C通讯例程
I2C接收数据时,复位将传输方向改变后 发送从机地址就传输错误了 enRet返回一个超时错误 我单步调试时返回ok 一运行就返回超时错误 初步判断是时钟的问题 但是不知道怎么改 求助
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);//向DTR数据发送寄存器发送从机地址
{
en_result_t enRet;
DDL_ASSERT(IS_VALID_UNIT(pstcI2Cx));
DDL_ASSERT(IS_VALID_7BIT_ADR(u8Addr));
DDL_ASSERT(IS_VALID_TRANS_DIR(enDir));
enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TEMPTYF, Set, u32Timeout);// TEMPTYE 发送数据空标志位 0:I2C_DTR寄存器满 1:I2C_DTR寄存器空
if(Ok == enRet)
{
/* 发送I2C地址到DTR数据发送寄存器上 u8Addr 0x49 实际发送0x92/0x93 */
I2C_WriteData(pstcI2Cx, (u8Addr << 1u) | (uint8_t)enDir);
if(I2CDirTrans == enDir)//数据传输方向
{
/* 如果在主机传输过程中,需要等待传输结束*/
enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TENDF, Set, u32Timeout);
}
else
{
/* If in master receive process, Need wait TRA flag 如果在主机接收进程中,需要等待TRA标志 */
enRet = I2C_WaitStatus(pstcI2Cx, I2C_SR_TRA, Reset, u32Timeout);
}
if(enRet == Ok)
{
/* 如果收到应答信号 NACK */
if(I2C_GetStatus(pstcI2Cx, I2C_SR_ACKRF) == Set)
{
enRet = Error;
}
}
}
return enRet;
}
en_result_t I2C_Mem_Read(uint8_t u8DevAddr, uint16_t u16MemAddr, uint8_t *pu8Data, uint32_t u32Size, uint32_t u32TimeOut)
{
en_result_t enRet;
//uint16_t u16MemAddrTemp;
//u16MemAddrTemp = ((u16MemAddr >> 8) & 0xFFul) + ((u16MemAddr << 8) & 0xFF00ul);
I2C_Cmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Enable);
I2C_SoftwareResetCmd(I2C_UNIT, Disable);
enRet = I2C_Start(I2C_UNIT,u32TimeOut);
if(Ok == enRet)
{
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirTrans, u32TimeOut);//向DTR数据发送寄存器发送从机地址
if(Ok == enRet)
{
enRet = I2C_TransData(I2C_UNIT, (uint8_t *)&u16MemAddr, E2_MEM_ADR_LEN, u32TimeOut);//向DTR数据发送寄存器发送内存地址
if(Ok == enRet)
{ //通过重新开始条件,切换发送/接收模式
enRet = I2C_Restart(I2C_UNIT,u32TimeOut);//I2C复位 先清除之前START的标志位 再重新添加标志位,然后检查
if(Ok == enRet)
{
if(1ul == u32Size)
{
I2C_AckConfig(I2C_UNIT, I2c_NACK);//I2C ACK状态配置
}
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);//向DTR数据发送寄存器发送从机地址
if(Ok == enRet)//如果从机地址发送顺利
{
enRet = I2C_MasterDataReceiveAndStop(I2C_UNIT, pu8Data, u32Size, u32TimeOut);//I2Cx主机接收数据以及停止I2C
}
I2C_AckConfig(I2C_UNIT, I2c_ACK);//I2C ACK状态配置
}
}
}
}
if(Ok != enRet)
{
enRet=I2C_Stop(I2C_UNIT,u32TimeOut);
}
I2C_Cmd(I2C_UNIT, Disable);
return enRet;
}
这是华大HC32F460的I2C通讯例程
I2C接收数据时,复位将传输方向改变后 发送从机地址就传输错误了 enRet返回一个超时错误 我单步调试时返回ok 一运行就返回超时错误 初步判断是时钟的问题 但是不知道怎么改 求助
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);//向DTR数据发送寄存器发送从机地址
赞0
已处理
评论
2023-05-01
赞0
已处理
评论
2023-05-01
赞0
按你说的一点点加发现是传输内存地址的时候DTR数据接收寄存器接收完内存地址 SR状态寄存器NACK自动置1了,数据发送完了但又没有数据所以超时了,但是我调试的时候又发现到这里如果调试断点停在数据读取这一步,NACK又不会置1了,那么我在读取数据之前delay一下是否可行呢?我去试试
评论
2023-04-06
delay是可行的 搞了半天是执行时间的原因 执行时间太短 DTR数据没读取到 导致SR以为主机和从机的联系断开了 自动发送了NACK的信号
赞0
评论
2023-04-05
enRet = I2C_TransAddr(I2C_UNIT, (uint8_t)u8DevAddr, I2CDirReceive, u32TimeOut);//向DTR数据发送寄存器发送从机地址 这个函数有误 我程序直接编译过去会返回一个超时 一步步调试又没问题
您需要登录后才可以回复 登录 | 注册