使用pcf8574扩展I2C接口进行1602显示,但在进行proteus(7.8 sp2)调试时,不能长时间稳定工作,情况如下:
部分程序代码:(MCU:Attiny13)
#define SDA PB3 //i2c 端口,双向
#define SCL PB4 //i2c 端口,单向输出
#define SDA_OUT DDRB|=(1<<SDA) // i2c信号端配置为输出
#define SDA_IN DDRB&=~(1<<SDA) // i2c信号端配置为输入
#define SDA_1 PORTB|=(1<<SDA) // i2c信号端高电平
#define SDA_0 PORTB&=~(1<<SDA) // i2c信号端低电平
#define SDA_R PINB&(1<<SDA) // i2c信号输入1判断
#define SCL_OUT DDRB|=(1<<SCL) // i2c时钟端配置为输出
#define SCL_1 PORTB|=(1<<SCL) // i2c时钟端高电平
#define SCL_0 PORTB&=~(1<<SCL) // i2c时钟端低电平
/*-------------------------------------------------
调用方式:void i2cByteW(uchar ch)
函数说明:私有函数,I2C专用 ,写入1字节
-------------------------------------------------*/
void i2cByteW(uchar ch)
{
uchar i=8;
SDA_OUT;SCL_OUT;
while (i--)
{
if(ch&0x80) //此位数据是否为高
{
SDA_1; //是高则将单总线拉高
}
else
{
SDA_0; //是低则将单总线拉低
}
ch<<=1;
nops();SCL_1;nops();SCL_0;nops();
}
WaitACK();
}
/*-------------------------------------------------
内部函数,等待ACK
--------------------------------------------------*/
void WaitACK(void)
{ uchar errtime=10;
SDA_1; /*读ACK*/
SDA_IN;
nops();SCL_1;nops();
while(SDA_R)
{errtime--;
if(!errtime) break;
}
SCL_0;
}
仿真后截图如下:
经反复查找,可能问题是在PCF8574返回ACK时,SDA的下降沿在SCL下降沿之前出现了,造成输出sr的假象,但这个ACK时机在proteus模拟中,没法改变,是不是这个原因呢?我不好确定,实际工作中会不会不这样?请教大家有没有这个问题,谢谢。
|