8H4K64TL, I2C调试时, 发I2CMSCR命令后,无响应 | 已解决,又有新问题
大佬,请假一下,I2C没有响应,,,,,最进步的输出都不正常。发送完命令后没有进入中断,I2CMSST的MSIF:主机模式的中断请求位(中断标志位),经测试没有置 1.
简化后用下面的程序,一直卡在DO不断翻转。 示波器看SDA和SCL波形,同时下拉,并无错位延时。
P1^4和P1^5的端口,另外测试是可以正常输出波形的。
配置参考例程。
P_SW2 |= 0x80;
I2CCFG = 0xe0; //使能 I2C ,主机模式。速度32X2+4个时钟
I2CMSST = 0x80; //等待命令
EA = 1;
while(1)
{
I2CMSCR = 0x81; ///发送start信号
while (!(I2CMSST & 0x40)){DO = ~DO;}--------------------一直卡在这里; 没检测到下面的20ms延时。
I2CMSST &= ~0x40;
delayms(20);
}
在进行I2C调试时,遇到发送I2CMSCR命令后无响应的情况,可能是由于硬件配置、软件逻辑或外部环境等多方面原因导致的。以下是对该问题的详细分析和可能的解决方案。
1. 硬件配置检查
首先,确保硬件连接正确无误。I2C总线需要上拉电阻,通常为4.7kΩ,以确保SDA和SCL线在空闲时保持高电平。检查P1^4(SDA)和P1^5(SCL)引脚是否正确连接到I2C设备,并且上拉电阻已正确安装。
2. 软件配置检查
在软件配置方面,确保I2C模块的配置寄存器设置正确。根据提供的代码,I2CCFG和I2CMSST的配置如下:
c
PSW2 |= 0x80;
I2CCFG = 0xe0; //使能 I2C ,主机模式。速度32X2+4个时钟
I2CMSST = 0x80; //等待命令
EA = 1;
PSW2 |= 0x80;:确保I2C模块的时钟和引脚配置正确。
I2CCFG = 0xe0;:使能I2C模块,并设置为主机模式,时钟速度为32X2+4个时钟。
I2CMSST = 0x80;:清除中断标志位,等待命令。
3. 中断处理
在I2C通信中,中断处理是关键的。确保中断使能位EA已正确设置,并且中断服务程序(ISR)已正确配置。如果中断未触发,可能是由于中断配置不正确或中断优先级设置问题。
4. 调试步骤
根据提供的代码,程序卡在while (!(I2CMSST & 0x40)){DO = ~DO;}处,说明I2CMSST的MSIF位未置1。以下是可能的调试步骤:
4.1 检查I2C总线状态
使用示波器或逻辑分析仪检查SDA和SCL线的波形,确保总线在发送START信号后处于正确状态。如果总线被拉低或波形异常,可能是由于总线冲突或设备未正确响应。
4.2 检查I2C设备地址
确保I2C设备的地址正确,并且设备已正确初始化。如果设备地址错误或设备未初始化,I2C主机将无法收到ACK信号,导致通信失败。
4.3 检查I2C时序
I2C通信对时序要求严格,确保时钟频率和时序符合设备规格。如果时钟频率过高或过低,可能导致通信失败。
4.4 检查电源和地线
确保I2C设备和主控芯片的电源和地线连接良好,电源电压稳定。电源噪声或地线干扰可能导致通信异常。
5. 代码优化
根据提供的代码,可以进一步优化和调试:
c
PSW2 |= 0x80;
I2CCFG = 0xe0; //使能 I2C ,主机模式。速度32X2+4个时钟
I2CMSST = 0x80; //等待命令
EA = 1;
while(1)
{
I2CMSCR = 0x81; ///发送start信号
while (!(I2CMSST & 0x40))
{
DO = ~DO; // 调试信号
}
I2CMSST &= ~0x40; // 清除中断标志位
delayms(20);
}
6. 进一步调试
如果上述步骤仍未解决问题,可以尝试以下方法:
使用调试器单步执行代码,检查寄存器和变量的值,确保程序逻辑正确。
尝试降低I2C时钟频率,观察是否能够正常通信。
检查I2C设备的电源和地线,确保设备正常工作。
7. 总结
I2C通信无响应的问题可能涉及硬件配置、软件逻辑和外部环境等多方面因素。通过逐步排查硬件连接、软件配置和调试代码,可以找到问题的根源并解决。如果问题仍未解决,建议参考芯片手册和I2C协议规范,进一步深入分析和调试。
希望以上分析和建议能够帮助您解决I2C调试中的问题。如有进一步疑问,欢迎继续交流。
[本文内容由国芯人工智能辅助生成,仅供参考] bit I2C_Busy;void I2C_Start(void)
{
I2C_Busy=1;
I2CMSCR=0x81;
while(I2C_Busy);
}
void I2C_SendData(unsigned char dat)
{
I2CTXD=dat;
I2C_Busy=1;
I2CMSCR=0x82;
while(I2C_Busy);
}
void I2C_RecvACK(void)
{
I2C_Busy=1;
I2CMSCR=0x83;
while(I2C_Busy);
}
//unsigned char I2C_RecvData(void)
//{
// I2C_Busy=1;
// I2CMSCR=0x84;
// while(I2C_Busy);
// return I2CRXD;
//}
//void I2C_SendACK(void)
//{
// I2CMSST=0x00;
// I2C_Busy=1;
// I2CMSCR=0x85;
// while(I2C_Busy);
//}
//void I2C_SendNAK(void)
//{
// I2CMSST=0x01;
// I2C_Busy=1;
// I2CMSCR=0x85;
// while(I2C_Busy);
//}
void I2C_Stop(void)
{
I2C_Busy=1;
I2CMSCR=0x86;
while(I2C_Busy);
}
void Init(void)
{
P_SW2|=EAXFR;
P3M0=0x00;
P3M1=0x00;
P5M0=0x00;
P5M1=0x00;
P3PU=0x0c;
I2CCFG=0xC1; //921.6K@11.0592M
I2CMSCR=EMSI;
I2CMSST=0x00;
EA=1;
}void I2C_Isr(void) interrupt 24
{
_push_(P_SW2);
P_SW2|=EAXFR;
if(I2CMSST&MSIF)
{
I2CMSST&=~MSIF;
I2C_Busy=0;
}
_pop_(P_SW2);
}
建议上传完整工程。是不是在中断里清掉了
ercircle 发表于 2025-4-23 18:01
建议上传完整工程。是不是在中断里清掉了
压根没进入中断, 因为一直卡在DO=~DO那里,不断输出波形。 DebugLab 发表于 2025-4-23 17:58
开始这些全部都弄进去了,重新整理,实在没反应了才不断的简化。 发现发送指令后,连中断都没进入 dxtvrcmn 发表于 2025-4-23 18:03
压根没进入中断, 因为一直卡在DO=~DO那里,不断输出波形。
或者检查没声明中断函数?
dxtvrcmn 发表于 2025-4-23 18:03
压根没进入中断, 因为一直卡在DO=~DO那里,不断输出波形。
就是这个函数
void I2C_Interrupt() interrupt 24
我测试可以运行到P2=0x0F;点灯 ercircle 发表于 2025-4-23 18:19
就是这个函数
void I2C_Interrupt() interrupt 24
有声明的,本身也是有调用过这里的i2c.....h内的子函数。
中断函数内,把busy直接 =0, 也发现没执行到。
更正一下,刚测试的有变化, 进中断了。
发送start信号,SDA和SCL的信号同时拉低。
dxtvrcmn 发表于 2025-4-23 18:25
有声明的,本身也是有调用过这里的i2c.....h内的子函数。
中断函数内,把busy直接 =0, 也发现没执行到 ...
I2CMSST &= ~0x40;
会清除中断标识导致主函数阻塞
页:
[1]
2