① 单片机中如何实现永久保存某一程序中的数据
可以外接EEPROM 24C02,下面的程序你可以参考,改动后使用,我试过,读写都正常
;**************************************************/
#define uchar unsigned char
#define uint unsigned int
#define Slaw 0x0a; //写命令字
#define Slar 0xa1; //读命令字
#include "reg52.h"
#include "intrins.h"
sbit Scl=P3^6; //串行时钟
sbit Sda=P3^7; //串行数据
bit Rec; //接收到数据的标志
uchar RecBuf[3]; //接收缓冲区
#define Hidden 0x10; //消隐字符在字形码表中的位置
uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};
uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};
uchar DispBuf[6]; //6字节的显示缓冲区
uchar code TH0Val=63266/256;
uchar code TL0Val=63266%256;//当晶振为11.0592时,定时2.5ms的定时器初值
//以下是中断程序,用于显示
void Timer0() interrupt 1
{ uchar tmp;
static uchar dCount; //计数器,显示程序通过它得知现正显示哪个数码管
TH0=TH0Val;
TL0=TL0Val;
tmp=BitTab[dCount]; //根据当前的计数值取位值
P2=P2|0xfc; //P2与11111100B相或,将高6位置1
P2=P2&tmp; //P2与取出的位值相与,将某一位清零
tmp=DispBuf[dCount]; //根据当前的计数值取显示缓冲待显示值
tmp=DispTab[tmp]; //取字形码
P0=tmp; //送出字形码
dCount++; //计数值加1
if(dCount==6) //如果计数值等于6,则让其回0
dCount=0;
}
/*发送起始条件*/
void Start(void) /*起始条件*/
{
Sda=1;
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Sda=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
}
void Stop(void) /*停止条件*/
{
Sda=0;
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Sda=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
}
void Ack(void) /*应答位*/
{
Sda=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=0;
}
void NoAck(void) /*反向应答位*/
{
Sda=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=0;
}
void Send(uchar Data) /*发送数据子程序,Data为要求发送的数据*/
{
uchar BitCounter=8; /*位数控制*/
uchar temp; /*中间变量控制*/
do
{
temp=Data;
Scl=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
if((temp&0x80)==0x80)/* 如果最高位是1*/
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1; /*RLC*/
Data=temp;
BitCounter--;
}while(BitCounter);
Scl=0;
}
uchar Read(void) /*读一个字节的数据,并返回该字节值*/
{
uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do{
Scl=0;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
Scl=1;
_nop_ ();
_nop_ ();
_nop_ ();
_nop_ ();
if(Sda) /*如果Sda=1;*/
temp=temp|0x01; /*temp的最低位置1*/
else
temp=temp&0xfe; /*否则temp的最低位清0*/
if(BitCounter-1)
{ temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}while(BitCounter);
return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)
{
uchar i=0;
uchar *PData;
PData=Data;
Start();
Send(0xa0);
Ack();
Send(Address);
Ack();
for(i=0;i<Num;i++)
{
Send(*(PData+i));
Ack();
}
Stop();
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)
{
uchar i=0;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(0xa0);
Ack();
Send(Address+i);
Ack();
Start();
Send(0xa1);
Ack();
*(PData+i)=Read();
Scl=0;
NoAck();
Stop();
}
}
void Recive() interrupt 4 //串行中断程序
{ static uchar Count=0;
if(TI)
{ TI=0;
return; //如果是发送中断,直接退出
}
RI=0; //清RI标志
RecBuf[Count]=SBUF;
Count++;
Rec=0;
if(Count>=3)
{ Count=0;
Rec=1; //置位标志
}
}
void Init()
{ TMOD=0x21;
RI=0;
TH1=0xfd;
TL1=0xfd;
PCON|=0x80;
TR1=1;
SCON=0x50;
TH0=TH0Val;
TL0=TL0Val;
ET0=1; //开T0中断
EA=1; //开总中断
ES=1;
TR0=1; //T0开始运行
TR1=1;
}
void Calc(uchar Dat1,uchar Dat2) //第一个参数放在第1、2位,第二个参数放入第5、6位
{ DispBuf[0]=Dat1/16;
DispBuf[1]=Dat1%16;
DispBuf[4]=Dat2/16;
DispBuf[5]=Dat2%16;
}
void main()
{ uchar RomDat[4];
Init(); //初始化
DispBuf[2]=Hidden;
DispBuf[3]=Hidden;
for(;;)
{
Calc(RecBuf[1],RomDat[0]); //分别显示地址和数据
if(Rec) //接收到数据
{ Rec=0; //清除标志
if(RecBuf[0]==0) //第一种功能,写入
{ RomDat[0]=RecBuf[2];
WrToROM(RomDat,RecBuf[1],1);
SBUF=RomDat[0];
}
else
{ RdFromROM(RomDat,RecBuf[1],1);
SBUF=RomDat[0];
}
}
}
}
② 如何让单片机某一临时数据永久保存
存到EEPROM ,开机的时候再从EEPROM读取
③ 如何保存单片机程序设定的参数,停电后这些参数不会消失。
很多单片机(如PIC16F87X系列)除了基本的ROM和RAM外,都带有内部EEPROM,CPU是在运行时可以对EEPROM进行读写的。EEPROM掉电后的信息是不会丢失的。
④ 以什么格式保存参数方便单片机读取
CSV格式的文件,就是数据项之间用逗号隔开的文件。
单片机又叫芯片,里面是有程序的。在单片机上电的瞬间,MCU的程序指针PC会被初始化为上电复位时的地址,从哪个地址处读取将要执行的指令,由此程序在MCU上开始执行(当然在调用程序的main之前,还有一系列其他的的初始化要做,如堆栈的初始化,不过这些很少回去修改)。
PC在上电时,和MCU差不多,不过读取的是BIOS,有它完成了很多初始化操作,最后,调用系统的初始化函数,将控制权交给了操作系统,于是我们看到了Windows、Linux系统启动了。
⑤ 飞思卡尔 mc9s12xs128 单片机 怎样才可以 在EPROM 或者在 FASH 中 保存运行的参数
有相关资料可以参考的,你搜一下flash to epprom相关资料:
用Flash模拟EEPROM
本程序利用S08系列单片机的片内Flash模拟EEPROM。解决部分8位机没有EEPROM导致在运用上的局限。本程序提供一个初始化函数和三个功能函数。用户必须在调用功能函数前调用调用初始化函数。三个功能函数分别是字节写入、字节读取、EEPROM全擦除。用户必须保证调用功能函数前有至少30Bate的栈空间。
本程序参考飞思卡尔公司提供的《在 HCS08 微控制器上使用 FLASH 存储器模拟 EEPROM》。并在源程序的基础上精简了部分功能,减少了RAM使用量。并尝试使用分页机制确定EEPROM地址。
接口函数的EEPROM地址寻址由页地址和页内偏移量组成。即把用户定义的EEPROM分为若干个大小为256字节的页。其地址与FLASH地址的换算关系为:
FLASH真实地址=EEPROM空间起始地址+页地址×256+页内偏移地址
用户在使用EEPROM是只用确定数据保存在EEPROM的相对地址即可。接口函数原型为:
EEPROM_WRITE_DATA(数据,页地址, 页内偏移地址);
Char EEPROM_READ_DATA(页地址, 页内偏移地址);
1. 程序流程分析与设计。
由于S08系列单片机在Flash写入时序中不能进行任何的Flash读操作,Flash写入指令必须放到RAM中执行并关闭所有可屏蔽中断。程序流程如图13-1-?。
字节写入/.全擦除程序流程 字节读取程序流程
图13-1-?
2.程序源代码。此程序在CodeWarrior 6.0继承编译环境中编译通过
/*****************************************************/
//河南工业大学Freescale MCU&DSP联合实验室
// 文件名:flash_program.h
// CPU :MC9S08AW60
// 版 本:v1.0
// 日 期:2008年8月12日
// 调试环境:CodeWarrior 6.0
// 作 者:曾 滔
// 描 述: 头文件,用于保存初始化EEPROM设定、用户定制参数、编译器参数等信息。
/*****************************************************/
#include <hidef.h>
#include "derivative.h"
#include <stdio.h>
/*************flash编程指令(请勿改动)*****************/
#define BLACK_CHECK 0x05 //查空指令
#define BITE_PROGRAM 0x20 //字节编程指令
#define BURST_PROGRAM 0x25 //快速编程指令
#define PAGE_ERASE 0x40 //页擦除指令(1页=512字节)
#define MASS_ERASE 0x41 //全擦除指令
/******用户定制参数(根据单片机型号和用户flash使用情况定制)**********/
#define EEPROM_START_ADDRESS 0xE000 //EEPROM区起始地址。512B的倍数
#define EEPROM_PAGE_NUM 8 //EEPROM页数。1page=256B
#define BUS_FREQUENCY 2000 //总线频率。单位(KHz)
/********************编译器相关参数**************************/
#define INT8U unsigned char //无符号字节变量。根据编译器更改。默认CodeWarrior 6.0
#define INT16U unsigned short int //无符号字变量。根据编译器更改。默认CodeWarrior 6.0
/***********EEPROM API函数原型***********/
//初始化程序。此函数必须在使用EEPROM前调用。建议用户在系统初始化是调用。
void INIT_EEPROM(void);
//EEPROM擦除函数。擦除所有EEPROM数据。
void EEPROM_ERASE(void);
//EEPROM字节写入函数。写入一个字节到EEPROM指定区域。
void EEPROM_WRITE_DATA(INT8U data,INT8U EEPROM_page,INT8U offset_address)
//EEPROM读出函数。读出一个指定的区域所保存的字节的到函数返回值。
char EEPROM_READ_DATA(INT8U EEPROM_page,INT8U offset_address);
/****************************END************************************/
/*****************************************************/
//河南工业大学Freescale MCU&DSP联合实验室
// 文件名:flash_program.c
// C P U :MC9S08AW60
// 版 本:v1.0
// 日 期:2008年8月12日
// 调试环境:CodeWarrior 6.0
// 作 者:曾 滔
// 描 述:提供了一个初始化函数和三个功能函数供用户调用,没有可更改参数。
/*****************************************************/
#include "flash_program.h"
const INT8U FLASH_CODE[]={ // ; flash操作代码
0x45, 0x18, 0x26, // LDHX #$1826 ; FCMD地址写入H:X
0xA6, 0x00, // LDA #$00 ; 0x00为命令占位符
0xF7, // STA ,X ; 将命令写入FCMD命令缓存器
0x5A, // DECX ; 指针指向 FSTAT
0xF6, // LDA ,X ;
0xAA, 0x80, // ORA #$80 ;
0xF7, // STA ,X ; 置位FSTAT_FCBEF。启动flash写入命令
0xF6, // LDA ,X ; 等待3个时钟周期(请勿删除此代码)
0xF6, // LDA ,X ; 读取FSTAT
0xA5, 0x30, // BIT #$30
0x26, 0x05, // BNE *+6 ; 错误则返回
//LOOP
0xF6, // LDA ,X ; 等待写操作结束
0xA5, 0x40, // BIT #$40
0x27, 0xFB, // BEQ *-3 ; 跳转到LOOP
//EXIT:
0X81 //RTS ; 返回
};
/*********************初始化函数**********************************/
#if BUS_FREQUENCY >= 12000
void INIT_EEPROM(void){FCDIV=(((BUS_FREQUENCY/(8*175)))|0x40)-1;}
#endif
#if BUS_FREQUENCY < 12000
void INIT_EEPROM(void){FCDIV=(BUS_FREQUENCY/175)-1;}
#endif
/***********************EEPROM字节写入函数****************************/
void EEPROM_WRITE_DATA(INT8U data,INT8U EEPROM_page,INT8U offset_address)
{
INT16U address; //存放写入地址
INT8U code_space[23]; //初始化代码空间
if(EEPROM_page>=EEPROM_PAGE_NUM)return; //地址错误返回,保护用户代码
address=offset_address+EEPROM_page*256+EEPROM_START_ADDRESS; //地址转化
(void)memcpy(code_space,FLASH_CODE,23); //复制flash操作代码到RAM
code_space[4] = BITE_PROGRAM; //修改命令占位符为写入命令
DisableInterrupts; //关中断
if (FSTAT&0x10){ //清错误标志
FSTAT = FSTAT|0x10;
}
_asm
{ //写入初始化
LDHX address;
LDA data;
STA ,X; //写入缓存
TSX;
JSR 2,x; //跳入RAM执行
}
EnableInterrupts; //开中断
__RESET_WATCHDOG();
}
/********************EEPROM字读取入函数********************************/
char EEPROM_READ_DATA(INT8U EEPROM_page,INT8U offset_address){
unsigned short int address; //地址变量
char rusult; //数据变量
address=offset_address+EEPROM_page*0x100+EEPROM_START_ADDRESS; //地址转换
asm{
LDHX address;
LDA ,X; //读取地址到数据变量
STA rusult;
}
__RESET_WATCHDOG();
return(rusult); //返回
}
/**********************EEPROM擦除函数********************************/
void EEPROM_ERASE(void)
{
INT16U address;
INT8U i; //循环变量
INT8U code_space[23];
for(i=0;i<(EEPROM_PAGE_NUM/2);i++){ //分页擦除
address=i*0x200+EEPROM_START_ADDRESS;
(void)memcpy(code_space,FLASH_CODE,23); //复制flash操作代码到RAM
code_space[4] = PAGE_ERASE; //修改命令占位符为擦除命令
DisableInterrupts; //关中断
if (FSTAT&0x10){ //清错误标志
FSTAT = FSTAT | 0x10;
}
_asm
{
LDHX address; //擦除地址写入缓存
STA ,X;
TSX;
JSR 3,x; //跳入RAM执行
}
EnableInterrupts; //开中断
__RESET_WATCHDOG();
}
}
/****************************END************************************/
/*****************************************************/
// 版权所有(c)河南工业大学
// 文件名:mian.c
// C P U :MC9S08AW60
// 版 本:v1.0
// 日 期:2008年8月12日
// 调试环境:CodeWarrior 6.0
// 作 者:曾 滔
// 描 述: 测试Flash模拟EEPROM程序。
/*****************************************************/
#include <hidef.h>
#include "derivative.h"
#include "flash_program.h"
void main(void){
char temp;
PTADD=0XFF;
INIT_EEPROM(); //初始化Flash控制寄存器。
do{
EEPROM_WRITE_DATA(88,0,0); //写入一个字节。
temp=EEPROM_READ_DATA(0,0); //读取一个字节
}while(temp!=88); //若写入失败则再次写入
PTAD_PTAD0=1;
do{
EEPROM_ERASE();
}while(EEPROM_READ_DATA(0,0)!=0xff); //擦除Flash
PTAD_PTAD1=1;
for(;;)__RESET_WATCHDOG(); //死循环
}
⑥ 51单片机 此次运行的程序运算出来的变量怎么能在掉电模式下保存一定采纳
存储在AT24C02之中,每次更新数据之后同时存储在AT24C02之中,然后重新运行的时候可以从24C02里面取出来数据。这样可以防止掉电造成的数据丢失,24C02的C51程序网上很多,你可以从网络文库下载下来分析一下添加到你的程序中去,慢慢调试几次你就会掌握了,祝你好运!
⑦ 单片机如何保存用户设置过的参数
SM5964没有EEPROM,所以按照你的要求的话最简单的就是使用外部EEPROM来保存参数,一般最简单的就是使用24系列的串行ROM,比如24C512(64KB),或者使用并行的28系列EEPROM(如AT28C64,8KB)或者29系列的Flash(W29C020,256KB)。
⑧ 51单片机按键调节参数值并保存的程序代码
uchar a=50;//假设a的可调范围是1到100;
uint time=0;
eepromEraseSector (0X2800);//擦除EPROM一个扇区
while(time<5000)//不足5s
{
if(s1==0)//S1按下
{ delay_ms(20);
if(s1==0){ while(s1==0);a-- ; time=0; if(a==0)a=100;}
}
if(s2==0)//S2按下
{ delay_ms(20);
if(s2==0){ while(s2==0);a++; time=0; if(a>100)a=0; };
//一旦按键按下,time就清0
}
delay_ms(100);
time+=100;
}
eepromWrite(0x2800, a);//写入 EPROM
⑨ 单片机怎样才能保存设置的参数,初学者请教各位!!!
先看你用的什么单片机,现在流行的单片机如C8051F等都有Flash存储器,可掉电保存数据,这样就不需要外扩存储器。经典的MCS-51很古老,没有Flash,所以一般单片机教材上的都没讲怎样保存数据。具体有没有Flash可以查看单片机的数据手册。
往单片机的Flash里存数据一般有特殊的编程步骤,各种单片机都不一样,也要查看数据手册。
单片机没有Flash的话,就需要扩展存储器了。EPROM是紫外线擦除的,不能用。EEPROM是电擦除的。看你需要多大空间、什么接口,再去查型号,AT24C01,AT29C020等。下面的网址可以参考:
http://www.zymcu.com/device/memory/eeprom_01.htm
http://www.zymcu.com/device/memory/flash_01.htm
⑩ 如何把参数保存到51单片机
把参数保存到51单片机:
如果是保存掉电不保护的缓存数据,可以用单片机内部的RAM空间,包括20H~7FH直接寻址区、80H~FFH中非SFR占用的间接寻址区,在STC单片机中还有内部扩展RAM也可以使用。
如果是保存掉电保护的数据,可以在单片机外部挂机flash或eeprom芯片。目前常用的51单片机中,有部分型号可以将ROM的顶端空间配置成eeprom,用于存储这类掉电保护的数据。