转: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++ ); }
}
复制代码

浙公网安备 33010602011771号