📄 eeprom.c
字号:
// 24LC256的应用编程
// 该程序实现DSP2407与EEPROM芯片24LC256的接口编程
#include "register.h"
int source[4]={3,3,3,3};
int result[4];
int n,control;
// 系统初始化子程序
void sysinitial()
{
asm( " setc INTM "); // 关闭总中断
asm( " clrc SXM ") ; // 抑制符号扩展
asm( " clrc OVM ") ; // 累加器结果正常溢出
asm( " clrc CNF ") ; // B0被配置为数据空间
SCSR1=0x81FE; // CLKIN=6M,CLKOUT=24M
WDCR=0x0E8; // 不使能看门狗
IMR=0x00; // 禁止所有中断
WSGR=0x0FFFF; // 不使能所有的等待状态
}
// IO口初始化子程序
void ioinitial()
{
// 选择定义IOPD0,IOPA2,IOPE0为通用I/O口
MCRA=MCRA&0xfffb;
MCRB=MCRB&0xfeff;
MCRC=MCRC&0xfffe;
PADATDIR=PADATDIR|0x0400; // IOPA2为输出
PDDATDIR=PDDATDIR|0x0100; // IOPD0为输出,且写允许
}
// 启动I2C总线子程序
void I2CStart()
{
int k;
// SCL=0
PADATDIR=PADATDIR&0xfffb;
// IOPE0(SDA为输出)
PEDATDIR=PEDATDIR|0x0100;
// SDA=SCL=1
PEDATDIR=PEDATDIR|0x0001;
PADATDIR=PADATDIR|0x0004;
for(k=8;k>=0;k--) { k=k;} // 软件延时600ns
// SDA=0
PEDATDIR=PEDATDIR&0xfffe;
for(k=8;k>=0;k--) { k=k;} // 软件延时600ns
// SCL=0
PADATDIR=PADATDIR&0xfffb;
for(k=18;k>=0;k--) { k=k;} // 软件延时1400ns
// SDA=1
PEDATDIR=PEDATDIR|0x0001;
}
// 向I2C总线写入数据子程序
void I2CSendByte(int data)
{
int flag,sz,k; // 定义局部寄存器
// 设置IOPE0为输出口
PEDATDIR=PEDATDIR|0x0100;
for(flag=0x0080;flag!=0x00;flag=flag/2)
{
// SCL=0
PADATDIR=PADATDIR&0xfffb;
for(k=0x06;k>=0;k--) { k=k;}
sz=data&flag; // 屏蔽掉相应的位
if(sz==0)
// 如果相应的位为0,则SDA=0
PEDATDIR=PEDATDIR&0xfffe;
else
// 如果相应的位为1,则SDA=1
PEDATDIR=PEDATDIR|0x0001;
// SCL=1,在SCL=1期间数据线上的状态必须保持不变
PADATDIR=PADATDIR|0x0004;
for(k=0x016;k>=0;k--) { k=k;}
}
// SCL=0
PADATDIR=PADATDIR&0xfffb;
}
// 检查应答位子程序
int I2CRECACK()
{
int k;
// SCL=0
PADATDIR=PADATDIR&0xfffb;
for(k=16;k>=0;k--) { k=k;} // 软件延时600ns
// SCL=1,在SCL=1期间数据线上的状态必须保
PADATDIR=PADATDIR|0x0004;
// 持不变
for(k=3;k>=0;k--) { k=k; } // 软件延时600ns
// IOPE0(SDA为输入)
PEDATDIR=PEDATDIR&0xfeff;
for(k=3;k>=0;k--) { k=k; } // 软件延时600ns
// SCL=0
PADATDIR=PADATDIR&0xfffb;
k=PEDATDIR&0x01; // k值存储应答位,若K=0,则表示操作成功;
// 若k=1,则表示操作失败
return(k);
}
// 从I2C总线读取数据
int I2CRecByte()
{
int k=0;
int flag;
int sz;
// IOPC0(SDA为输入)
PEDATDIR=PEDATDIR&0xfeff;
// SCL=0
PADATDIR=PADATDIR&0xfffb;
for(flag=0x0080;flag!=0x00;flag=flag/2)
{
// SCL=1
PADATDIR=PADATDIR|0x0004;
sz=PEDATDIR&flag; // 取得应该读取的相应位
if(sz==flag) k=k|flag; // 若读取的相应位为1,则k值的相应位置1
PADATDIR=PADATDIR&0x0fffb; // SCL=0
}
return(k);
}
// 对I2C总线产生应答
void I2CAck()
{
int k;
PEDATDIR=PEDATDIR|0x0100; // 设置IOPE0为输出口
PEDATDIR=PEDATDIR&0x0FFFE; // SDA=0
for(k=3;k>0;k--) { k=k;} // 软件延时
PADATDIR=PADATDIR|0x0004; // SCL=1
for(k=7;k>0;k--) { k=k;} // 软件延时
PADATDIR=PADATDIR&0x0FFFb; // SCL=0
PEDATDIR=PEDATDIR|0x0001; // SDA=1,数据线恢复为1,但此时SCL=0,SDA在
// 后来可以改变
}
// 不对I2C总线产生应答
void I2CNoAck()
{
PEDATDIR=PEDATDIR|0x0100; // 设置IOPE0为输出口
PEDATDIR=PEDATDIR|0x0001; // SDA=1
PADATDIR=PADATDIR|0x0004; // SCL=1
PADATDIR=PADATDIR&0x0FFFb; // SCL=0
}
// 停止I2C总线
void I2CStop()
{
int k;
PADATDIR=PADATDIR&0x0FFFb; // SCL=0
PEDATDIR=PEDATDIR|0x0100; // 设置IOPE0为输出口
PEDATDIR=PEDATDIR&0x0FFFE; // SDA=0
PADATDIR=PADATDIR|0x0004; // SCL=1
for(k=7;k>0;k--) { k=k;} // 软件延时
PEDATDIR=PEDATDIR|0x0001; // SDA=1
for(k=7;k>0;k--) { k=k;} // 软件延时
PADATDIR=PADATDIR&0x0FFFb; // SCL=0
}
// 读数据子程序
int read(array,control,n)
int *array,control,n;
{
int dat;
I2CStart(); // 设置I2C总线的开始状态
I2CSendByte(control); // 送出控制字节(R/W=1)
dat=I2CRECACK(); // 检查应答位
if(dat==0){
for(;n!=1;n--,array++) {
dat=I2CRecByte(); // 读取一个字节的数据
I2CAck(); // 产生应答信号
*array=dat; // 把读取的数据存入数组
}
dat=I2CRecByte(); // 接收最后一个字节的数据
I2CNoAck(); // 不产生应答信号
*array=dat; // 把读取的数据存入数组
dat=0x00; // dat值赋0,表示前面的操作成功
}
return(dat);
}
// 写数据子程序
int write(array,control,n)
int *array,control,n;
{
int dat;
PDDATDIR=PDDATDIR&0x0FFFE; // 设置写允许,WP=0
for(;n!=0;n--,array++) {
I2CSendByte(*array); // 写出一个字节数据
dat=I2CRECACK();
if(dat==1) break; // 如果无应答位,则写数据失败,终止写操作
}
PDDATDIR=PDDATDIR|0x0001; // 写操作完成,设置写保护:WP=1
return(dat);
}
// 通用读写24LC256子程序,入口参数为输入/输出缓冲区首地址array,
// 24LC256的块内地址adress,控制字节control,需要读写的字节数n
int EEPROM(array,adress,control,n)
int *array,adress,control,n;
{
int dat;
I2CStart(); // 设置I2C总线的开始状态
dat=control&0x0FFFE; // 清除控制字节的第0位
I2CSendByte(dat); // 送出控制字节(R/W=0)
dat=I2CRECACK(); // 检查应答位
if(dat==0) {
dat=adress&0x0FF00;
dat=dat>>8; // dat=24LC256的块内地址的高字节
I2CSendByte(dat); // 送出24LC256的块内地址的高字节
dat=I2CRECACK(); // 检查应答位
if(dat==0) {
dat=adress&0x00FF;
I2CSendByte(dat); // 送出24LC256的块内地址的低字节
dat=I2CRECACK(); // 检查应答位
if(dat==0) {
dat=control&0x0001;
switch(dat) {
case 1 :dat=read(array,control,n);break;// 调用读数据子程序
case 0 :dat=write(array,control,n);break;// 调用写数据子程序
}
}
}
}
I2CStop();
return(dat); // 返回一个状态字,以确定操作是否成功
}
// 主程序
main()
{
int k;
sysinitial(); // 系统初始化
ioinitial(); // io端口初始化
while(1) {
k=EEPROM(source,0x0000,0x00A0,4);
if(k==0) break;
} // 如果写入成功,则终止写操作,否则继续写
for(k=0x20;k>0;k--) { k=k;}
while(1) {
k=EEPROM(result,0x00,0x00A1,4);
if(k==0) break; // 如果读出成功,则终止读操作,否则继续读
}
}
// 直接返回中断服务子程序
void interrupt nothing()
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -