微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机I2C总线协议的实现

51单片机I2C总线协议的实现

时间:11-27 来源:互联网 点击:
//-----------------------函数声明,变量定义-------------------------------------------------------

#include

#include

sbit SDA=P1^0;// 将p1.0口模拟数据口

sbit SCL=P1^1;// 将p1.1口模拟时钟口

#define NUM 10 // 接收和发送缓存区的深度

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

unsignedcharidata sendbuf[NUM];// 数据发送缓冲区

unsignedcharidata receivebuf[NUM];// 数据接收缓冲区

bit bdata SystemError;// 从机错误标志位

//------------------------------------------------------------------------------------------------

// 函数名称: iic_start()

// 函数功能: 启动I2C总线子程序

//------------------------------------------------------------------------------------------------

voidiic_start(void)

{ EA=0;//时钟保持高,数据线从高到低一次跳变,I2C通信开始

SDA = 1;

SCL = 1;

delayNOP();// 延时5us

SDA = 0;

delayNOP();

SCL = 0;

}

//------------------------------------------------------------------------------------------------

// 函数名称: iic_stop()

// 函数功能: 停止I2C总线数据传送子程序

//------------------------------------------------------------------------------------------------

voidiic_stop(void)

{

SDA = 0;//时钟保持高,数据线从低到高一次跳变,I2C通信停止

SCL = 1;

delayNOP();

SDA = 1;

delayNOP();

SCL = 0;

}

//------------------------------------------------------------------------------------------------

// 函数名称: slave_ACK

// 函数功能: 从机发送应答位子程序

//------------------------------------------------------------------------------------------------

voidslave_ACK(void)

{

SDA = 0;

SCL = 1;

delayNOP();

SDA = 1;

SCL = 0;

}

//------------------------------------------------------------------------------------------------

// 函数名称: slave_NOACK

// 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束

//------------------------------------------------------------------------------------------------

voidslave_NOACK(void)

{

SDA = 1;

SCL = 1;

delayNOP();

SDA = 0;

SCL = 0;

}

//------------------------------------------------------------------------------------------------

// 函数名称: check_ACK

// 函数功能: 主机应答位检查子程序,迫使数据传输过程结束

//------------------------------------------------------------------------------------------------

voidcheck_ACK(void)

{

SDA = 1;// 将p1.0设置成输入,必须先向端口写1

SCL = 1;

F0 = 0;

if(SDA == 1)// 若SDA=1表明非应答,置位非应答标志F0

F0 = 1;

SCL = 0;

}

//-----------------------------------------------------------------------------------------------

// 函数名称: IICSendByte

// 入口参数: ch

// 函数功能: 发送一个字节

//------------------------------------------------------------------------------------------------

voidIICSendByte(unsignedcharch)

{

unsignedcharidata n=8;// 向SDA上发送一位数据字节,共八位

while(n--)

{

if((ch&0x80) == 0x80)// 若要发送的数据最高位为1则发送位1

{

SDA = 1;// 传送位1

SCL = 1;

delayNOP();

SDA = 0;

SCL = 0;

}

else

{

SDA = 0;// 否则传送位0

SCL = 1;

delayNOP();

SCL = 0;

}

ch = ch<1;// 数据左移一位

}

}

//------------------------------------------------------------------------------------------------

// 函数名称: IICreceiveByte

// 返回接收的数据

// 函数功能: 接收一字节子程序

//------------------------------------------------------------------------------------------------

unsignedcharIICreceiveByte(void)

{

unsignedcharidata n=8;// 从SDA线上读取一上数据字节,共八位

unsignedchartdata;

while(n--)

{

SDA = 1;

SCL = 1;

tdata = tdata<1;// 左移一位,或_crol_(temp,1)

if(SDA == 1)

tdata = tdata|0x01;// 若接收到的位为1,则数据的最后一位置1

else

tdata = tdata&0xfe;// 否则数据的最后一位置0

SCL=0;

}

return(tdata);

}

//------------------------------------------------------------------------------------------------

// 函数名称: writeNbyte

// 入口参数: slave_add从机地址,n要发送的数据个数

// 函数功能: 发送n位数据子程序

//----------

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top