电子文章 | 电子资料下载 | 家电维修 | 维修资料下载 | 加入收藏 | 全站地图
您现在所在位置:电子爱好者电子文章电子基础知识并口模拟IIC的经验之谈

并口模拟IIC的经验之谈

08-09 23:01:54 | http://www.5idzw.com | 电子基础知识 | 人气:319
标签:电子基础,电子基础知识应用,电工电子技术基础,http://www.5idzw.com 并口模拟IIC的经验之谈,http://www.5idzw.com
向378H写入"0XFC",使SCL和SDA为低电平,延时一段时间,向378H写入"0XFD",使SCL变为高电平,SDA为低电平,延时,向378H写入"0XFF"SCL保持不变,使SDA由原来的低电平变为高电平,即产生了一个停止信号。延时一段时间,最后向378H写入"0XFE",使SCL为低电平,以完成一个时钟。

发送数据:先把要发送的数据放在一个变量里,然后按位发送。方法为,通过位运算求得欲发送位的值(
1或0),然后用写端口函数模拟出SCL和SDA,并按I2C的写时序将一位数据发送出去,程序中可用while循环语句来控制发送的位数和字节数。

主机(并口)发送应答:I2C总线,主机发送应答用在连续读时序中,每读取一字节(8位)后,主机使SDA
保持一个时钟周期的低电平。可以用写端口函数先将SDA、SCL置为 0,然后将SCL变高,SDA保持低电平,一个应答信号既被发送,最后将SCL置低,完成一个时钟。

接收数据:并口读取I2C总线的数据时,必须让 T1截止,使用并口的13脚来接收SDA上的数据。可按下面步
骤操作,先用写端口函数使SCL为低电平,同时在并口3脚输出高电平使 T1 截止。然后用写端口函数单独将SCL置1,其它位保持不变,模拟出时钟上升沿,IC1 将把一位数据放到数据线SDA上,用读端口函数 读
取‘打印机状态'寄存器379H当前的值,将结果赋值给一个变量,然后对这个变量进行先右移4位,再左移7位
的运算(用以获得13 脚电平状态,即打印机状态寄存器的位 4 的值),判断该变量是否为0,最后将判断结果
移入另外的一个用于存放‘已读取数据'的变量中,完成读取一位数据的操作,用写端口函数使SCL为低电平,
在下一个SCL的上升沿,同样用上面的方法将一位数据加入‘已读取数据'变量中。可用while循环控制要读的
位数和字节数。注意以上过程都是在 T1 为截止态时进行的。

主机(并口)接收应答:接收应答用于写 I2C 时,每写一字节数据到从机后,如果操作成功,从机在下一
个时钟内使 SDA 为低。主机查询应答可以加强操作的可靠性。接收应答和上面说的接收数据大致相同,只是仅 接收一位数据并且不存储,直接判断其值是否为 0,不为 0 时(即没有收到应答)转错误处理程序,为 0则继
续后面的操作。在实际编程时将这个步骤合并到写I2C的操作中。

有关延时:I2C器件对SDA和SCL上的高、低电平信号需保持的时间是有规定的。如:开始信号的高、低电平
要保持多长时间,数据信号的高、低电平最低要保持多长时间等。不同的器件对这个时间有不同的规定。查找
24LO02的数据手册,可以知道,它在不同的电压下对各信号要保持的时间分别在几百纳秒到几微秒之间。这个
时间也体现了I2C器件的读写速度。因为计算机的速度不同,要用计算机并口来模拟I2C很难将这个时间精确到
微秒。为了能够在不同的计算机上可靠的操作I2C总线,试验程序用了C语言的延时函数delay();这个函数能产
生的最小延时为1毫秒。虽然这样做降低了I2C的读写速度,但可以保证操作的可靠性。

程序代码:

/***************************************/
//控制的地址是0x378
//SDA信号: PIN13 模拟作为主机的输入;
//                PIN3 模拟作为主机的输出;
//SCL信号: PIN15 模拟作为主机的输入;
//                PIN5 模拟作为主机的输出;
/***************************************/
/*************************************/
//函数名称:IIC start 函数
//开始信号:在时钟线(SCL)为高电平其间,
//数据线(SDA)由高变低,将产生一个开始信号。
/*************************************/
void port2iicbase::i2c_start()
{
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);
SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
delay(1);
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
return;
}
/*************************************/
//函数名称:IIC stop 函数
//停止信号:在时钟线(SCL)为高电平其间,
//数据线(SDA)由低变高,将产生一个停止信号
/*************************************/
void port2iicbase::i2c_stop()
{
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);
SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
delay(1);/***/
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);/**/
SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
}
/*************************************/
//函数名称:IIC 写一个字节函数
/*************************************/
int port2iicbase::i2c_writebyte(char c)
{
short int count=7;
char temp;
DWORD dwPortVal;
char e;

while(count>=0)
{
   temp=c>>count;
   temp=temp<<7;          //确定传输的字节
   if (temp=='\x80')      //传输"1"
   {
    SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
    delay(1);
    SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
    delay(1);
    SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
    delay(1);
    SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
    delay(1);
   }
   else                   //传输"0"
   {
    SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
    delay(1);
    SetPortVal(PORT1,0x0d,1);/*scl 1, sda 0*/
    delay(1);
    SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
    delay(1);
   }
   count--;
}
/**ask**/
SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
delay(1);/***/
SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
delay(1);
// SetPortVal(PORT1,0x05,1);/*scl 0, sda 0*/
// delay(1);/***/

GetPortVal(PORT2, &dwPortVal, 1);
e = (char)dwPortVal;
temp=e>>4;
temp=temp<<7;

if (temp=='\x0')
   return 0;
else
   MessageBox(NULL,"Not Acknowledge!!","发送错误",MB_OKCANCEL);
return 1;
}
/*************************************/
//函数名称:IIC 读一个字符函数
/*************************************/
char port2iicbase::i2c_readbyte()
{
unsigned short count=8;
char d,e,f='\x0';
DWORD dwPortVal;

while(count>0)
{
   SetPortVal(PORT1,0x07,1);/*scl 0, sda 1*/
   delay(1);/***/
   SetPortVal(PORT1,0x0f,1);/*scl 1, sda 1*/
   delay(1);

   GetPortVal(PORT2, &dwPortVal, 1);
   e = (char)dwPortVal;
   d=e>>4;
   d=d<<7;

   if(d=='\x80')
    d='\x1';
   f=f<<1;
   f=(f+d);                  //组合成字节
   count--;
}
return f;

上一页  [1] [2] [3]  下一页

,并口模拟IIC的经验之谈
关于《并口模拟IIC的经验之谈》的更多文章