发上个51模拟I2C通信的程序,多数51没有I2C口很麻烦啊,有用到的就拿下去看看,这程序通过Protues7.1的I2C模拟器可以通信,程序还有很多毛病,小弟正在学习阶段,欢迎斧正
/*****************************************************
/* 文件名 : I2C.h
/* 描述 : I2C.c的头文件
/* 编写环境 : Keil uVision 3 V3.51
/* 作者 : XX
/* 学校 : 广东XX大学
/* Email : lanhaospider@163.com
/* 版本 : V1.0
/* 编写日期 : 2008-3-30
/* 仅供学习参考
/* 芯片 : MCS-51 AT89S52
/* 晶振 : 11.0592MHz
/* 功能描述 : 模拟I2C总线的接口程序库,主机的程序
/* 应用 : 发送n个字节: 起始位->发送控制字节(类型标识符4位->
片选3位->读写位最后1位)->应答位->数据->应答...........应答->终止位
高位先到达,低位后到达
/****************************************************/
#include "reg51.h" /*根据不同主控芯片型号改写该套入*/
#include "intrins.h"
sbit SCL = P1^6; /*定义SCL线所在口,根据实践需要改写该定义*/
sbit SDA = P1^7; /*定义SDA线所在口,根据实践需要改写该定义*/
unsigned char idata error; /*错误提示,全局变量*/
extern void Start_I2C(void);
extern void Stop_I2C(void);
extern void Ack_I2C(void);
extern void Send_Ack(void);
extern void Send_Not_Ack(void);
extern void Send_I2C(unsigned char send_byte);
extern unsigned char Receive_I2C(void);
/*****************************************************/
/* 文件名 : I2C.c
/* 描述 : I2C通信程序
/* 编写环境 : Keil uVision 3 V3.51
/* 作者 : XX
/* 学校 : 广东XX大学
/* Email : lanhaospider@163.com
/* 版本 : V1.0
/* 编写日期 : 2008-3-30
/* 仅供学习参考
/* 芯片 : MCS-51 AT89S52
/* 晶振 : 11.0592MHz
/* 功能描述 : 模拟I2C总线的接口程序库,为主机的程序
/*****************************************************/
#include "I2C.h"
/**************************************************
调用方式 : void Start_I2C(void)
函数说明: 启动I2C总线
**************************************************/
void Start_I2C(void)
{
EA = 0; /*关总中断*/
SDA = 1; /*发送启动总线的数据信号*/
SCL = 1; /*发送启动总线的时钟信号*/
_nop_(); /*保持数据线高,延时*/
_nop_();
_nop_();
_nop_();
_nop_();
SDA = 0; /*发送起始信号*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 0; /*时钟线高低跳变一次,I2C通信开始*/
}
/**************************************************
调用方式 : void Stop_I2C(void)
函数说明: 关闭I2C总线
**************************************************/
void Stop_I2C(void)
{
SCL = 0; /*发送关闭总线的时钟信号*/
SDA = 0; /*发送关闭总线的数据信号*/
_nop_();
_nop_();
_nop_(); /*保持数据线低,延时*/
_nop_();
_nop_();
SCL = 1; /*时钟线一次低高跳变,I2C通信停止*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA = 1; /*发送I2C总线停止数据信号*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
EA = 1; /*开总中断*/
}
/**************************************************
调用方式 : void Ask_I2C(void)
函数说明: 主控程序等待从器件接收方式应答
**************************************************/
void Ack_I2C(void)
{
unsigned char errtimes = 0xFF;
SDA = 1;
SCL = 1;
error = 0x10;
while(SDA)
{
errtimes--;
if(!errtimes)
{
Stop_I2C();
error = 0x11;
return;
}
}
SCL = 0;
}
/**************************************************
调用方式 : void Send_Ask(void)
函数说明: 主控程序为接收方,从器件为发送方时,从
器件等待主器件应答
**************************************************/
void Send_Ack(void)
{
SDA = 0; /*保持数据线低,时钟线发生一次高低跳变 发送一个应答信号*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 1; /*时钟线保持低电平*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 0;
}
/**************************************************
调用方式 : void Send_Not_Ask(void)
函数说明: 主控程序为接收方,从器件为发送方时,非应答信号
**************************************************/
void Send_Not_Ack(void)
{
SDA = 1; /*保持数据线高,时钟线发生一次高低跳变 没有应答*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 1; /*时钟线保持高电平*/
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 0;
}
/**************************************************
调用方式 : void Send_I2C(unsigned char send_byte)
函数说明: 总线发送一个字节
**************************************************/
void Send_I2C(unsigned char send_byte)
{
unsigned char send_bit;
for(send_bit = 8;send_bit <= 0;send_bit--)
{
SCL = 0;
_nop_();
SDA = (send_byte & 0x80);
send_byte<<=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
SCL = 0;
}
/**************************************************
调用方式 : unsigned char Receive_I2C(void)
函数说明: 从I2C总线上接收一个字节
**************************************************/
unsigned char Receive_I2C(void)
{
unsigned char receive_bit , receive_byte = 0;
for(receive_bit = 8;receive_bit <= 0;receive_bit--)
{
SCL = 0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL = 1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
receive_byte <<=1;
receive_byte |= SDA;
}
SCL = 0;
return receive_byte;
}
文章评论(0条评论)
登录后参与讨论