小弟用P3.5和P3.6模拟I2C总线,但是得不出正确的波形,大佬们能指点一下吗?程序和波形图如下:
void IICstart()
{
P3OUT|=BIT5;//先保证SDA数据总线为高,保证在时钟信号为高的前提下以便于变低
_NOP();
_NOP();
_NOP();
P3OUT|=BIT6;
_NOP();
_NOP();
_NOP();
P3OUT&=~BIT5;//数据信号由高到低,启动信号发出
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
P3OUT&=~BIT6;//使时钟信号为底,以便数据下次的变化
_NOP();
_NOP();
_NOP();
_NOP();
}
//IIC停止信号,在scl为高的前提下,使SDA由低到高;
void IICstop()
{
P3OUT&=BIT5;//先保证SDA数据总线为低,保证在时钟信号为高的前提下以便于变高
_NOP();
_NOP();
_NOP();
P3OUT|=BIT6;
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
P3OUT|=BIT5;//数据信号由低到低高,停止信号发出
_NOP();
_NOP();
P3OUT&=~BIT6;
_NOP();
_NOP();
}
//IIC写一个字节,在scl为低的前提下,SDA上的数据才能变化;在SCL为高,SDA的数要稳定
void IICWrite1byte(unsigned char Buf)
{
unsigned char k;
for(k=0;k<8;k++)//一个字节为8位,故要读八位出来
{
if(Buf&0x80)//屏蔽低7位,保留高一位并且做出判断;
P3OUT|=BIT5;
else
P3OUT&=~BIT5;
_NOP();
_NOP();
//上面几句代码是为了在SCL为低的前提下,SDA做好数据准备
P3OUT|=BIT6;
_NOP();
_NOP();
_NOP();
_NOP();
_NOP();
Buf=Buf<<1;//Buf左移一位,因为最高位的数已经写入到SDA上面了,为写
//次高位做好准备
_NOP();
_NOP();
P3OUT&=~BIT6;//拉低SCL,为SDA上的数变化做好准备
_NOP();
_NOP();
}
P3DIR&=~BIT5;//
_NOP();
_NOP();
P3OUT|=BIT6;//当8位数据发送完毕后,第9个脉冲是要检测应答位
//当SDA=0时,数据发送完毕,SDA=1时未发送完
_NOP();
_NOP();
_NOP();
if(P3OUT&BIT5){
P3OUT&=~BIT6;
_NOP();
_NOP();
P3DIR=BIT5;
}
}
//往AT24C02中写一个字节
void WriteAT24C02(unsigned char address,unsigned char Databuf)
{
IICstart();
IICWrite1byte(0xA0);//写从器件的地址
IICWrite1byte(address);//要写到从器件的什么地址中
IICWrite1byte(Databuf);//地址中写的数
IICstop();
}
void delay(unsigned int z)
{
unsigned i;
for(i=0;i<=z;i++);
}
void main()
{
WriteAT24C02(0x18,99);
while(1);
}
波形图很乱,不知道问题处在哪,如下:
file:///C:UsersAdministratorAppDataRoamingTencentUsers1779521811QQWinTempRichOle D1O`X$MZW9K7WRJ]9L1~Z1.png
此帖出自
小平头技术问答
{
P3OUT&=BIT5;//先保证SDA数据总线为低,保证在时钟信号为高的前提下以便于变高
这个地方不对。没有取反。好好检查一下还有没有类似的问题。
你注意一下,逻辑分析仪的电平设置。要和波形的幅度匹配,否则,容易出问题。
您说的是把逻辑分析仪的阈值电压设置成和VDD一样的值吗?
你看你手里的型号,是否有电平的设置。他会显示电压幅度和阈值,比如选择3V3 ,阈值就应该显示1V65左右。 你选择电压时,他应该有显示的。
看从设备芯片手册的时序。起始,位宽等等,每一个部分都认真检查,是否和手册相符。当然,从设备硬件首先得正常
一周热门 更多>