您好,欢迎来到意榕旅游网。
搜索
您的当前位置:首页关于断电延时和EEPROM数据保存STC掉电保存数据程序

关于断电延时和EEPROM数据保存STC掉电保存数据程序

来源:意榕旅游网


关于断电延时和EEPROM数据保存(申酷!!)

EEPROM, 申酷, 数据, 延时, 断电

原来想用AD检测断电的,做出来测试几遍不行,听了各位的意见。

就花了一个下午完成用一个I/O断电检测电路。把法拉电容改小了,节约开支,一个2200uf的普通电容就足够了。经测试能正常保存数据到EEPROM。

电路见下面的图片链接。

该解决方案的程序:

#include

#include //汇编头文件

#define uchar unsigned char

#define uint unsigned int

sbit p12 = P1^2;

uchar i;

void delay(uint z) //延时ms

{

uint x,y;

for(x=112;x>0;x--)

for(y=z;y>0;y--);

}

void init_232(void) //串口初始化

{

SCON = 0x50;

TMOD |= 0x20;

TH1 = 0xfa; //波特率 9600

TL1 = 0xfa;

PCON |= 0x80;

EA = 1;

ES = 1;

TR1 = 1;

}

void send_char(uchar w) //串口发送一个字符

{

SBUF = w;

while(TI == 0);

TI = 0;

}

void send_string(uchar *s,uint string_length) //串口发送一个字符串

{

uint i = 0;

do

{

send_char(*(s + i));

i++;

}

while(i < string_length);

}

/*EEPROM字符读取*/

uchar eeprom_read(uchar x,y)

{

ISP_ADDRH = x;

ISP_ADDRL = y;

ISP_CONTR = 0x9b;

ISP_CMD = 0x01;

ISP_TRIG = 0x46;

ISP_TRIG = 0xb9;

_nop_();

ISP_CONTR=0;

ISP_CMD=0;

ISP_TRIG=0;

return(ISP_DATA);

}

/*EEPROM字符写入*/

void eeprom_write(uchar x,y,z)

{

ISP_DATA = z;

ISP_ADDRH = x;

ISP_ADDRL = y;

ISP_CONTR = 0x9b;

ISP_CMD = 0x02;

ISP_TRIG = 0x46;

ISP_TRIG = 0xb9;

_nop_();

ISP_CONTR=0;

ISP_CMD=0;

ISP_TRIG=0;

}

/*EEPROM扇区擦除*/

void eeprom_erase(uchar x,y)

{

ISP_ADDRH = x;

ISP_ADDRL = y;

ISP_CONTR = 0x9b;

ISP_CMD = 0x03;

ISP_TRIG = 0x46;

ISP_TRIG = 0xb9;

_nop_();

ISP_CONTR=0;

ISP_CMD=0;

ISP_TRIG=0;

}

void main()

{

init_232();

i = 0;

delay(10);

while(1)

{

if((p12 == 0) && (i == 0))

{

eeprom_erase(0x10,0x00); //擦除第一扇区

delay(1);

eeprom_write(0x10,0x00,0x88); //在第一扇区写入88

delay(1);

i = 1;

}

}

}

/*串口接收中断函数*/

void RS232() interrupt 4

{

uchar ch = 0;

if(RI)

{

ch = SBUF;

RI = 0;

send_char(ch);

}

switch(ch)

{

case 1: send_char(eeprom_read(0x10,0x00)); //串口助手输入16进制1,读EEPROM第一扇区

break;

case 2: send_char(eeprom_read(0x12,0x00)); //串口助手输入16进制2,读EEPROM第2扇区

break;

case 3: eeprom_write(0x10,0x00,0x55); //串口助手输入16进制3,写EEPROM第一扇区55

break;

case 4: eeprom_write(0x12,0x00,0x66); //串口助手输入16进制4,写EEPROM第2扇区66

break;

case 5: eeprom_erase(0x10,0x00); //串口助手输入16进制5,擦除EEPROM第一扇区

break;

case 6: eeprom_erase(0x12,0x00); //串口助手输入16进制6,擦除EEPROM第2扇区

break;

default: break;

}

}

这是一段stc单片机EEPROM掉电存储程序,麻烦大家帮我看看哈,怎么调用时输出有问题啊,希望给个调用的例子

悬赏分:0 - 提问时间2010-8-21 19:32

#include < reg52.h >

#include < absacc.h >

#include < intrins.h >

#include \" ..\\h_files\\eeprom.h \"

/**************************************************************************************************/

void isp_iap_enable ( void )

{

EA = 0 ; /*关中断*/

ISP_CONTR = ISP_CONTR & 0x18 ;

ISP_CONTR = ISP_CONTR | WAIT_TIME ;

ISP_CONTR = ISP_CONTR | 0x80 ; /*ISPEN = 1*/

}

/**************************************************************************************************/

void isp_iap_disable ( void )

{

ISP_CONTR = ISP_CONTR & 0x7f ; /*ISPEN = 0*/

ISP_TRIG = 0x00 ;

EA = 1 ; /*开中断*/

}

/**************************************************************************************************/

void isp_iap_goon ( void )

{

isp_iap_enable ( ) ; /*打开ISP,IAP功能*/

ISP_TRIG = 0x46 ; /*触发ISP,IAP命令字节1*/

ISP_TRIG = 0xb9 ; /*触发ISP,IAP命令字节2*/

_nop_ ( ) ;

}

/**************************************************************************************************/

UINT8 byte_read ( UINT16 byte_addr )

{

ISP_ADDRH = ( UINT8 ) ( byte_addr >> 8 ) ; /*地址赋值*/

ISP_ADDRL = ( UINT8 ) ( byte_addr & 0x00ff ) ;

ISP_COMD = ISP_COMD & 0xf8 ; /*清除低3位*/

ISP_COMD = ISP_COMD | RE_COMMAND ; /*写入读命令*/

isp_iap_goon ( ) ; /*触发执行*/

isp_iap_disable ( ) ; /*关闭ISP,IAP功能*/

return ( ISP_DATA ) ; /*返回读到的数据*/

}

/**************************************************************************************************/

void sector_erase ( UINT16 sector_addr )

{

UINT16 i_sector_addr ;

i_sector_addr = ( sector_addr & 0xfe00 ) ; /*取扇区地址*/

ISP_ADDRH = ( UINT8 ) ( i_sector_addr >> 8 ) ;

ISP_ADDRL = 0x00 ;

ISP_COMD = ISP_COMD & 0xf8 ; /*清空低3位*/

ISP_COMD = ISP_COMD | ER_COMMAND ; /*擦除命令3*/

isp_iap_goon ( ) ; /*触发执行*/

isp_iap_disable ( ) ; /*关闭ISP,IAP功能*/

}

/**************************************************************************************************/

void byte_write ( UINT16 byte_addr , UINT8 original_data )

{

ISP_ADDRH = ( UINT8 ) ( byte_addr >> 8 ) ; /*取地址*/

ISP_ADDRL = ( UINT8 ) ( byte_addr & 0x00ff ) ;

ISP_COMD = ISP_COMD & 0xf8 ; /*清空低3位*/

ISP_COMD = ISP_COMD | PR_COMMAND ; /*写命令2*/

ISP_DATA = original_data ; /*写入数据准备*/

isp_iap_goon ( ) ; /*触发执行*/

isp_iap_disable ( ) ; /*关闭ISP,IAP功能*/

}

提问者: smu_east - 一级

网友推荐答案

/************************************************************************************************************************************/

#include

#include

#include

#include

/********************************************************************************

****************************************************/

#define Uchar unsigned char

#define Uint unsigned int

#define Ulong unsigned long

//定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数

#define ENABLE_ISP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值

/************************************************************************************************************************************/

sfr IAP_DATA = 0xE2;

sfr IAP_ADDRH = 0xE3;

sfr IAP_ADDRL = 0xE4;

sfr IAP_CMD = 0xE5;

sfr IAP_TRIG = 0xE6;

sfr IAP_CONTR = 0xE7;

/************************************************************************************************************************************/

//全局变量及共用体变量

/************************************************************************************************************************************/

Uchar buff[8];

Uchar buff1[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

union union_temp16{ Uint un_temp16;Uchar un_temp8[2];}my_unTemp16;//定义共用体,给存储eeprom使用

/************************************************************************************************************************************/

//函数声明区

/************************************************************************************************************************************/

void Read_8byte(Uchar *buf,Uint add,Uchar bitt); //读多个字节,调用前需打开

IAP 功能

void Program_8byte(Uchar *buf,Uint add,Uchar bitt);//写多个字节,调用前需打开IAP 功能

void Sector_Erase(Uint add); //擦除扇区

void IAP_Disable(); //关闭IAP 功能

void Delay(); //延时函数

void mcu_ini(void);//mcu初始化函数

/************************************************************************************************************************************/

//主函数区

/************************************************************************************************************************************/

void main (void)

{

Uchar i;

P1 = 0xF0; //演示程序开始,让 P1[3:0] 控制的灯亮

Delay(); //延时

P1 = 0x0F; //演示程序开始,让 P1[7:4] 控制的灯亮

Delay() ; //延时

Sector_Erase(0x4000); //擦除整个扇区

Program_8byte(buff1,0x4000,8);

P2 = 0x55;//P2.7亮

Read_8byte(buff,0x4000,8);

while (1)//CPU 在此无限循环执行此句

{

P0 = ~buff[i];

Delay(); //延时

i++;

if(i==8){i=0;P2 ^= 0xff;Delay();}

//延时

}

}

/********************************************************************************************************************************/

//读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节

/********************************************************************************************************************************/

Uchar Byte_Read(Uint add)

{

IAP_DATA = 0x00;

IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间

IAP_CMD = 0x01; //IAP/ISP/EEPROM 字节读命令

my_unTemp16.un_temp16 = add;

IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址

IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址

//EA = 0;

IAP_TRIG = 0x46; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此

IAP_TRIG = 0xB9; //送完A5h 后,ISP/IAP 命令立即被触发起动

_nop_();

//EA = 1;

return (IAP_DATA);

}

/********************************************************************************************************************************/

//读多个字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节

/********************************************************************************************************************************/

void Read_8byte(Uchar *buf,Uint add,Uchar bitt)

{ Uchar i;

for (i=0;i{

buf[i]= Byte_Read(add+i);

}

IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,

//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关

}

/********************************************************************************

************************************************/

//字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据

/********************************************************************************************************************************/

void Byte_Program(Uint add, Uchar ch)

{

IAP_CONTR = ENABLE_ISP; //打开 IAP 功能, 设置Flash 操作等待时间

IAP_CMD = 0x02; //IAP/ISP/EEPROM 字节编程命令

my_unTemp16.un_temp16 = add;

IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址

IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址

IAP_DATA = ch; //要编程的数据先送进IAP_DATA 寄存器

//EA = 0;

IAP_TRIG = 0x46; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此

IAP_TRIG = 0xB9; //送完A5h 后,ISP/IAP 命令立即被触发起动

_nop_();

//EA = 1;

}

/********************************************************************************************************************************/

//多字节写入函数

/********************************************************************************************************************************/

void Program_8byte(Uchar *buf,Uint add,Uchar bitt)

{ Uchar i;

for (i=0;i{

Byte_Program(add+i, buf[i]);

}

IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,

//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关

}

/***************************************************************************************************************************************/

//扇区擦除, 入口:DPTR = 扇区地址

/***************************************************************************************************************************************/

void Sector_Erase(Uint add)

{

IAP_CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间

IAP_CMD = 0x03; //IAP/ISP/EEPROM 扇区擦除命令

my_unTemp16.un_temp16 = add;

IAP_ADDRH = my_unTemp16.un_temp8[0]; //设置目标单元地址的高8 位地址

IAP_ADDRL = my_unTemp16.un_temp8[1]; //设置目标单元地址的低8 位地址

//EA = 0;

IAP_TRIG = 0x46; //先送 5Ah,再送A5h 到ISP/IAP 触发寄存器,每次都需如此

IAP_TRIG = 0xB9; //送完A5h 后,ISP/IAP 命令立即被触发起动

_nop_();

//EA = 1;

IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,

//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关

}

/***************************************************************************************************************************************/

//关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,

//一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关

/***************************************************************************************************************************************/

void IAP_Disable()

{

IAP_CONTR = 0; //关闭IAP 功能

IAP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用

IAP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用

IAP_ADDRH = 0;

IAP_ADDRL = 0;

}

/***************************************************************************************************************************************/

//延时函数

/***************************************************************************************************************************************/

void Delay()

{

Uchar i;

Uint d=100;

while (d--)

{

i=255;

while (i--);

}

}

你这个是STC系列的EPROM代码

要是STC12C系列就不一样了

回答者: yoya0303 - 八级 2010-8-24 20:06

这个是连续读写8个字节的程序

我调试过了,直接ctrl+c,ctrl+v,主程序调用就可以了

#define IAP_BYTE_READ 1

#define IAP_BYTE_WRITE 2

#define IAP_BYTE_ERASE 3

#define ENABLE_IAP 0x84

#define EEPROM_DATA_ADDR 0x00

UCHAR EEPROM_data[8];

UCHAR EEPROM_num;

UCHAR EEPROM_addr;

void read_EEPROM_DATA()

{

EEPROM_addr=25;

for(EEPROM_num=0;EEPROM_num<8;EEPROM_num++)

{

IAP_ADDRH=0x00;

IAP_ADDRL=EEPROM_addr;

IAP_CONTR=ENABLE_IAP;

IAP_CMD=IAP_BYTE_READ;

IAP_TRIG=0x5a;

IAP_TRIG=0xa5;

nop();

EEPROM_data[EEPROM_num]=IAP_DATA;

IAP_CONTR=0x00;

IAP_CMD=0x00;

EEPROM_addr++;

}

IAP_TRIG=0xff;

IAP_ADDRH=0xff;

IAP_ADDRL=0xff;

}

void write_EEPROM_DATA()

{

EEPROM_addr=25;

for(EEPROM_num=0;EEPROM_num<8;EEPROM_num++)

{

IAP_DATA=EEPROM_data[EEPROM_num];

IAP_ADDRH=0x00;

IAP_ADDRL=EEPROM_addr;

IAP_CONTR=ENABLE_IAP;

IAP_CMD=IAP_BYTE_WRITE;

IAP_TRIG=0x5a;

IAP_TRIG=0xa5;

nop();

nop();

nop();

nop();

IAP_CONTR=0x00;

IAP_CMD=0x00;

EEPROM_addr++;

Delay_10ms();

}

IAP_TRIG=0x00;

IAP_ADDRH=0xff;

IAP_ADDRL=0xff;

}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务