我发现GT9147_RD_Reg(GT_GSTID_REG,&mode,1),没有触点时,多次能读到0xFF(当然还有别的异常值)。用示波器跟踪发现STM32F407发送0x28,GT9147竟然没有ACK。整个波形全是乱的。在CTIIC.C中,优化了三个函数,测试OK(无触点或者数据没有准备oK,GT9147_RD_Reg(GT_GSTID_REG,&mode,1); mode=0;松手,可以观察到3次mode=0x80,我不是太明白为何有3次;有一个触点,mode=0x81,多个mode=0x8*)
应该是从侧先ACK,后有主侧SCL变高电平,优化之
u8 CT_IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
CT_SDA_IN(); //SDA设置为输入
CT_IIC_SCL=0;
delay_us(2);
while(CT_READ_SDA)
{
ucErrTime++;
delay_us(2);
if(ucErrTime>250)
{
CT_IIC_Stop();
return 1;
}
}
delay_us(2);
CT_IIC_SCL=1;
delay_us(2);
CT_IIC_SCL=0;
delay_us(3);
return 0;
}
增加SDA到SCL之间的延时,解决发地址没有ACK问题
void CT_IIC_Send_Byte(u8 txd)
{
u8 t;
CT_SDA_OUT();
CT_IIC_SCL=0;//拉低时钟开始数据传输
CT_Delay();
for(t=0;t<8;t++)
{
CT_IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2);//pnhhit
CT_IIC_SCL=1;
CT_Delay();
CT_IIC_SCL=0;
CT_Delay();
}
}
读数据延时放大,100us,是我大致放大,可以在细化 ,比如50us
u8 CT_IIC_Read_Byte(unsigned char ack)
{
u8 i,receive=0;
CT_SDA_IN();//SDA设置为输入
//delay_us(30);//pnhhit 这个相对myiic.c文件是正点原子他们自己加的,但是我测试还是不够长
delay_us(100);
for(i=0;i<8;i++ )
{
CT_IIC_SCL=0;
CT_Delay();
CT_IIC_SCL=1;
receive<<=1;
if(CT_READ_SDA)receive++;
delay_us(1);//pnhhit
}
if (!ack)CT_IIC_NAck();//发送nACK
else CT_IIC_Ack(); //发送ACK
return receive;
}
GPIO模拟I2C,有点问题,这里随便说说:
1)SDA,SCL最好设置成OD门,否则当CPU驱动SDA为高,IC应答ACK为低,SDA信号上出现半高电平。
2)不同的IC存放数据和准备数据的物理时间可能不同,比如GT9147和TI流量计芯片QB27520就不同
3)GPIO模拟时没有对SDA和SCL的状态裁决,不管IC的状态,强行控制,是很简单粗暴的
另外,u8 GT9147_Scan(u8 mode)函数,是不是还要优化一下!
一周热门 更多>