欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標(biāo)題:
51單片機(jī)關(guān)于EEPROM的讀寫(xiě)
[打印本頁(yè)]
作者:
內(nèi)卷1234
時(shí)間:
2024-3-2 14:08
標(biāo)題:
51單片機(jī)關(guān)于EEPROM的讀寫(xiě)
首先我們要知道什么是EEPROM
這里要看自己的單片機(jī)EEPROM地址大小和起始地址
主要要用到的寄存器并不多,一個(gè)是IAP_CMD(C5H),還有的就是IAP_CONTR(C7H)
然后以下就是通過(guò)代碼寫(xiě)命令到寄存器最后進(jìn)行數(shù)據(jù)操作即可
單片機(jī)源程序如下:
#include "STC15F2kxx.h"
#include "stceeprom.h"
#include <intrins.h>
#include <string.h>
#include "delay.h"
//關(guān)閉IAP功能
void IapIdle()
{
IAP_CONTR = 0;
IAP_CMD = 0;
IAP_TRIG = 0;
IAP_ADDRH = 0x80;
IAP_ADDRL = 0;
}
//擦除指定地址的扇區(qū)
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP;//使能IAP
IAP_CMD = CMD_ERASE; //擦除命令
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_(); //等待
IAP_TRIG = 0xa5;
_nop_();
IapIdle();//關(guān)閉IAP功能
}
//往指定地址中寫(xiě)入一個(gè)字節(jié)字符數(shù)據(jù)
void IapWritecChar(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //寫(xiě)命令
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_DATA = dat;
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
IapIdle();
}
//往指定地址寫(xiě)入兩個(gè)字節(jié)數(shù)據(jù)
void IapWriteInt(WORD addr,unsigned int dat)
{
unsigned char i;
typedef union //設(shè)置共用體,用char分?jǐn)?字節(jié)
{
unsigned int dat1;
char mchar[2];
}NEW_DATA;
NEW_DATA data1;
data1.dat1 = dat;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //寫(xiě)命令
for(i = 0; i < 2; i++)
{
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_DATA = data1.mchar[i];
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
addr++;
}
IapIdle(); //關(guān)閉IAP功能
}
//往指定地址寫(xiě)入四個(gè)字節(jié)數(shù)據(jù)
void IapWriteI32(WORD addr, unsigned long dat)
{
unsigned char i;
typedef union//設(shè)置共用體,用char分?jǐn)?字節(jié)
{
unsigned long dat1;
char mchar[4];
}NEW_DATA;
NEW_DATA data1;
data1.dat1 = dat;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //寫(xiě)命令
for(i = 0; i < 4; i++)
{
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_DATA = data1.mchar[i];
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
addr++;
}
IapIdle(); //關(guān)閉IAP功能
}
/*******************************************************************************
* 函數(shù)名 : Powerlost_data
* 描述 : 斷電中斷數(shù)據(jù)寫(xiě)入函數(shù)
* 輸入 : addr 地址 dat 寫(xiě)入數(shù)據(jù)
* 輸出 : 無(wú)
* 返回值 : 無(wú)
* 說(shuō)明 : 為了應(yīng)對(duì)中斷函數(shù)與主函數(shù)循環(huán)使用IapWriteI32函數(shù)沖突
*******************************************************************************/
void Powerlost_data(WORD addr ,unsigned long dat)
{
unsigned char i;
typedef union//設(shè)置共用體,用char分?jǐn)?字節(jié)
{
unsigned long dat1;
char mchar[4];
}NEW_DATA;
NEW_DATA data1;
data1.dat1 = dat;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //寫(xiě)命令
for(i = 0; i < 4; i++)
{
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_DATA = data1.mchar[i];
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
addr++;
}
IapIdle(); //關(guān)閉IAP功能
}
//往指定起始地址寫(xiě)入不固定長(zhǎng)度的字符串?dāng)?shù)據(jù)
void IapWriteString(WORD addr,BYTE *mString,BYTE n)
{
unsigned char i;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //寫(xiě)命令
for(i=0; i<n ;i++)
{
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_DATA = mString[i];
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
addr++;
}
IapIdle(); //關(guān)閉IAP功能
}
//向指定地址讀取一個(gè)字節(jié)的字符數(shù)據(jù)
char IapReadChar(WORD addr)
{
BYTE dat;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //讀命令
IAP_ADDRL = addr; //指定地址
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
dat = IAP_DATA;
IapIdle(); //關(guān)閉IAP功能
return dat;
}
//向指定地址讀取兩個(gè)字節(jié)的數(shù)字?jǐn)?shù)據(jù)
unsigned int IapReadInt(WORD addr)
{
unsigned int dat;
unsigned char i;
typedef union //設(shè)置共用體,用char分?jǐn)?字節(jié)
{
unsigned int dat1;
char mchar[2];
}NEW_DATA;
NEW_DATA data1;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //讀命令
for(i = 0; i < 2; i++)
{
IAP_ADDRL = (addr + i); //指定地址
IAP_ADDRH = ((addr + i) >> 8);
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
data1.mchar[i]= IAP_DATA;
}
IapIdle(); //關(guān)閉IAP功能
dat = data1.dat1;
return dat;
}
//向指定地址讀取四個(gè)字節(jié)的數(shù)字?jǐn)?shù)據(jù)
unsigned long IapReadI32(WORD addr)
{
unsigned long dat;
unsigned char i;
typedef union//設(shè)置共用體,用char分?jǐn)?字節(jié)
{
unsigned long dat1;
char mchar[4];
}NEW_DATA;
NEW_DATA data1;
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //讀命令
for(i = 0; i < 4; i++)
{
IAP_ADDRL = (addr + i); //指定地址
IAP_ADDRH = ((addr + i) >> 8);
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
data1.mchar[i] = IAP_DATA;
}
IapIdle();//關(guān)閉IAP功能
dat = data1.dat1;
return dat;
}
//向指定地址讀取不定長(zhǎng)度的字符串?dāng)?shù)據(jù)
void IapReadString(WORD addr,BYTE *mString, BYTE n)
{
unsigned char i;
memset(mString,0,strlen(mString));
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //讀命令
for(i = 0; i < n; i++)
{
IAP_ADDRL = (addr + i); //指定地址
IAP_ADDRH = ((addr + i) >> 8);
IAP_TRIG = 0x5a; //命令觸發(fā)器先寫(xiě)5ah,再寫(xiě)a5h命令才能生效
_nop_();
IAP_TRIG = 0xa5;
_nop_();
mString[i] = IAP_DATA;
}
IapIdle();//關(guān)閉IAP功能
}
復(fù)制代碼
作者:
aidianzi
時(shí)間:
2024-3-9 11:49
小數(shù)據(jù)可以這樣寫(xiě)分開(kāi)幾個(gè)字節(jié)幾個(gè)字節(jié)的寫(xiě),不過(guò)建議寫(xiě)數(shù)據(jù)可以使用一個(gè)結(jié)構(gòu)體把數(shù)據(jù)和校驗(yàn)數(shù)據(jù)都寫(xiě)進(jìn)去,使用指針,存儲(chǔ)根據(jù)結(jié)構(gòu)體數(shù)據(jù)sizeof結(jié)果直接寫(xiě)入,讀取時(shí)通過(guò)結(jié)構(gòu)體數(shù)據(jù)大小一次性讀取并做校驗(yàn),我現(xiàn)在數(shù)據(jù)量小CRC8做校驗(yàn),要是數(shù)據(jù)量大可以考慮CRC16或32
歡迎光臨 (http://m.raoushi.com/bbs/)
Powered by Discuz! X3.1