TMS320F28069的硬件I2C一直卡在查询 I2caRegs.I2CSTR.bit.XRDY
项目场景:
使用TMS320F28069的硬件I2C读取MPU6050的数据
问题描述
Uint16 I2CA_ReadBytes( Uint16 SlaveAddress, Uint16 RomAddress,Uint16 number, Uint16 *RamAddr)
{
Uint16 i,Temp;
if (I2caRegs.I2CSTR.bit.BB == 1) //返回总线忙错误状态
{
return I2C_BUS_BUSY_ERROR;
}
while(!I2CA_CheckTxReady());
I2caRegs.I2CSAR = SlaveAddress&0x00ff; //设备从地址
I2caRegs.I2CCNT = 1; //发送一个字节为要读取数据的寄存器地址
I2caRegs.I2CDXR = RomAddress&0x00ff;
I2caRegs.I2CMDR.all = 0x6620; //主机发送模式,自动清除停止位不产生停止信号
if (I2caRegs.I2CSTR.bit.NACK == 1) //送到无应答信号返回错误
return I2C_BUS_BUSY_ERROR;
DELAY_US(5);
while(!I2CA_CheckTxReady()); //调试过程中有时会卡在这一步,表示通讯不正常
I2caRegs.I2CSAR = SlaveAddress&0x00ff;
I2caRegs.I2CCNT = number;
I2caRegs.I2CMDR.all = 0x6C20; //主机接受模式,包含有停止信号
if (I2caRegs.I2CSTR.bit.NACK == 1)
return I2C_BUS_BUSY_ERROR;
for(i=0;i<number;i++)
{
while(!I2CA_CheckRecieveOk());
Temp = I2caRegs.I2CDRR;
if (I2caRegs.I2CSTR.bit.NACK == 1)
return I2C_BUS_BUSY_ERROR;
*RamAddr = Temp;
RamAddr++;
}
return I2C_SUCCESS; //接受数据成功
}
读取数据,调试单步调试代码运行正常,但是全速运行就一直卡在 while(!I2CA_CheckTxReady()); 这一句,或者返回I2C_BUS_BUSY_ERROR。
原因分析:
调试通过说明主从机的时序对上,在查询标志位的时候出错了。查看代码I2CA_CheckTxReady(),发现原来的写法是:
Uint16 I2CA_CheckTxReady(void)
{
Uint16 t,;
t = I2caRegs.I2CSTR.bit.XRDY; // IIC模块发送准备OK
return t;
}
我猜测可能是因为函数出入时间较短,导致I2caRegs.I2CSTR.bit.XRDY寄存器的数据总线一直被占用了,硬件无法更新该标志位。
解决方案:
降低查询速率
Uint16 I2CA_CheckTxReady(void)
{
Uint16 t,i;
t = I2caRegs.I2CSTR.bit.XRDY; // IIC模块发送准备OK
for(i=5;i>0;i–);//添加延时
return t;
}
对于函数I2CA_CheckRecieveOk()同理同样操作,bug就解决了
下面是IIC源码
//###########################################################################
// $ 函数名称: void I2CA_Init(void) $
// $ 函数功能: IIC模块初始化,设置IIC模块的功能引脚以及设置IIC的工作方式 $
//###########################################################################
void I2CA_Init(void)
{I2caRegs.I2CMDR.all = 0x0000; // 复位IICEALLOW;GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0; // 使能(SDAA)上拉GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0; // 使能 (SCLA)上拉GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3; // 同步 (SDAA)GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3; // 同步 (SCLA)GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // 配置 GPIO32为 SDAAGpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1; // 配置GPIO33 为SCLAEDIS;// 预分频——时钟模块的频率I2caRegs.I2CPSC.all = 7; // 预分频 IIC模块时钟需设置为7-12MHz,本实验设置为 (80/8 = 10MHz)I2caRegs.I2CCLKL = 10; //时钟低电平时间值I2caRegs.I2CCLKH = 5; //时钟高电平时间值I2caRegs.I2CMDR.all = 0x0020; // IIC准备就绪DELAY_US(100000);
}//###########################################################################
// $ 函数名称: Uint16 I2CA_CheckTxReady() $
// $ 函数功能: IIC模块发送准备OK $
//###########################################################################
Uint16 I2CA_CheckTxReady(void)
{Uint16 t,i;t = I2caRegs.I2CSTR.bit.XRDY; // IIC模块发送准备OKfor(i=5;i>0;i--);return t;
}//###########################################################################
// $ 函数名称: Uint16 I2CA_CheckRecieveOk() $
// $ 函数功能: IIC模块接收准备OK $
//###########################################################################
Uint16 I2CA_CheckRecieveOk(void)
{Uint16 t,i;t = I2caRegs.I2CSTR.bit.RRDY; // IIC模块接收准备OKfor(i=5;i>0;i--);return t;
}//###########################################################################
// $ 函数名称: Uint16 I2CA_WriteBytes( Uint16 SlaveAddress, Uint16 RomAddress,Uint16 number, Uint8 *Wdata) $
// $ 函数功能: IIC写数据 $
//###########################################################################
Uint16 I2CA_WriteBytes( Uint16 SlaveAddress, Uint16 RomAddress,Uint16 number, Uint8 *Wdata)
{Uint16 i;if (I2caRegs.I2CSTR.bit.BB == 1){return I2C_BUS_BUSY_ERROR; //返回总线忙错误状态}while(!I2CA_CheckTxReady()); //等待数据发送就绪,XRDY=1,表明发送寄存器已经准备好接受新的数据I2caRegs.I2CSAR = SlaveAddress&0x00ff; //设备从地址I2caRegs.I2CCNT = number + 1; //需要发送的字节数I2caRegs.I2CDXR = RomAddress&0x00ff; //第一个发送字节为发送数据的目标寄存器地址I2caRegs.I2CMDR.all = 0x6E20; //发送起始信号,内部数据计数器减到0时,发送停止信号,主机发送模式,使能IIC模式,for (i=0; i<number; i++){while(!I2CA_CheckTxReady()); //等待数据发送就绪,发送下一个数据I2caRegs.I2CDXR = *Wdata&0xFF;Wdata++;if (I2caRegs.I2CSTR.bit.NACK == 1) //送到无应答信号返回错误return I2C_BUS_BUSY_ERROR;}return I2C_SUCCESS; //发送成功
}//###########################################################################
// $ 函数名称: Uint16 I2CA_ReadBytes( Uint16 SlaveAddress, Uint16 RomAddress,Uint16 number, Uint16 *RamAddr) $
// $ 函数功能: IIC读数据 $
//###########################################################################
Uint16 I2CA_ReadBytes( Uint16 SlaveAddress, Uint16 RomAddress,Uint16 number, Uint16 *RamAddr)
{Uint16 i,Temp;if (I2caRegs.I2CSTR.bit.BB == 1) //返回总线忙错误状态{return I2C_BUS_BUSY_ERROR;}while(!I2CA_CheckTxReady());I2caRegs.I2CSAR = SlaveAddress&0x00ff; //设备从地址I2caRegs.I2CCNT = 1; //发送一个字节为要读取数据的寄存器地址I2caRegs.I2CDXR = RomAddress&0x00ff;I2caRegs.I2CMDR.all = 0x6620; //主机发送模式,自动清除停止位不产生停止信号if (I2caRegs.I2CSTR.bit.NACK == 1) //送到无应答信号返回错误return I2C_BUS_BUSY_ERROR;DELAY_US(5);while(!I2CA_CheckTxReady()); //调试过程中有时会卡在这一步,表示通讯不正常I2caRegs.I2CSAR = SlaveAddress&0x00ff;I2caRegs.I2CCNT = number;I2caRegs.I2CMDR.all = 0x6C20; //主机接受模式,包含有停止信号if (I2caRegs.I2CSTR.bit.NACK == 1)return I2C_BUS_BUSY_ERROR;for(i=0;i<number;i++){while(!I2CA_CheckRecieveOk());Temp = I2caRegs.I2CDRR;if (I2caRegs.I2CSTR.bit.NACK == 1)return I2C_BUS_BUSY_ERROR;*RamAddr = Temp;RamAddr++;}return I2C_SUCCESS; //接受数据成功
}//###########################################################################
// $ 函数名称: IICwriteBit(Uint16 slaveaddress, Uint16 regaddress, Uint8 bitNum, Uint8 data) $
// $ 函数功能: IIC向寄存器的某一位写数据 $
//###########################################################################
void IICwriteBit(Uint16 slaveaddress, Uint16 regaddress, Uint8 bitNum, Uint8 data)
{Uint16 a;Uint8 b;DELAY_US(50);I2CA_ReadBytes(slaveaddress,regaddress,1,&a);b=(Uint8 )(a&0xff);b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));DELAY_US(50);I2CA_WriteBytes(slaveaddress,regaddress,1,&b);
}//###########################################################################
// $ 函数名称: IICwriteBits(Uint16 slaveaddress,Uint16 regaddress,Uint8 bitStart,Uint8 length,Uint8 data) $
// $ 函数功能: IIC向寄存器的某几位写数据 $
//###########################################################################
void IICwriteBits(Uint16 slaveaddress,Uint16 regaddress,Uint8 bitStart,Uint8 length,Uint8 data)
{Uint8 b,mask;Uint16 a;DELAY_US(50);I2CA_ReadBytes(slaveaddress,regaddress,1,&a);b=(Uint8 )(a&0xff);mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);data <<= (8 - length);data >>= (7 - bitStart);b &= mask;b |= data;DELAY_US(50);I2CA_WriteBytes(slaveaddress,regaddress,1, &b);
}
TMS320F28069的硬件I2C一直卡在查询 I2caRegs.I2CSTR.bit.XRDY相关推荐
- STM32单片机硬件I2C驱动程序(查询方式)
本文章原始地址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与接收. 本例程中采用I2C ...
- STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech
感谢原作者:FeoTech 原文网址:http://feotech.com/?p=69 本程序主要用于驱动STM32单片机芯片的硬件I2C寄存器,实现通过使用芯片自带的I2C寄存器进行数据的发送与 ...
- STM8/STM32硬件I2C读取APDS9930程序代码
STM的硬件I2C一直被各种吐槽,实际上只是用起来比较复杂而已,难点主要是在作为Master时的数据接收上,作为Slave时的数据发送没难度,正常用.重点是要真正掌握它里面设计的那个Data shif ...
- 联通物联卡流量查询、充值的操作方法
联通物联网卡是近年来发展较好的物联网卡之一,它是中国联通专门为物联网而设计的一种专用设备卡.随着我国物联网应用的日益增多,如何查询和评价物联网卡的价值已成为许多用户面临的难题.那么中国联通物联卡流量查 ...
- 联通物联卡为什么没有网络_联通物联网卡怎么样?联通物联卡的查询官网是什么?...
原标题:联通物联网卡怎么样?联通物联卡的查询官网是什么? 物联网时代的来临为我们生活中带来了许许多多的智能应用,移动物联网卡.电信物联网卡.联通物联网卡作为物联网最基础的通讯产品,在物联网应用中发挥着 ...
- 如何以物联网+硬件+物联卡方式构建新型智慧医疗管理体系?
医疗事业的建设关系着我国人民的身体健康和生命安全,医疗体制改革一直以来都是国家战略布局的重点,医疗改革的本质就是改善医疗服务,提升病患就医体验,今天中创物联网将探讨如何通过物联网技术实现医疗改革和物联 ...
- STM32F10x_硬件I2C主从通信(轮询发送,中断接收)
推荐 分享一个大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到人工智能的队伍中来!http://www.captainbed.net/strongerhuang Ⅰ.写在前面 ...
- STC8系列单片机硬件I2C使用教程(一)
硬件I2C(查询方式)以STC8F2K08S2单片机为例 一.I2C相关的寄存器 ① I2C 配置寄存器 ② I2C 主机控制寄存器 ③ I2C 主机辅助控制寄存器 ④ I2C 主机状态寄存器 ⑤ I ...
- STM32F10x_硬件I2C读写EEPROM(标准外设库版本)
Ⅰ.写在前面 上一篇文章是"STM32F10x_模拟I2C读写EEPROM",讲述使用IO口模拟I2C总线通信,对EEPROM(AT24Xxx)进行读写操作的过程. 上一篇文章主要 ...
最新文章
- 只因为离职报告多写这三个字,员工竟然倒赔公司2.9万!
- 用友u8cloud使用教程_四大ERP供应商SAP、Oracle、用友、金蝶哪个好
- 队列 集合的前n个元素
- python框架Flask学习笔记之get和post请求
- 随想录(怎么用source insight阅读kernel代码)
- 各种好用的开源库。快点进来,包你喜欢~^_^
- Flutter学习 — 实现滑动关闭、删除item
- vs2019编译的程序在win7环境上运行失败
- 安装CHD走过的一些坑
- MAC - macbook Ctrl键失灵的解决办法
- 俄罗斯计算机三进制优缺点,为什么我们没有用上三进制的计算机
- (11)向量组及其线性组合
- 2022 极术通讯-从CPU、DSA到软硬件融合
- WMP专辑封面显示不正常的问题(更新问题真实原因及完美解决方法)
- 如何更高效更系统地学习3D视觉?
- 果蔬超市管理系统的设计与实现
- 基于监督学习+自监督学习的智能抠图,精确到头发丝 | CVPR2020
- 关于如何定制开发Android第三方ROM,最全开发教程、原理阐述
- 前端文字转语音(tts+mp3拼接)
- 光纤光信号闪红灯_电信光纤猫光信号闪红灯怎么办 电信光纤猫光信号闪红解决方法...