帮忙看下stc eepROM的读写程序
读写出错 不知道错在哪里主程序里调用部分
void flash_eeprom_cl(void)
{
uchar fe_tmp;
fe_tmp=( hanziqu-1 )/4;
read_block_eeprom(tab_play_buff,fe_tmp);
erasure_block_eeprom(fe_tmp);
uart_eeprom();
write_block_eeprom(tab_play_buff,fe_tmp);
read_32byte_eeprom(tab_hanzi_buff,display_page);
hanzi_find_updata();
}
stc eepROM的程序 分为扇区读 ,扇区写,扇区擦除 ,读32字节
#include<stc89.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define IAP_READ 0x01 //eeprom 读
#define IAP_WRITE 0x02 //eeprom 写
#define IAP_ERASE 0x03 //eeprom 擦除
#define ENABLE_IAP 0x82 //时间
#define base_address(ba) 0x8000+(512*ba)
#define base_32_address(ba) 0x8000+(32*ba)
void iap_disable(void); //关闭iap
void f_delay(uchar fd); //延时函数
void read_block_eeprom(unsigned char *read_eeprom_data,unsigned char read_eeprom_address)//read section
{
uint bi,eepr_address;
ISP_CONTR=ENABLE_IAP;
ISP_CMD=IAP_READ;
eepr_address=base_address(read_eeprom_address);
ISP_ADDRH= eepr_address/256;
ISP_ADDRL= eepr_address%256;
EA=0;
for(bi=0;bi<512;bi++)
{
ISP_TRIG=ISP_TRIG0;
ISP_TRIG=ISP_TRIG1;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
*read_eeprom_data++=ISP_DATA;
eepr_address++;
ISP_ADDRH= eepr_address/256;
ISP_ADDRL= eepr_address%256;
}
EA=1;
iap_disable();
}
void write_block_eeprom(unsigned char *write_eeprom_data,unsigned char write_eeprom_address) //write section
{
uint bii,eepw_address;
ISP_CONTR=ENABLE_IAP;
ISP_CMD=IAP_WRITE;
eepw_address=base_address(write_eeprom_address);
ISP_ADDRH= eepw_address/256;
ISP_ADDRL= eepw_address%256;
EA=0;
for(bii=0;bii<512;bii++)
{
ISP_DATA=*write_eeprom_data++;
ISP_TRIG=ISP_TRIG0;
ISP_TRIG=ISP_TRIG1;
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
eepw_address++;
ISP_ADDRH= eepw_address/256;
ISP_ADDRL= eepw_address%256;
}
EA=1;
iap_disable();
}
void erasure_block_eeprom(unsigned char erasure_eeprom_address) //erasure section
{
ISP_CONTR=ENABLE_IAP;
ISP_CMD=IAP_ERASE;
ISP_ADDRH=( base_address(erasure_eeprom_address)/256 );
ISP_ADDRL=( base_address(erasure_eeprom_address)%256 );
EA=0;
ISP_TRIG=ISP_TRIG0;
ISP_TRIG=ISP_TRIG1;
iap_disable();
EA=1;
f_delay(10);
}
void read_32byte_eeprom(unsigned char *read_eeprom_32byte,unsigned int read_32byte_address) //read_32byte
{
uchar bir;
uint eepr32_address;
ISP_CONTR=ENABLE_IAP;
ISP_CMD=IAP_READ;
eepr32_address=base_32_address(read_32byte_address); //计算初始地址
ISP_ADDRH= eepr32_address/256;
ISP_ADDRL= eepr32_address%256;
EA=0;
for(bir=0;bir<32;bir++)
{
ISP_TRIG=ISP_TRIG0;
ISP_TRIG=ISP_TRIG1;
_nop_();_nop_();
*read_eeprom_32byte++=ISP_DATA;
eepr32_address++;
ISP_ADDRH= eepr32_address/256;
ISP_ADDRL= eepr32_address%256;
}
EA=1;
iap_disable();
}
void iap_disable(void)
{
ISP_CONTR = 0; //关闭IAP 功能
ISP_CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用
ISP_TRIG = 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
ISP_ADDRH = 0;
ISP_ADDRL = 0;
}
void f_delay(uchar fd)
{
uchar fdt;
while(fd)
{
for(fdt=0;fdt<200;fdt++)
{
_nop_();_nop_();_nop_();_nop_();
}
fd--;
}
} 好长,呵呵 注意,STC新型号和旧型号与eeprom相关的好几个寄存器不一样,指令也不一样 /*===============================================================
项目名称:STC单片机EEPROM操作
适用范围:STC具有内部EEPROM的单片机
注意事项:
1.不同系列的STC单片机其EEPROM地址区域可能是不尽相同,除早期的89C系列及其兼容的90C系列外,
其余的基本上都是以0000H,作为第一扇区的起始地址
2.不同系列的STC单片机其ISP触发指令可能不尽相同(15/11/10/12C5A/12C52为0X5A+0XA5;
12C54/12C56/90C/89C为0X46+0XB9),可根据型号调整TRIG_CMD1和TRIG_CMD2
3.不同系列的STC单片机其与EEPROM相关的特殊寄存器地址也不尽相同(89/90/12C52/12C54/12C56/
12C20为E2~E7,10/11/15/12C5A为C2~C7),可通过使能“#define NEW”设置
4. 应根据系统时钟适当调整ISP等待时间“ENABLE_ISP”
===================================================================*/
#define NEW
#ifdef NEW
sfr DATA = 0xC2;
sfr ADDRH = 0xC3;
sfr ADDRL = 0xC4;
sfr CMD = 0xC5;
sfr TRIG = 0xC6;
sfr CONTR = 0xC7;
#else
sfr DATA = 0xE2;
sfr ADDRH = 0xE3;
sfr ADDRL = 0xE4;
sfr CMD = 0xE5;
sfr TRIG = 0xE6;
sfr CONTR = 0xE7;
#endif
#define TRIG_CMD1 0X5A
#define TRIG_CMD2 0XA5
//#define ISP_TRIG_CMD1 0X46
//#define ISP_TRIG_CMD2 0XB9
#define CLOCK 12
#if CLOCK <=5
#define ENABLE_ISP 0x83
//#define ENABLE_ISP 0x84
#elif CLOCK <=10
#define ENABLE_ISP 0x82
//#define ENABLE_ISP 0x83
#elif CLOCK <=20
#define ENABLE_ISP 0x81
//#define ENABLE_ISP 0x82
#elif CLOCK >20
#define ENABLE_ISP 0x80
//#define ENABLE_ISP 0x81
#endif
void ISP_Disable() //关闭IAP 功能
{
CONTR = 0; //关闭IAP 功能
CMD = 0; //清命令寄存器,使命令寄存器无命令,此句可不用
TRIG= 0; //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
ADDRH = 0;
ADDRL = 0;
}
unsigned char Byte_Read(unsigned int add)
{
//DATA = 0x00;
ADDRL=add;
ADDRH=add >> 8;
CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间
CMD = 0x01; //字节读命令
EA = 0; //新的D版不需关中断
TRIG =TRIG_CMD1;//ISP触发指令
TRIG =TRIG_CMD2;//ISP触发指令
_nop_();
ISP_Disable();
EA = 1;
return (DATA);
}
void Byte_Program(unsigned int add,unsigned char ch)
{
DATA = ch;
ADDRL=add;
ADDRH=add >> 8;
CONTR = ENABLE_ISP; //打开 IAP 功能, 设置Flash 操作等待时间
CMD = 0x02; //字节编程命令
EA = 0; //新的D版不需关中断
TRIG =TRIG_CMD1;//ISP触发指令
TRIG =TRIG_CMD2;//ISP触发指令
_nop_();
ISP_Disable();
EA = 1;
return;
}
void Sector_Erase(unsigned int add)
{
ADDRL=add;
ADDRH=add >> 8;
CONTR = ENABLE_ISP; //打开IAP 功能, 设置Flash 操作等待时间
CMD = 0x03; //扇区擦除命令
EA = 0; //新的D版不需关中断
TRIG =TRIG_CMD1;//ISP触发指令
TRIG =TRIG_CMD2;//ISP触发指令
_nop_();
ISP_Disable();
EA = 1;
}
页:
[1]