我要做家庭教师网络家庭教师 还有我要做网络红人心理咨询师考试 爱好收集各国影视,这样可以有很多收入吗

求助lms9b96的I2C通信问题 - 基于 Stellaris(R) ARM(R) Cortex(TM)-M3 的 MCU - 德州仪器在线技术支持社区
求助lms9b96的I2C通信问题
发表于3年前
<input type="hidden" id="hGroupID" value="39"
我是一个初学者,第一次弄I2C通信,出现了几个问题,在此求助下各位前辈了。&/p>
&p>我用lms9b96做从机,接收来自主机的命令帧,通过解析命令上报相关的信息。&/p>
&p>问题是这样的:&/p>
&p>1、每次主机发送地址时,我从机这边不能每次都有应答,也就是偶尔回响应偶尔不响应,通过串口打印信息发现偶尔能够进入数据接收中断,偶尔不能进入;&/p>
&p>2、另外就是,即使进入了中断,通过串口打印接收数据,发现与主机发送的不吻合;&/p>
&p>是不是程序中的函数设置有误?还是有没有考虑到的问题?确实没有解决思路了,请教大家了,非常感谢。&/p>
&p>#include &iic.h&&/p>
&p>volatile unsigned char g_ucDataRx = LED_ON;&br>volatile unsigned long ulStatus = 0;&br>volatile unsigned long ulSrisStatus=0;&/p>
&p>unsigned char *pucI2CDataO&br>unsigned char ucDataR &br>unsigned char ucI2CDataIn[16]={16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};&br>unsigned char ReceDataFlag = 0;&br>unsigned char ucCRC8Table[]={};&br>void DebugInfo()&br>{&br> UARTprintf(&DataIn[0] %d\n&,ucI2CDataIn[0]);&br> UARTprintf(&DataIn[1] %d\n&,ucI2CDataIn[1]);&br> UARTprintf(&DataIn[2] %d\n&,ucI2CDataIn[2]); &br> UARTprintf(&DataIn[3] %d\n&,ucI2CDataIn[3]);&br> UARTprintf(&DataIn[4] %d\n&,ucI2CDataIn[4]);&br> UARTprintf(&DataIn[5] %d\n&,ucI2CDataIn[5]); &br> UARTprintf(&DataIn[6] %d\n&,ucI2CDataIn[6]); &br> UARTprintf(&DataIn[7] %d\n&,ucI2CDataIn[7]);&br> UARTprintf(&DataIn[8] %d\n&,ucI2CDataIn[8]);&br> UARTprintf(&DataIn[9] %d\n&,ucI2CDataIn[9]); &br> UARTprintf(&DataIn[10] %d\n&,ucI2CDataIn[10]);&br>}&/p>
&p>void I2C1_Init()&br> {&/p>
&p>SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // 使能I2C1相应的引脚时钟&br> //&br> SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);// 配置PA0和PA1引脚的类型&br> //&br> GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);// 配置PA6和PA7为SCL和SDA&br> //&br> GPIOPinConfigure(GPIO_PA6_I2C1SCL);//bule&br> GPIOPinConfigure(GPIO_PA7_I2C1SDA);//yellow&/p>
&p>I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_ADDRESS);// 设置本身地址&br> //&br> I2CSlaveEnable(I2C1_SLAVE_BASE);// 使能I2C模块&br> //&br> I2CSlaveIntEnable(I2C1_SLAVE_BASE);// 使能从机中断源&br> //&br> IntEnable(INT_I2C1); // 开启I2C1的中断&br> &br> I2CSlaveIntEnableEx(I2C1_SLAVE_BASE, I2C_SLAVE_INT_DATA|I2C_SLAVE_INT_START|I2C_SLAVE_INT_STOP);//中断条件选择//I2C_SLAVE_INT_DATA|&br> //I2CSlaveIntEnableEx(I2C1_SLAVE_BASE,I2C_SLAVE_INT_DATA);&br>}&/p>
&p>unsigned char ucSendByteCounter = 0;&br>unsigned char ucReceByteCounter = 0;&/p>
&p>void I2C1IntHandler(void)&br>{&/p>
&p>//GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, LED_OFF);&br> //UARTprintf(&IIC_In&);&/p>
&p>I2CSlaveIntClear(I2C1_SLAVE_BASE);// 清除中断&br> //&br> ulStatus = I2CSlaveStatus(I2C1_SLAVE_BASE); // 读取中断状态&br> //&br> ulStatus = ulStatus & (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_TREQ | I2C_SLAVE_CSR_FBR);// 屏蔽不需要的位&br> //&br> //&br> // 读取原始中断状态&br> // &br> ulSrisStatus = I2CSlaveIntStatusEx(I2C1_SLAVE_BASE,SLAVE_ADDRESS);&br> //&br> // 屏蔽原始中断不需要的位&br> //&br> ulSrisStatus = ulSrisStatus & (I2C_MASTER_CS_STOP | I2C_MASTER_CS_START | I2C_MASTER_CS_RUN);&br> &br> I2CSlaveIntClearEx(I2C1_SLAVE_BASE,I2C_SICR_STOPIC | I2C_SICR_DATAIC | I2C_SICR_STARTIC); &br> switch(ulSrisStatus){&br> //&br> // 停止信号中断&br> //&br> case I2C_MASTER_CS_STOP:&br> ucReceByteCounter = 0; &br> ReceDataFlag = 1;&br> UARTprintf(&D#Cnt_stop %d\n&,ucReceByteCounter);&/p>
&p>&br> //&br> // 停止信号中断&br> //&br> case I2C_MASTER_CS_START:&br> ucReceByteCounter = 1;&br> UARTprintf(&D#Cnt_start %d\n&,ucReceByteCounter);&/p>
&p>&br> default:&br>&br> } &br> switch(ulStatus){ // 判断状态&/p>
&p>// 有发送请求,发送数据&br> case I2C_SLAVE_CSR_TREQ: // Transmit request received&br> if(ucSendByteCounter & *(pucI2CDataOut+1)+1){&br> I2CSlaveDataPut(I2C1_SLAVE_BASE , *(pucI2CDataOut + ucSendByteCounter));&br> ucSendByteCounter ++ ;&br> }&br> else &br> I2CSlaveDataPut(I2C1_SLAVE_BASE,0xaa);&br>&/p>
&p>// 接收数据&br> case (I2C_SLAVE_CSR_RREQ): // Receive data from I2C master&br> ucI2CDataIn[ucReceByteCounter] = I2CSlaveDataGet(I2C1_SLAVE_BASE);&br> ucReceByteCounter++;&br> UARTprintf(&DCnt %d\n&,ucReceByteCounter); &br>ReceDataFlag = 1;&br>&br> &br> // 接受到第一个字节&br> case (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_FBR ): // First byte received from master&br> ucI2CDataIn[ucReceByteCounter] = I2CSlaveDataGet(I2C1_SLAVE_BASE);&br> UARTprintf(&D#Cnt %d\n&,ucReceByteCounter); &br>ucReceByteCounter++;&br> /ReceDataFlag = 1;&br>&br> &br> default:&br>&/p>
&p>}&br>}&/p>&div style=&clear:&>&/div>" />
求助lms9b96的I2C通信问题
此问题尚无答案
All Replies
我是一个初学者,第一次弄I2C通信,出现了几个问题,在此求助下各位前辈了。
我用lms9b96做从机,接收来自主机的命令帧,通过解析命令上报相关的信息。
问题是这样的:
1、每次主机发送地址时,我从机这边不能每次都有应答,也就是偶尔回响应偶尔不响应,通过串口打印信息发现偶尔能够进入数据接收中断,偶尔不能进入;
2、另外就是,即使进入了中断,通过串口打印接收数据,发现与主机发送的不吻合;
是不是程序中的函数设置有误?还是有没有考虑到的问题?确实没有解决思路了,请教大家了,非常感谢。
#include &iic.h&
volatile unsigned char g_ucDataRx = LED_ON;volatile unsigned long ulStatus = 0;volatile unsigned long ulSrisStatus=0;
unsigned char *pucI2CDataOunsigned char ucDataR unsigned char ucI2CDataIn[16]={16,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};unsigned char ReceDataFlag = 0;unsigned char ucCRC8Table[]={};void DebugInfo(){ UARTprintf(&DataIn[0] %d\n&,ucI2CDataIn[0]); UARTprintf(&DataIn[1] %d\n&,ucI2CDataIn[1]); UARTprintf(&DataIn[2] %d\n&,ucI2CDataIn[2]);
UARTprintf(&DataIn[3] %d\n&,ucI2CDataIn[3]); UARTprintf(&DataIn[4] %d\n&,ucI2CDataIn[4]); UARTprintf(&DataIn[5] %d\n&,ucI2CDataIn[5]);
UARTprintf(&DataIn[6] %d\n&,ucI2CDataIn[6]);
UARTprintf(&DataIn[7] %d\n&,ucI2CDataIn[7]); UARTprintf(&DataIn[8] %d\n&,ucI2CDataIn[8]); UARTprintf(&DataIn[9] %d\n&,ucI2CDataIn[9]);
UARTprintf(&DataIn[10] %d\n&,ucI2CDataIn[10]);}
void I2C1_Init() {
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // 使能I2C1相应的引脚时钟 // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);// 配置PA0和PA1引脚的类型 // GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);// 配置PA6和PA7为SCL和SDA // GPIOPinConfigure(GPIO_PA6_I2C1SCL);//bule GPIOPinConfigure(GPIO_PA7_I2C1SDA);//yellow
I2CSlaveInit(I2C1_SLAVE_BASE, SLAVE_ADDRESS);// 设置本身地址 // I2CSlaveEnable(I2C1_SLAVE_BASE);// 使能I2C模块 // I2CSlaveIntEnable(I2C1_SLAVE_BASE);// 使能从机中断源 // IntEnable(INT_I2C1); // 开启I2C1的中断
I2CSlaveIntEnableEx(I2C1_SLAVE_BASE, I2C_SLAVE_INT_DATA|I2C_SLAVE_INT_START|I2C_SLAVE_INT_STOP);//中断条件选择//I2C_SLAVE_INT_DATA| //I2CSlaveIntEnableEx(I2C1_SLAVE_BASE,I2C_SLAVE_INT_DATA);}
unsigned char ucSendByteCounter = 0;unsigned char ucReceByteCounter = 0;
void I2C1IntHandler(void){
//GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, LED_OFF); //UARTprintf(&IIC_In&);
I2CSlaveIntClear(I2C1_SLAVE_BASE);// 清除中断 // ulStatus = I2CSlaveStatus(I2C1_SLAVE_BASE); // 读取中断状态 // ulStatus = ulStatus & (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_TREQ | I2C_SLAVE_CSR_FBR);// 屏蔽不需要的位 // // // 读取原始中断状态 //
ulSrisStatus = I2CSlaveIntStatusEx(I2C1_SLAVE_BASE,SLAVE_ADDRESS); // // 屏蔽原始中断不需要的位 // ulSrisStatus = ulSrisStatus & (I2C_MASTER_CS_STOP | I2C_MASTER_CS_START | I2C_MASTER_CS_RUN);
I2CSlaveIntClearEx(I2C1_SLAVE_BASE,I2C_SICR_STOPIC | I2C_SICR_DATAIC | I2C_SICR_STARTIC);
switch(ulSrisStatus){ // // 停止信号中断 // case I2C_MASTER_CS_STOP: ucReceByteCounter = 0;
ReceDataFlag = 1; UARTprintf(&D#Cnt_stop %d\n&,ucReceByteCounter);
// // 停止信号中断 // case I2C_MASTER_CS_START: ucReceByteCounter = 1; UARTprintf(&D#Cnt_start %d\n&,ucReceByteCounter);
default: }
switch(ulStatus){ // 判断状态
// 有发送请求,发送数据 case I2C_SLAVE_CSR_TREQ: // Transmit request received if(ucSendByteCounter & *(pucI2CDataOut+1)+1){ I2CSlaveDataPut(I2C1_SLAVE_BASE , *(pucI2CDataOut + ucSendByteCounter)); ucSendByteCounter ++ ; } else
I2CSlaveDataPut(I2C1_SLAVE_BASE,0xaa);
// 接收数据 case (I2C_SLAVE_CSR_RREQ): // Receive data from I2C master ucI2CDataIn[ucReceByteCounter] = I2CSlaveDataGet(I2C1_SLAVE_BASE); ucReceByteCounter++; UARTprintf(&DCnt %d\n&,ucReceByteCounter); ReceDataFlag = 1;
// 接受到第一个字节 case (I2C_SLAVE_CSR_RREQ | I2C_SLAVE_CSR_FBR ): // First byte received from master ucI2CDataIn[ucReceByteCounter] = I2CSlaveDataGet(I2C1_SLAVE_BASE); UARTprintf(&D#Cnt %d\n&,ucReceByteCounter); ucReceByteCounter++; /ReceDataFlag = 1;
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
进士5850分
楼主不要用UARTprintf(&DataIn[0] %d\n&,ucI2CDataIn[0]);这种函数,尤其是在中断函数中,不要去通过UART发送东西。
这样写可能导致中断程序无法正常响应。
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
进士3545分
另外我补充一点,由于I2C的SCL引脚不能设置成开漏,所以在I2C0的配置中,应该使用GPIOPinTypeI2CSCL函数。
可以将I2C的初始化代码中
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);// 配置PA6和PA7为SCL和SDA
// 配置PA6和PA7为SCL和SDA
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
同时,将SCL做上拉
Best Regards
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
请问:我要是想调试中断中的代码,想通过串口打印出来,在电脑是中显示出来,怎么办呢?
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
进士3545分
使用UARTprintf即可。
Best Regards
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
楼上的Richard MA说不能在中断中使用UARTprintf函数,你又说能,能否解释一下呢?谢谢啦
You have posted to a forum that requires a moderator to approve posts before they are publicly available.
请答复啊啊啊啊啊啊!!!!!
You have posted to a forum that requires a moderator to approve posts before they are publicly available.经检测你所在的网络可能存在爬虫,因资源限制,我们只能拒绝你的请求。
如果你是推酷的用户,可以以继续访问使用。
如有疑问,可将IP信息发送到
请求解封。查看: 1928|回复: 7
用模拟IO的方式来实现I2C考虑过锁死的情况吗?就是主设备和从设备互相等待的问题。
主题帖子精华
中级会员, 积分 475, 距离下一级还需 25 积分
在线时间0 小时
用模拟IO的方式来实现I2C考虑过锁死的情况吗?就是主设备和从设备互相等待的问题。
在正常情况下,I2C总线协议能够保证总线正常的读写操作。但是,当I2C主设备异常复位时(看门狗动作,板上电源异常导致复位芯片动作,手动按钮复位等等)有可能导致I2C总线死锁产生。下面详细说明一下总线死锁产生的原因。
&&& 在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续I2C的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。而对于I2C主设备来说.复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种死锁状态。同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。
(1)尽量选用带复位输人的I2C从器件。
&&&&(2)将所有的从I2C设备的电源连接在一起,通过MOS管连接到主电源,而MOS管的导通关断由I2C主设备来实现。
&&& (3)在I2C从设备设计看门狗的功能。
&&&&(4)在I2C主设备中增加I2C总线恢复程序。
主题帖子精华
高级会员, 积分 713, 距离下一级还需 287 积分
在线时间0 小时
学习了,感觉方法一、二可能好用些
主题帖子精华
在线时间159 小时
主题帖子精华
在线时间75 小时
主题帖子精华
在线时间478 小时
主题帖子精华
初级会员, 积分 172, 距离下一级还需 28 积分
在线时间10 小时
学习了,谢谢!
暂不做硬件,投身机器学习和数据挖掘。欢迎交流!
主题帖子精华
金牌会员, 积分 1847, 距离下一级还需 1153 积分
在线时间94 小时
分明没有研究相关文献.
无论是主机复位,或者是从机复位,都有一个同步方法:
主机发送&START&-保持SDA高电平发送9个SCL-发送&START&-发送&STOP&.
技术讨论请发帖 , 需要我回复请点左下的
让系统通知我 .
本人不通过其他方式返回任何参数.
主题帖子精华
新手上路, 积分 30, 距离下一级还需 20 积分
在线时间0 小时
感谢分享!
Powered by你的位置:
I2C插入等待状态求助
今天看了一个I2C的资料,有个地方不是很清楚,上面说: “如果被控器需要延迟下一个数据字节开始传送的时间,则可以通过把时钟线SCL电平拉低并且保持,使主控器进入等待状态。”但是SCL不是应该由主控器提供吗,为什么被控器可以把SCL置低呢?

我要回帖

更多关于 心理咨询师报考条件 的文章

 

随机推荐