24c16、24cxx系列 原子demo模拟iic读取出现0xff的问题

    在之前一直使用原子的模拟iic在各种stm32单片机上用时没有过这种情况,这次在PIC单片机上使用时出现了这个问题。无论如何读写都是0xff。在经过多天排查之后最终发现是问题在原子的demo的iic.c里面的发送启动和结束信号的时序导致的。先贴原子代码如下:
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	
}

    我们可以看到在发送启动信号的时候SDA和SCL同时置高或者置低。虽然有先后顺序,但是单片机如果在翻转电平时速度不够或者有其它原因导致的电平不稳这就使得发送的启动和结束信号不对;
逻辑分析仪如下:
不好意思,图

丢了,我描述一下吧


启动信号的时候必须要保证scl拉高之前SDA复位到高电平了,确保在SCL高电平时只有下降沿,所以说尽量让他们时间上有个明显的先后,否则可能SCL一旦高就将不稳定的SDA当成了一个启动或者别的指令。所以修改代码如下:

//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SCL=0;
	delay_us(1);
	IIC_SDA=1;
	delay_us(1);	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	delay_us(1);
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	delay_us(4);
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	
}

https://blog.youkuaiyun.com/pamzerbhu/article/details/79949684

解决问题之后的逻辑分析仪波形如下:
写入


读取
如有其它问题可以评论留言
### I2C读取数据返回0xFF的原因分析 当I2C总线上的设备读取数据时返回0xFF,通常意味着存在某种错误状态或异常情况。具体原因可能有以下几个方面: - **未接收到应答信号(ACK)**:如果主机未能从目标器件处获得有效的ACK信号,则会默认接收缓冲区为空并填充为全高电平即0xFF[^1]。 - **地址配置不匹配**:若发送给从机的7位或10位硬件地址与实际连接到SMBus/I2C总线上对应外设所设定的不同,那么该外围电路不会响应请求从而导致读操作失败而返回FFH值。 - **物理层问题**:线路接触不良、上拉电阻设置不当或是电源供电不足都可能导致通信不稳定甚至完全失效,进而表现为连续读回最高字节形式的数据——也就是十六进制下的0xFF[^2]。 ### 解决方案建议 针对上述提到的各种可能性,可以采取相应措施来排查和解决问题: #### 配置检查 确认所有涉及I2C接口初始化参数均按照手册规定正确无误地进行了定义,特别是关于频率及时序特性的部分;确保使用的地址码同外部芯片资料相符,并且注意区分不同模式下(标准/快速)对于起始条件生成时间的要求差异。 ```c // 初始化I2C模块, 设置合适的时钟速度以及正确的从设备地址 void Init_I2C(void){ // ...其他必要的寄存器配置... // 假定使用STM32 HAL库函数为例 hi2c.Init.ClockSpeed = 100000; /* Standard mode (100kHz) */ hi2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; } ``` #### 软件调试技巧 利用逻辑分析仪或者串口打印功能监控整个交互过程中的每一个阶段,包括但不限于启动标志、停止事件的发生时刻及其间隔长度;重点观察每一步骤之后是否有预期之外的状态改变发生,比如意外丢失同步脉冲之类的状况。 #### 硬件环境优化 仔细审查PCB布局布线图样,保证SDA/SCL两根导线尽可能短直以减少干扰源影响范围;选用适当阻值大小的上拉元件使得工作电压处于合理区间内,同时也要考虑到功耗因素的影响。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值