📄 eeprom.c
字号:
#include "register.h"
int source[4]={0x2233,0x4455,0x4455,0x5566};
int result[4];
int n,control,control1;
//系统初始化子程序
void sysinitial()
{
asm(" setc INTM");//关闭总中断
asm(" clrc OVM");//累加器结果正常溢出
asm(" clrc CNF");//B0被设置成数据空间
SCSR1=0X81FE;//CLKIN=10M,CLKOUT=20M
WDCR=0X0E8;//不使能看门狗
IMR=0X00;//禁止所有中断
WSGR=0X0FFFF;//不使能所有的等待状态
}
//I/O初始化子程序
void ioinitial()
{
MCRC=MCRC&0X8FFF;//定义IOPF4、IOPF5、IOPF6为通用I/O口
PFDATDIR=PFDATDIR|0X3000;//IOPF5为输出,IOPF4为输出,且写允许
}
//延时子程序
void delay(int x)
{ int count;
for(count=0;count<x;count++)
;
}
//启动I2C总线子程序
void I2CStart()
{
PFDATDIR=PFDATDIR|0X0060;//SDA=SCL=1
delay(72);//延时
PFDATDIR=PFDATDIR&0x0FFBF;//SDA=0
delay(72);//延时
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
delay(24);//延时
}
//向I2C总线写入数据子程序
void I2CSendByte(unsigned int data)
{
int flag,sz,k;
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
delay(72);//延时
PFDATDIR=PFDATDIR|0X4000;//定义IOPF6为输出
for(flag=0x0080;flag!=0X00;flag=flag>>1)
{
sz=data&flag;//保留相应位
if(sz==0)PFDATDIR=PFDATDIR&0x0FFBF;//如果相应的位为0,则SDA=0;
else PFDATDIR=PFDATDIR|0x0040;//如果相应的位为1,则SDA=1;
delay(72);//延时
PFDATDIR=PFDATDIR|0X0020;//SCL=1
delay(72);//延时
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
delay(24);//延时
}
}
//检查应答位子程序(24LC256的应答)
int I2CRECACK()
{
int k;
PFDATDIR=PFDATDIR|0x0040;//SDA=1
delay(24);//延时
PFDATDIR=PFDATDIR&0x0BFFF;//SDA为输入
delay(24);//延时
PFDATDIR=PFDATDIR|0X0020;//SCL=1
delay(24);//延时
if(PFDATDIR&0x0040)
k=1;
else k=0;
PFDATDIR=(PFDATDIR|0X4000)&0XFF9F;/*SDA设为输出,SDA=0,SCL=0*/
delay(24); //后来加的!!!!
return(k);
}
//从I2C总线读取数据子程序
int I2CRecByte()
{
int k,flag,sz,kk=0x0000;
PFDATDIR=PFDATDIR&0x0BFFF;//SDA为输入
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
delay(72);
for(flag=0x080;flag!=0;flag=flag>>1)
{
PFDATDIR=PFDATDIR|0X0020;//SCL=1
delay(72);//延时
sz=PFDATDIR&0X0040;//读取SDA的值
if(sz==0) kk=kk;//若SDA=0,在相应的
else kk=kk|flag;//若SDA=1,在相应的数据位加数据位加0
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
delay(72); //延时
}
PFDATDIR=PFDATDIR|0X4000; //SDA为输出
delay(24); //延时
return(kk);
}
//对I2C总线产生应答(LF2407)
void I2CAck()
{
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
PFDATDIR=PFDATDIR&0x0FFBF;//SDA=0
PFDATDIR=PFDATDIR|0X0020;//SCL=1
delay(24);//延时
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
// delay(20);//延时
}
//不对I2C总线产生应答
void I2CNoAck()
{
PFDATDIR=PFDATDIR|0X0020;//SCL=1
delay(24);//延时
PFDATDIR=PFDATDIR&0x0FFDF;//SCL=0
delay(24);//延时
}
//停止I2C总线
void I2CStop()
{
PFDATDIR=PFDATDIR&0x0FFBF;//SDA=0
delay(24);//延时
PFDATDIR=PFDATDIR|0X0020;//SCL=1
delay(24);//延时
PFDATDIR=PFDATDIR|0x0040;//SDA=1
delay(24);//延时
}
//通用写24LC256子程序,入口参数为输入/输出缓冲区首地址array,
//24LC256的块内地址adress,控制字节control,需要读写的字节数n
int EEPROM_WR(int adress,int *array,int control,int n)
{
int dat,k;
PFDATDIR=PFDATDIR&0x0FFEF;//设置写允许,WP=0
I2CStart();//启动I2C
I2CSendByte(control);//送出写控制字
dat=I2CRECACK();//检查应答位
/* if(dat==0)I2CSendByte((page>>8)&0xff);//若应答正确,送页数的高8位
dat=I2CRECACK(); //检查应答位
if(dat==0)I2CSendByte(page&0xff);//若应答正确,送页数的低8位
dat=I2CRECACK();//检查应答位 */
if(dat==0)I2CSendByte((adress>>8)&0x00FF);//若应答正确,送地址的高8位
dat=I2CRECACK();//检查应答位
if(dat==0)I2CSendByte(adress&0x00FF);//若应答正确,送地址的低8位
dat=I2CRECACK();//检查应答位
if(dat==0) //若应答正确,送数据
{
for(k=0;k<n;k++)
{
I2CSendByte((*array>>8)&0X00FF); //送数据的高8位
dat=I2CRECACK();//检查应答位
if(dat==1)break;//应答不正确,中断
I2CSendByte(*array&0X00FF);//应答正确,送数据的低8位
dat=I2CRECACK();//检查应答位
if(dat==1)break;//应答不正确,中断
array++;
}
}
I2CStop();//停止I2C总线
return(dat);
}
//通用读24LC256子程序,入口参数为输入/输出缓冲区首地址array,
//24LC256的块内地址adress,控制字节control,需要读写的字节数n
int EEPROM_RD(int adress,int *array,int control,int control1,int n)
{
int dat,k;
I2CStart();//启动I2C
I2CSendByte(control);//送出写控制字
dat=I2CRECACK();//检查应答位
/* if(dat==0)I2CSendByte((page>>8)&0xff);//若应答正确,送页数的高8位
dat=I2CRECACK();//检查应答位
if(dat==0)I2CSendByte(page&0xff);//若应答正确,送页数的低8位
dat=I2CRECACK();//检查应答位 */
if(dat==0)I2CSendByte((adress>>8)&0x00FF);//若应答正确,送地址的高8位
dat=I2CRECACK();//检查应答位
if(dat==0)I2CSendByte(adress&0x00FF);//若应答正确,送地址的低8位
dat=I2CRECACK();//检查应答位
if(dat==0)
{
I2CStart();//应答正确,启动I2C
I2CSendByte(control1);//送读控制字
}
dat=I2CRECACK();//检查应答位
if(dat==0)//应答正确,接收数据
{
for(k=0;k<(n-1);k++)
{
dat=I2CRecByte();//接收高8位数据
*array=(dat<<8)&0xff00;//将接收到的8位数据保存为*array的高8位
I2CAck();//主机应答
dat=I2CRecByte(); //接收低8位数据
*array|=dat&0x00ff;//将接收到的8位数据保存为*array的低8位
I2CAck();//主机应答
array++;
}
dat=I2CRecByte();//接收最后一个字的高8位数据
*array=(dat<<8)&0xff00;//将接收到的8位数据保存为*array的高8位
I2CAck();//主机应答
dat=I2CRecByte();//接收最后一个字的低8位数据
*array|=dat&0x00ff;//将接收到的8位数据保存为*array的低8位
I2CNoAck();//不产生应答信号
I2CStop();//停止I2C
dat=0x00; //dat值赋0,表示前面的操作成功
}
return(dat);
}
//主程序
main()
{
int k;
sysinitial();//系统初始化
ioinitial();//IO初始化
while(1)
{
k=EEPROM_WR(0x01,source,0xA0,4);//写EEPROM
if(k==0)//如果写入成功,则进行读操作,否则继续写操作
{
delay(5800);//延时
k=EEPROM_RD(0x01,result,0xA0,0xA1,4); //读EEPROM
asm(" nop");
}
}
}
//直接返回中断服务子程序
void interrupt nothing()
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -