转:STC通用EEPROM操作函数(通杀1T,12T系列所有型号,支持连续读/写)--转amo论坛BXAK

原文地址:https://www.amobbs.com/thread-5474978-1-1.html

// data    指片内RAM:  0x00~0x7F
// bdata  指片内RAM:  0x20~0x2F
// idata   指片内RAM:  0x00~0xFF
// xdata  一般指扩展RAM:  0x0000~0xFFFF(也指STC内部扩展RAM:0x0000~0xFFFF)
// code   指程序存储区ROM:0x0000~0xFFFF

自定义数据类型

typedef  unsigned char  uint8; 
typedef  unsigned int   uint16; 
typedef  unsigned long  uint32;  

#define   uint8d    unsigned char data        
#define   uint8b    unsigned char bdata                
#define   uint8i     unsigned char idata                
#define   uint8x    unsigned char xdata                
#define   uint8c    unsigned char code

EROM_STC.H文件
// 注:连续读、写函数参数最好不使用通用指针,明确指针指向数据类型可以减小代码和提高速度
//
// STC89C52RC          EEOPROM大小: 4K,首址:0x2000,触发:0x5A,0xA5 
// STC11F01E          EEOPROM大小: 2K,首址:0x0000,触发:0x5A,0xA5 
// STC12C5410AD          EEOPROM大小:12K,首址:0x0000,触发:0x46,0xB9 
// STC12C4052         EEOPROM大小:10K,首址:0x0000,触发:0x46,0xB9
// STC12C5A32S2         EEOPROM大小:28K,首址:0x0000,触发:0x5A,0xA5
// STC12C5A60S2         EEOPROM大小: 1K,首址:0x0000,触发:0x5A,0xA5
// STC15F104E         EEOPROM大小: 1K,首址:0x0000,触发:0x5A,0xA5
// STC15F204EA         EEOPROM大小: 1K,首址:0x0000,触发:0x5A,0xA5

#ifndef __EROM_STC_H__
#define __EROM_STC_H__ 

#include "STC12C5A60S2.H"                           //STC头文件  
include  <intrins.h>              

        #define  InterEA             1                //主程序中是否使用中断(1:是,0:否) 
        #define  CPU_Fosc          12000000UL      //CPU工作频率
        #define  EROM_Start       0x0000             //EEOPROM首址         (不同STC型号有所不同)                   
       #define  EROM_COM        1                //EEOPROM触发命令(不同STC型号有所不同,1:[0x5A,0xA5],0:[0x46,0xB9])


extern uint8 EROM_R( uint16 addr );                  //读指定地址一字节数据
extern void  EROM_W( uint16 addr, uint8 dat ); //向指定地址写一字节数据
extern void  EROM_C( uint8 n );                          //擦除指定扇区
extern void  EROM_R_8( uint16 addr, uint8i *pr, uint16 size ); //连续读数据
extern void  EROM_W_8( uint16 addr, uint8i *pr, uint16 size ); //连续写数据

#endif
复制代码
EROM_STC.c文件
#include "EROM_STC.H"

#if   ( EROM_COM == 1 )
    #define  COM0_STC        0x5A                    
    #define  COM1_STC        0xA5
#else
    #define  COM0_STC        0x46                     
    #define  COM1_STC        0xB9
#endif                
                                                        
                             //以下是ISP/IAP操作时间宏定义选项(根据CPU工作频率选择)
#if   ( CPU_Fosc <=  1000000 )
    #define  EN_IAP  0x87          //系统时钟 <= 1MHz
#elif ( CPU_Fosc <=  2000000 )
    #define  EN_IAP  0x86          //系统时钟 <= 2MHz
#elif ( CPU_Fosc <=  3000000 )
    #define  EN_IAP  0x85          //系统时钟 <= 3MHz
#elif ( CPU_Fosc <=  6000000 )
    #define  EN_IAP  0x84          //系统时钟 <= 6MHz
#elif ( CPU_Fosc <= 12000000 )
    #define  EN_IAP  0x83          //系统时钟 <= 12MHz
#elif ( CPU_Fosc <= 20000000 )
    #define  EN_IAP  0x82          //系统时钟 <= 20MHz
#elif ( CPU_Fosc <= 24000000 )
    #define  EN_IAP  0x81          //系统时钟 <= 24MHz
#elif ( CPU_Fosc <= 30000000 )
    #define  EN_IAP  0x80          //系统时钟 <= 30MHz
#else
        #define  EN_IAP  0x80          //系统时钟 > 30MHz 默认
#endif

/********************************************************************
函数:IAP触发命令 + 禁止IAP操作(清IAP相关寄存器)
********************************************************************/
void Command_and_Close( void )
{
    #if( InterEA )  
        EA = 0; 
        #endif
                          
    IAP_TRIG = COM0_STC;                
    IAP_TRIG = COM1_STC;                  
    _nop_();
    _nop_(); 
    _nop_(); 
          
        #if( InterEA )
        EA = 1; 
        #endif
          
        IAP_CONTR = 0;    
    IAP_CMD   = 0;          
    IAP_TRIG  = 0;                   
    IAP_ADDRH = 0xFF;      
    IAP_ADDRL = 0xFF;              
}

/********************************************************************
函数:读指定地址一字节数据                   
输入:(地址) 
返回:(地址内容) 
********************************************************************/
uint8 EROM_R( uint16 addr )
{                      
    IAP_CONTR = EN_IAP;   
    IAP_CMD   = 1;                   //允许读取EEPROM
        IAP_ADDRL = addr;                
    IAP_ADDRH = addr >> 8;               
                  
    Command_and_Close();
          
    return IAP_DATA;                        
}

/********************************************************************
函数:向指定地址写一字节数据
输入:(地址,数据)
********************************************************************/
void EROM_W( uint16 addr, uint8 dat )
{     
    IAP_CONTR = EN_IAP;        
    IAP_CMD   = 2;                  //允许编写EEPROM
    IAP_ADDRL = addr;                
    IAP_ADDRH = addr >> 8;           
    IAP_DATA  = dat;
                                  
    Command_and_Close();    
}

/********************************************************************
函数:擦除指定扇区          
输入:(扇区号)
********************************************************************/
void EROM_C( uint8 n )
{           
        IAP_CONTR = EN_IAP; 
    IAP_CMD   = 3;            //允许擦除EEPROM     
    IAP_ADDRL = 0x00;                
    IAP_ADDRH = (EROM_Start>>8) + n*0x02; 
                                           
    Command_and_Close();
}

/********************************************************************
函数:连续读数据                   
输入:(起始地址,指针指向,字节长)
备注:最好不使用通用指针,明确指针指向数据类型可以减小代码和提高速度
********************************************************************/
void EROM_R_8( uint16 addr, uint8i *pr, uint16 size )
{                         
    while( size-- ) {  *pr++ = EROM_R( addr++ ); }                                    
}

/********************************************************************
函数:连续写数据
输入:(起始地址,指针指向,字节长)
备注:最好不使用通用指针,明确指针指向数据类型可以减小代码和提高速度
********************************************************************/
void EROM_W_8( uint16 addr, uint8i *pr, uint16 size )
{
    while( size-- ) {  EROM_W( addr++, *pr++ ); }                  
}                            
复制代码

  

posted @ 2018-01-01 00:09  XZHDJH  阅读(548)  评论(0)    收藏  举报