yanyinzhong 发表于 2011-6-28 16:22:42

帮忙看下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--;
       }
}

koolie 发表于 2011-6-28 20:16:26

好长,呵呵

linminsong 发表于 2011-7-7 14:54:09

注意,STC新型号和旧型号与eeprom相关的好几个寄存器不一样,指令也不一样

linminsong 发表于 2011-7-7 14:55:15

/*===============================================================
项目名称: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]
查看完整版本: 帮忙看下stc eepROM的读写程序