24C04或24CXX系列EEPROM读写程序 C51的

24C04或24CXX系列EEPROM读写程序 C51的,第1张

我课程设计使用的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秒加一个数 谢谢了等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/10102803.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存