📄 i2c.c
字号:
//*******************************************************
// 文件名:I2C.c
// 创建人: ZFZ
// 建立时间: 2008-6-6
// 版本描 述: STIV8.0.0
// 文件描述:标准80C51单片机模拟I2C总线的主机程序
// 功能描述:
// 备注:本程序仅供学习参考,版权归江西新和公司所有,勿用于商业目的
// 最后修改时间:
//*******************************************************
#include <C8051F340.h>
#include <intrins.h>
#include "I2C.h"
/*---------------------------------------------
函数名:Romdelay
功 能:24C512的延时
参 数:uint x
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void Romdelay(unsigned int x)
{
unsigned int i;
for(i=0;i<x;i++);
}
/*---------------------------------------------
函数名: sta
功 能:24C512起始条件
参 数:无
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void sta(void)
{
SDA=1; //SCL为高时,SDA的下降延开始
Romdelay(50);
//_nop_();
SCL=1;
while(SCL==0)
{;}
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
SDA=0;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
SCL=0;
//_nop_();
//_nop_();
Romdelay(100);
}
/*---------------------------------------------
函数名:stop
功 能:24C512停止
参 数:无
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void stop(void)
{
SDA=0; //SCL为高时,SDA的上升延停止
SCL=1;
while(SCL==0)
{;}
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
SDA=1;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
}
/*---------------------------------------------
函数名:wrbyt
功 能:向EEPROM写一个字节函数
参 数:uchar shu
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void wrbyt(unsigned char shu)
{
unsigned char i;
for(i=0;i<8;i++)
{
SDA=((shu&0x80)>0)?1:0; //取数据最高位,先传高再低
Romdelay(100);
//_nop_();
SCL=1;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
SCL=0; //SDA上的数据只有在SCL为低时才能改变
Romdelay(100);
//_nop_();
shu<<=1; //数据左移一位
}
}
/*---------------------------------------------
函数名:rdbyt
功 能:从EEPROM读一个字节
参 数:无
返回值:uchar nn
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
unsigned char rdbyt(void)
{
unsigned char nn=0xff;
unsigned char j;
for(j=0;j<8;j++)
{
SDA=1;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
SCL=1;
if(SDA==0)
{
nn<<=1;
nn=(nn&0xfe);
SCL=0;
}
else
{
nn<<=1;
nn=(nn|0x01);
SCL=0;
}
}
return(nn);
}
/*---------------------------------------------
函数名:mack
功 能:
参 数:无
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void mack(void)
{
SDA=0;
SCL=1;
Romdelay(100);
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
SCL=0;
SDA=1;
}
/*---------------------------------------------
函数名:mnack
功 能:
参 数:无
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void mnack(void)
{
SDA=1;
SCL=1;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
SCL=0;
SDA=0;
}
/*---------------------------------------------
函数名:cack
功 能:返回应答信号
参 数:无
返回值:F0(0或1)
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
bit cack(void)
{
bit F0;
//_nop_();
//_nop_();
//_nop_();
Romdelay(50);
SDA=1;
//_nop_();
//_nop_();
//_nop_();
Romdelay(50);
SCL=1;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(200);
F0=(SDA==0)?0:1;
SCL=0;
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
//_nop_();
Romdelay(100);
return(F0);
}
/*---------------------------------------------
函数名:rdnbyt
功 能:从EEPROM读出一个数组函数
参 数:unsigned int SubAddr,unsigned char number,unsigned char qq[]
返回值:unsigned char qq[]
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void rdnbyt(unsigned int SubAddr,unsigned char number,unsigned char qq[])
{
unsigned char l;
unsigned char addh,addl;
bit cflag=0;
addh = SubAddr / 0x100;
addl = SubAddr % 0x100;
sta();
wrbyt(0xA0);
cflag=cack();
wrbyt(addh);
cflag=cack();
wrbyt(addl);
cflag=cack();
sta();
wrbyt(0xA1); //写命令字(读)
cflag=cack();
for(l=0;l<number;l++)
{
qq[l]=rdbyt();
if(l<(number-1))
{
mack();
}
Romdelay(100);
}
mnack();
Romdelay(100);
stop();
Romdelay(2000);
}
/*---------------------------------------------
函数名:wrnbyt
功 能:向EEPROM写一个数组
参 数:unsigned int SubAddr,unsigned char number,unsigned char ff[]
返回值:无
修改记录
----------------------------------------------
日期 作者 内容
---------------------------------------------*/
void wrnbyt(unsigned int SubAddr,unsigned char number,unsigned char ff[])
{
unsigned char k;
unsigned char addh,addl;
bit cflag=0;
addh = SubAddr / 0x100;
addl = SubAddr % 0x100;
for (k=0;k<number;k++)
{
if ((k==0) || (addl==0)||(addl==128)) //页边界处理。
{
sta(); //开始
wrbyt(0xA0); //写命令字(写)1010(000)0
cflag=cack();
wrbyt(addh);
cflag=cack();
wrbyt(addl);
cflag=cack();
}
wrbyt(ff[k]);
cflag=cack(); //接收应答信号
Romdelay(100); //延时
addl=addl+1;
if((addl==128)||(addl==0))
{
addh=(addl==0)?(addh+1):addh;
stop();
Romdelay(2000); //延时
}
}
Romdelay(200); //延时
stop(); //停止
Romdelay(2000); //延时
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -