|
#ifndef __EEPROM_H__
#define __EEPROM_H__
#include "stc8hxx.h"
#include "intrins.h"
union u16_2char
{
unsigned char p[2];
unsigned int num;
};
//從某扇區(qū)讀取一個2字節(jié)數(shù)據(jù)
unsigned int Read_EEPROM_u16(unsigned int add);
//在某個地址所在扇區(qū)保存一個2字節(jié)數(shù)據(jù)
void Save_EEPROM_u16(unsigned int add,unsigned int dat);
//在EEPROM里面一次性寫入20個數(shù)據(jù)
void Wr_20_Long(unsigned int addr,long *dat);
//在EEPROM里面一次性讀取20個數(shù)據(jù)
void Re_20_Long(unsigned int addr,long *dat);
#endif
#include "EEPROM.h"
void IapIdle()
{
IAP_CONTR = 0; //關(guān)閉IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除觸發(fā)寄存器
IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
IAP_ADDRL = 0; //清徐IAP地址
}
//讀取某地址一個字節(jié)
unsigned char Read_One_Byte(unsigned int addr) //讀IAP數(shù)據(jù)
{
unsigned char dat;
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
IAP_CMD = 1; //設(shè)置IAP讀命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); // 延時等待發(fā)送完成
dat = IAP_DATA; //讀IAP數(shù)據(jù)
IapIdle(); //關(guān)閉IAP功能
return dat;
}
//在某地址寫入一個字節(jié)
void Write_One_Byte(unsigned int addr,unsigned char dat) //寫IAP數(shù)據(jù)
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
IAP_CMD = 2; //設(shè)置IAP寫命令
IAP_ADDRL = addr; //設(shè)置IAP低地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
IAP_DATA = dat; //寫IAP數(shù)據(jù)
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); // 延時等待發(fā)送完成
IapIdle(); //關(guān)閉IAP功能
}
//擦除某地址所在的扇區(qū)
void Erase_IAP(unsigned int addr) //IAP擦除
{
IAP_CONTR = 0x80; //使能IAP
IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
IAP_CMD = 3; //設(shè)置IAP擦除命令
IAP_ADDRL = addr; //設(shè)置IAP低8位地址
IAP_ADDRH = addr >> 8; //設(shè)置IAP高8位地址
IAP_TRIG = 0x5a; //寫觸發(fā)命令(0x5a)
IAP_TRIG = 0xa5; //寫觸發(fā)命令(0xa5)
_nop_(); // 延時等待發(fā)送完成
IapIdle(); //關(guān)閉IAP功能
}
//在某個地址所在扇區(qū)保存一個2字節(jié)數(shù)據(jù)
void Save_EEPROM_u16(unsigned int add,unsigned int dat)
{
unsigned int addr = 0;
union u16_2char dat1;
addr = add;
dat1.num = dat;
addr = add * 256 + 1;//非IAP系列單片機(jī),直接輸入扇區(qū)地址用的
Erase_IAP(addr);//擦除當(dāng)前扇區(qū)
Write_One_Byte(addr,dat1.p[0]);//保存的高字節(jié)在前
Write_One_Byte(addr+1,dat1.p[1]);
// Write_One_Byte(addr+2,dat1.p[2]);
// Write_One_Byte(addr+3,dat1.p[3]);
}
//從某扇區(qū)讀取一個2字節(jié)數(shù)據(jù)
unsigned int Read_EEPROM_u16(unsigned int add)
{
unsigned int addr = 0;
union u16_2char dat1;
addr = add;
dat1.p[0] = Read_One_Byte(addr);
dat1.p[1] = Read_One_Byte(addr+1);
// dat1.p[2] = Read_One_Byte(addr+2);
// dat1.p[3] = Read_One_Byte(addr+3);
return dat1.num;
}
//在EEPROM里面一次性寫入20個數(shù)據(jù)
void Wr_20_unsignedint(unsigned int addr,unsigned int *dat)
{
unsigned int addr2=0;
unsigned char a=0;
addr2 = addr;
Erase_IAP(addr2);//擦除當(dāng)前扇區(qū)
for(a=0;a<20;a++)
{
Save_EEPROM_u16 (addr2,dat[a]);
addr2 += 2;
}
}
//在EEPROM里面一次性讀取20個數(shù)據(jù)
void Re_20_unsignedint(unsigned int addr,unsigned int *dat)
{
unsigned int addr2=0;
unsigned char a=0;
addr2 = addr;
for(a=0;a<20;a++)
{
dat[a] = Read_EEPROM_u16(addr2);
addr2 += 2;
}
}
這樣改好像不對呀?請高人指點(diǎn)! |
|