① 單片機中如何實現永久保存某一程序中的數據
可以外接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,用於存儲這類掉電保護的數據。