小弟用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
此帖出自
小平头技术问答
给您看下我的波形图吧。我从设备地址是110111M(M为0或者1),然后加上写位就是11011100,16位是DC。
看从设备手册,它还提到了发送只能两字节两字节发,我有点没搞明白
协议你自己对照手册看吧。 一帧数据的结构应该是有说明的。i2C的协议,你好好理解一下。i2C的协议,你可以抛开手册,看基本规则。协议本身理解了。再结合手册中,时序的要求。一般不会有太大的差异。时序这块就应该能清楚了。 按照时序要求去写。 时钟间隔不一致。这样开发不太规范。开发要踏下心来分析。
一周热门 更多>