在51上用P1口模拟I2C

时间:2008-08-18

使用下面代码,可以在51上用P1口模拟I2C。

/* 电平模拟函数和基本读写函数 
void IIC_Start(void); 
void IIC_Stop(void); 
void SEND_0(void); 
void SEND_1(void); 
bit Check_Acknowledge(void); 
void Write_Byte(uchar b)reentrant; 
bit Write_N_Bytes(uchar *buffer,uchar n)reentrant; 
bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer); 
uchar Read_Byte(void)reentrant; 
*/ 

#include<string.h> 
#include<reg52.h> 
#include<intrins.h> 
#include"aiic_51.h" 

sbit SCL=P1^6; 
sbit SDA=P1^7; 

void DELAY(uint t) 

while(t!=0) 
t--; 

void IIC_Start(void) 

//启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变 
SDA=1; 
SCL=1; 
DELAY(DELAY_TIME); 
SDA=0; 
DELAY(DELAY_TIME); 
SCL=0; 
DELAY(DELAY_TIME); 

void IIC_Stop(void) 

//终止I2C总线,当SCL为高电平时使SDA产生一个正跳变 
SDA=0; 
SCL=1; 
DELAY(DELAY_TIME); 
SDA=1; 
DELAY(DELAY_TIME); 
SCL=0; 
DELAY(DELAY_TIME); 

void SEND_0(void) 

//发送0,在SCL为高电平时使SDA信号为低 
SDA=0; 
SCL=1; 
DELAY(DELAY_TIME); 
SCL=0; 
DELAY(DELAY_TIME); 

void SEND_1(void) 

//发送1,在SCL为高电平时使SDA信号为高 
SDA=1; 
SCL=1; 
DELAY(DELAY_TIME); 
SCL=0; 
DELAY(DELAY_TIME); 

bit Check_Acknowledge(void) 

//发送完一个字节后检验设备的应答信号 
SDA=1; 
SCL=1; 
DELAY(DELAY_TIME/2); 
F0=SDA; 
DELAY(DELAY_TIME/2); 
SCL=0; 
DELAY(DELAY_TIME); 
if(F0==1) 
return FALSE; 
return TRUE; 

void Write_Byte(uchar b)reentrant 

//向IIC总线写一个字节 
uchar i; 
for(i=0;i<8;i++) 
if((b<<i)&0x80) 
SEND_1(); 
else 
SEND_0(); 

bit Write_N_Bytes(uchar *buffer,uchar n)reentrant 

//向I2C总线写n个字节 
uchar i; 
IIC_Start(); 

for(i=0;i<n;i++) 

Write_Byte(buffer[i]); 
if(!Check_Acknowledge()) 

IIC_Stop(); 
return(i==n); 

IIC_Stop(); 
return TRUE; 

uchar Read_Byte(void)reentrant 

//从I2C总线读一个字节 
uchar b=0,i; 
for(i=0;i<8;i++) 

SDA=1; //释放总线 
SCL=1; //接受数据 
DELAY(10); 
F0=SDA; 
DELAY(10); 
SCL=0; 
if(F0==1) 

b=b<<1; 
b=b|0x01; 

else 
b=b<<1; 

return b; 

bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer) 

//从I2C总线读n个字节 
uchar i; 
IIC_Start(); 
Write_Byte(SlaveAdr); //向总线发送接收器地址 
if(!Check_Acknowledge()) //等待接收器应答信号 
return FALSE; 
for(i=0;i<n;i++) 

buffer[i]=Read_Byte(); 
if(i!=n) 
SEND_0(); //发送应答 
else 
SEND_1(); //发送非应答 

IIC_Stop(); 
return TRUE; 



  
上一篇:32位嵌入式开发的发展和动向分析
下一篇:PCB布线原则

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料