我课程设计使用的EEPROM型号为X24C16P(2048字节),使用的X24C16P EEPROM读写程序为AT24C02C修改来的,两者读写原理上基本一致。我先放上一个经过PROTEUS仿真的程序,可用,我课设的程序在同学电脑上,一时拿不到:#include<reg52h> //软件模拟IIC的很好的例子,理解实质即可
#include<intrinsh> //程序虽然长,但是不是很复杂,关键在于理解IIC的工作机理
#define uchar unsigned char
#define uint unsigned int
#define DELAY5US _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
sbit VSDA = P1^0;
sbit VSCL = P1^1;
sbit LED = P1^7;
uchar SLAW;
void STA() //发现:24C02C 是 256字节8位的串行EEPROM存储器芯片,注意是ROM只读的
{ //但是这个例子将0-255这些数据写入到了ROM当中,怎么写的,是烧进去的,
VSDA = 1; //这个不是很理解啊
VSCL = 1;
DELAY5US
VSDA = 0;
DELAY5US
VSCL = 0;
}
void STOP()
{
VSDA = 0;
VSCL = 1;
DELAY5US
VSDA = 1;
VSCL = 1;
DELAY5US
}
void MACK()
{
VSDA = 0;
VSCL = 1;
DELAY5US
VSCL = 0;
}
void MNACK()
{
VSDA = 1;
VSCL = 1;
DELAY5US
VSCL = 0;
}
void CACK()
{
VSDA = 1;
VSCL = 1;
F0 = 0;
if ( 1 == VSDA )
{
F0 = 1;
}
VSCL = 0;
}
void WRBYTE(uchar idata p)
{
uchar idata n = 8, temp;
temp = p;
while(n--)
{
if ( 0x80 == (temp&0x80) )
{
VSDA = 1;
VSCL = 1;
DELAY5US
VSCL = 0;
}
else
{
VSDA = 0;
VSCL = 1;
DELAY5US
VSCL = 0;
}
temp = temp<<1;
}
}
void RDBYTE(uchar idata p)
{
uchar idata n = 8, temp = 0;
while(n--)
{
VSDA = 1;
VSCL = 1;
temp = temp<<1;
if ( 1 == VSDA )
temp = temp|0x01;
else
temp = temp&0xfe;
VSCL = 0;
}
p = temp;
}
void delayMoreThan5ms()
{
uint i;
for ( i = 0; i < 1000; i++ )
{
DELAY5US
}
}
int main()
{
uchar ch, p;
uint i;
SLAW = 0xA2; //0xA0是slave write地址字节(写),A是1010是器件地址,由厂家决定
for ( i = 0; i <= 255; i++ ) //1010(A)是24C02C所属系列的器件地址
{ //0000是自己决定的,前3个0由24C02C芯片的A0A1A2决定
STA(); //最后一个0是写的意思,1则为读
p = &SLAW; //4个(器件地址),3个(引脚地址),一个(读写选择位)。
WRBYTE(p); //应答信号是关键啊
CACK(); //发送对应写, 接收对应读
if ( 1 == F0 )
{
LED = 0;
while(1)
;
}
ch = i;
p = &ch;
WRBYTE(p);
CACK();
if ( 1 == F0 )
{
LED = 0;
while(1)
;
}
WRBYTE(p);
CACK();
STOP();
delayMoreThan5ms();
}
while(1)
;
return 0;
}
/
函数名:EE_readbyte
功 能:片内EEPROM 读1字节
说 明:Read_AddrH:待写入的高地址;Read_Addr:待写入的低地址
函数执行完返回一个存放在该地址处的值
/
uchar EE_ReadByte(uchar Read_AddrH,uchar Read_Addr)
{
EEADRH = Read_AddrH; //写入高地址
EEADR = Read_Addr; //写入低地址
EECON1bitsEEPGD = 0; //访问EEPROM存储区
EECON1bitsCFGS = 0; //访问EEPROM或程序区
EECON1bitsRD = 1;
return EEDATA;
}
/
函数名:EE_writebyte
功 能:片内EEPROM 写1字节
说 明:Write_AddrH:待写入的高位地址;Write_Addr:待写入的低位地址;Write_Byte:待写入的字节
/
void EE_WriteByte(uchar Write_AddrH,uchar Write_Addr,uchar Write_Byte)
{
ClrWdt(); //喂狗
while(EECON1bitsWR);
EEADRH = Write_AddrH; //写入高地址
EEADR = Write_Addr; //写入低地址
EEDATA = Write_Byte; //写入数据
EECON1bitsEEPGD = 0; //访问EEPROM存储区
EECON1bitsCFGS = 0; //访问EEPROM或程序区
EECON1bitsWREN = 1; //充许擦写
INTCONbitsGIE = 0; //禁止所有中断
EECON2 = 0x55; //写入密钥
EECON2 = 0xaa;
EECON1bitsWR = 1; //开始写 *** 作
Nop();
Nop();
INTCONbitsGIE = 1; //开中断
EECON1bitsWREN = 0; //禁止擦写
while(EECON1bitsWR) //等待写完成
{
;
}
}
/
函数名:EE_WriteArray
功 能:写入数组数据到EEPROM
说 明:AddrH:EEPROM起始地址高字节,Addr:EEPROM起始地址低字节
WriteByte[]:待存储的数据存放数组
LenArray:待存储的数组长度
举例:存放地址0x0020---0x0029;存放数据array[10]
/
void EE_WriteArray(uchar AddrH,uchar Addr,uchar WriteArray[],uchar LenArray)
{
uchar tempH,tempL,tempByte;
uint i=0;
tempH = AddrH;
tempL = Addr;
for(i=0;i<LenArray;i++)
{
tempByte = WriteArray[i];
EE_WriteByte(tempH,tempL,tempByte);
tempL++;
}
}
/
函数名:EE_ReadArray
功 能:写入数组数据到EEPROM
说 明:AddrH:EEPROM起始地址高字节,Addr:EEPROM起始地址低字节
ReadByte[]:待存储的数据存放数组
LenArray:待存储的数组长度
举例:存放地址0x0020---0x0029;存放数据array[10]
/
void EE_ReadArray(uchar AddrH,uchar Addr,uchar ReadArray[],uchar LenArray)
{
uchar tempH,tempL,tempByte;
uint i;
tempH=AddrH;
tempL=Addr;
for(i=0;i<LenArray;i++)
{
tempByte=EE_ReadByte(tempH,tempL);
ReadArray[i]=tempByte;
tempL++;
}
}
//24c08地址为0xa0
#include <reg52h>
#define uchar unsigned char
unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char sec=0; //定义计数值,每过1秒,sec加1
unsigned int count; //定时中断次数
bit write=0; //写24C08的标志;
sbit gewei=P2^7; //个位选通定义
sbit shiwei=P2^6; //十位选通定义
/////////24C08读写驱动程序////////////////////
sbit scl=P3^4; // 24c08 SCL
sbit sda=P3^5; // 24c08 SDA
sbit K5=P1^4; //清0按键
//
void delay() //delay 5us
{ ;; }
//
void delay1(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
//
void start() //开始信号
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
//
void stop() //停止信号
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
//
void respons() //应答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
//
void init_24c08() //初始化24C02
{
sda=1;
delay();
scl=1;
delay();
}
//
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
// scl=0;
// delay();
}
scl=0;
delay();
sda=1;
delay();
}
//
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
//
void write_24c08(uchar address,uchar shuju) //给指定地址中写入数据
{
start();
write_byte(0xa0); // 最低位为0写,1读
respons();
write_byte(address);
respons();
write_byte(shuju);
respons();
stop();
}
//
uchar read_24c08(uchar address) //从24c08指定地址中读出数据
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
/////////////24C02读写驱动程序完/////////////////////
//
void LEDshow() //LED显示函数
{
P0=table[sec/10];
shiwei=0;
delay1(40);
shiwei=1;
P0=table[sec%10];
gewei=0;
delay1(40);
gewei=1;
}
//
void main(void)
{
TMOD=0x01; //定时器工作在方式1
ET0=1;
EA=1;
init_24c08(); //初始化24C08
sec=read_24c08(2);//读出保存的数据赋于sec
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //使定时器005秒中断一次
TR0=1; //开始计时
while(1)
{
LEDshow();
if(write==1) //判断计时器是否计时一秒
{
write=0; //清零
write_24c08(2,sec); //在24c08的地址2中写入数据sec
}
if(K5==0){
delay1(10);
if(K5==0){
sec=0;
}
}
}
}
//
void t0(void) interrupt 1 using 0 //定时中断服务函数
{
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //重装计数初值
count++; //每过50ms tcnt加一
if(count==20) //计满20次(1秒)时
{
count=0; //重新再计
sec++;
write=1; //1秒写一次24C08
if(sec==100) //定时100秒,在从零开始计时
{sec=0;}
}
}
你如果想要显示单个数据的话只要这一句x=eeprom_re(0x10);然后将数据拿出去显示即可,如果你要显示一串数据,那么就要搞一个FOR函数将你需要的数据一个一个取出来,另外你还要编写一个数码管字段表,就是0到9这10个数字对应的显示代码,下面我写一个小例子,
uchar code[,,,,];//0-9的数码管字段表
x=eeprom_re(0x10);
uchar a,b,c,d;
a=x/10;
b=x%10;
c=code[a];
d=code[b];
P1=c;//假设P1口连的是数码管1
P2=d;//假设P2口连的是数码管2
//你可以参考一下
以上就是关于24C04或24CXX系列EEPROM读写程序 C51的全部的内容,包括:24C04或24CXX系列EEPROM读写程序 C51的、PIC18单片机怎么读写EEPROM,我使用的是18F4520的单片机,求一个读写EEPROM的程序实例、用c语言写个程序24c08(EEprom)控制两个数码管 实现重1加到99 掉电不归0 利用中断定时1秒加一个数 谢谢了等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)