📄 fm24c16.c
字号:
#include <reg51f.h>
#include <intrins.h>
#include <string.h>
#include <absacc.h>
#define IIC_READ 0xA1 //定义读指令
#define IIC_WRITE 0xA0 //定义写指令
#define uchar unsigned char //宏定义
#define uint unsigned int ///宏定义
#define SomeNOP(); _nop_();_nop_();_nop_();_nop_();
sbit SDA=P0^1; //I2C2数据传送位
sbit SCL=P0^2; //I2C2时钟控制位
sbit WP=P0^3; //eerom掉电写保护
bit ack; //应答标志位
/***************************起动总线函数***************************
函数原型: void Start_I2c();
功能描述: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void Start_I2c()
{
EA=0; //关中断
WP = 0; //关写保护
SomeNOP(); //待高电平稳定
SDA=1; //发送起始条件的数据信号
SCL=1;
SomeNOP(); //待高电平稳定
SDA=0; //发送起始信号
SomeNOP();
SCL=0; //钳住I2C总线,准备发送或接收数据
}
/******************************结束总线函数**************************
函数原型: void Stop_I2c();
功能描述: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void Stop_I2c()
{
SCL=0;
SDA=0; //发送结束条件的数据信号
SomeNOP();
SCL=1; //发送结束条件的时钟信号
SomeNOP();
SDA=1; //发送I2C总线结束信号
WP = 1; //写保护
SomeNOP(); //待高电平稳定
EA=1; //开中断
}
/********************************应答子函数***************************
函数原型: void Ack_I2c(bit a);
功能描述: 主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)
SDA=0; //在此发出应答或非应答信号
else
SDA=1;
SCL=1;
SCL=0; //清时钟线,钳住I2C总线以便继续接收
}
/****************************字节数据发送函数*************************
函数原型: void SendByte(uchar c);
功能描述: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
{
if((c<<BitCnt)&0x80)SDA=1; //判断发送位
else SDA=0;
SCL=1; //置时钟线为高,通知被控器开始接收数据位
SCL=0;
}
SDA=1; //8位发送完后释放数据线,准备接收应答位
SCL=1;
if(SDA==1)ack=0;
else ack=1; //判断是否接收到应答信号,如果正确第九个sda为零
SCL=0;
}
/******************************单个字节数据接收函数 *************************************
函数原型: uchar RcvByte();
功能描述: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数应答从机。
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; //置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL=0; //置时钟线为低,准备接收数据位
SCL=1; //置时钟线为高使数据线上数据有效
retc=retc<<1;
if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中
}
SCL=0;
return(retc);
}
/************************向有子地址器件发送字节数据函数*******************
函数原型: bit ISendByte(uchar sla,uchar c);
功能描述: 从启动总线到发送命令,地址,数据,结束总线的全过程,器件子地址sbua.
如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit ISendByte(uint suba,uchar c) //写字节
{
uchar temp,tempw;
temp=(uchar)(suba>>8); //temp=0 0 0 0 0 a10 a9 a8
tempw=(IIC_WRITE|(temp<<1)); //tempw=1 0 1 0 a10 a9 a8 0
Start_I2c(); //启动总线
SendByte(tempw); //发送命令
if(ack==0)return(0);
SendByte((uchar)suba); //发送地址
if(ack==0)return(0);
SendByte(c); //发送数据
if(ack==0)return(0);
Stop_I2c(); //结束总线
return(1);
}
/****************向有子地址器件发送多字节数据函数*******************
函数原型: bit ISendStr(uchar suba,uchar *s,uchar no);
功能: 从启动总线到发送命令,子地址,数据,结束总线的全过程
如果返回1表示操作成功,否则操作有误。
注意: 使用前必须已结束总线。
********************************************************************/
bit ISendStr(uint suba,uchar *s,uchar no)
{
uchar i;
uchar temp,tempw;
temp=(uchar)(suba>>8); //temp=0 0 0 0 0 a10 a9 a8
tempw=(IIC_WRITE|(temp<<1));//tempw=1 0 1 0 a10 a9 a8 0
Start_I2c(); //启动总线
SendByte(tempw); //发送命令
if(ack==0)return(0);
SendByte((uchar)suba); //发送器件子地址
if(ack==0)return(0);
for(i=0;i<no;i++)
{
SendByte(*s); //发送数据
if(ack==0)return(0);
s++;
}
Stop_I2c(); //结束总线
return(1);
}
/***********************向有子地址器件读字节数据函数 **************
函数原型: bit IRcvByte(uchar sbua ,ucahr *c);
功能描述 : 从启动总线到发送命令,地址,读数据,结束总线的全过程,器件子地
址sbua ,返回值在c.
如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit IRcvByte(uint sbua,uchar *c) //读字节
{
uchar temp,tempw,tempr;
temp=(uchar)(sbua>>8); //temp=0 0 0 0 0 a10 a9 a8
tempw=(IIC_WRITE|(temp<<1)); //tempw=1 0 1 0 a10 a9 a8 0
tempr=(IIC_READ|(temp<<1)); //tempr=1 0 1 0 a10 a9 a8 1
Start_I2c(); //启动总线
SendByte(tempw); //写命令
if(ack==0)return(0);
SendByte((uchar)sbua); //写地址
if(ack==0)return(0);
Start_I2c(); //重新启动总线
SendByte(tempr); //读命令
if(ack==0)return(0);
*c=RcvByte(); //读取数据
Ack_I2c(1); //发送非就答位
Stop_I2c(); //结束总线
return(1);
}
/*********************向有子地址器件读取多字节数据函数 **********************************************
函数原型: bit ISendStr(uchar suba,uchar *s,uchar no);
功能描述: 从启动总线到发送命令,子地址,读数据,结束总线的全过程,
如果返回1表示操作成功,否则操作有误。
********************************************************************/
bit IRcvStr(uint suba,uchar *s,uchar no)
{
uchar i;
uchar temp,tempw,tempr;
temp=(uchar)(suba>>8); //temp=0 0 0 0 0 a10 a9 a8
tempw=(IIC_WRITE|(temp<<1)); //tempw=1 0 1 0 a10 a9 a8 0
tempr=(IIC_READ|(temp<<1)); //tempr=1 0 1 0 a10 a9 a8 1
Start_I2c(); //启动总线
SendByte(tempw); //写命令
if(ack==0)return(0);
SendByte((uchar)suba); //写地址
if(ack==0)return(0);
Start_I2c(); //重新启动总线
SendByte(tempr);
if(ack==0)return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte(); //发送数据
Ack_I2c(0); //发送就答位
s++;
}
*s=RcvByte();
Ack_I2c(1); //发送非应位
Stop_I2c(); //结束总线
return(1);
}
/*******************
void main(void)
{
while(1)
{
//uchar a[4]={0xed,0xaa,0x55,0xcc};
uchar a[4]={0xDc,0x55,0xaa,0xed};
uchar d=0xAa;
ISendStr(0x400,a,4);
IRcvStr(0x400,b,4);
ISendByte(0x300,d);
IRcvByte(0x300,c);
IRcvStr(0x400,b1,4);
}
}
**********************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -