stc8a的EEPROM.c


#include "config.h"
#include "EEPROM.h"

#define EE_ADDRESS1	0x0200

#define CMD_IDLE    0            
#define CMD_READ    1              
#define CMD_PROGRAM 2               
#define CMD_ERASE   3              

#define ENABLE_IAP 0x80           //if SYSCLK<30MHz
extern int   xdata g_x,g_y,g_z;		//ÍÓÂÝÒǽÃÕý²ÎÊý
extern float xdata a_x,a_y;			//½Ç¶È½ÃÕý²ÎÊý
extern float data AngleX,AngleY;

u8	xdata	tmp[20];

//========================================================================
// º¯Êý: void	DisableEEPROM(void)
// ÃèÊö: ½ûÖ¹·ÃÎÊISP/IAP.
// ²ÎÊý: non.
// ·µ»Ø: non.
// °æ±¾: V1.0, 2012-10-22
//========================================================================
void	DisableEEPROM(void)
{
	IAP_CONTR = 0;			//½ûÖ¹ISP/IAP²Ù×÷
	IAP_CMD   = 0;			//È¥³ýISP/IAPÃüÁî
	IAP_TRIG  = 0;			//·ÀÖ¹ISP/IAPÃüÁîÎó´¥·¢
	IAP_ADDRH = 0xff;		//Çå0µØÖ·¸ß×Ö½Ú
	IAP_ADDRL = 0xff;		//Çå0µØÖ·µÍ×Ö½Ú£¬Ö¸Ïò·ÇEEPROMÇø£¬·ÀÖ¹Îó²Ù×÷
}

//========================================================================
// º¯Êý: void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number)
// ÃèÊö: ´ÓÖ¸¶¨EEPROMÊ×µØÖ·¶Á³ön¸ö×Ö½Ú·ÅÖ¸¶¨µÄ»º³å.
// ²ÎÊý: EE_address:  ¶Á³öEEPROMµÄÊ×µØÖ·.
//       DataAddress: ¶Á³öÊý¾Ý·Å»º³åµÄÊ×µØÖ·.
//       number:      ¶Á³öµÄ×Ö½Ú³¤¶È.
// ·µ»Ø: non.
// °æ±¾: V1.0, 2012-10-22
//========================================================================

void EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number)
{
	F0 = EA;
	EA = 0;		//½ûÖ¹ÖжÏ
	IAP_CONTR = ENABLE_IAP;
	IAP_CMD   = CMD_READ;
	do
	{
		IAP_ADDRH = EE_address / 256;		//Ë͵ØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
		IAP_ADDRL = EE_address % 256;		//Ë͵ØÖ·µÍ×Ö½Ú
		IAP_TRIG  = 0x5a;	IAP_TRIG  = 0xa5;
		_nop_();
		*DataAddress = IAP_DATA;			//¶Á³öµÄÊý¾ÝËÍÍù
		EE_address++;
		DataAddress++;
	}while(--number);

	DisableEEPROM();
	EA = F0;		//ÖØÐÂÔÊÐíÖжÏ
}


/******************** ÉÈÇø²Á³ýº¯Êý *****************/
//========================================================================
// º¯Êý: void EEPROM_SectorErase(u16 EE_address)
// ÃèÊö: °ÑÖ¸¶¨µØÖ·µÄEEPROMÉÈÇø²Á³ý.
// ²ÎÊý: EE_address:  Òª²Á³ýµÄÉÈÇøEEPROMµÄµØÖ·.
// ·µ»Ø: non.
// °æ±¾: V1.0, 2013-5-10
//========================================================================
void EEPROM_SectorErase(u16 EE_address)
{
	F0 = EA;
	EA = 0;		//½ûÖ¹ÖжÏ
	IAP_ADDRH = EE_address / 256;			//ËÍÉÈÇøµØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
	IAP_ADDRL = EE_address % 256;			//ËÍÉÈÇøµØÖ·µÍ×Ö½Ú
	IAP_CONTR = ENABLE_IAP;
	IAP_CMD   = CMD_ERASE;
	IAP_TRIG  = 0x5a;	IAP_TRIG  = 0xa5;
	_nop_();
	DisableEEPROM();
	EA = F0;		//ÖØÐÂÔÊÐíÖжÏ
}

//========================================================================
// º¯Êý: void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
// ÃèÊö: °Ñ»º³åµÄn¸ö×Ö½ÚдÈëÖ¸¶¨Ê×µØÖ·µÄEEPROM.
// ²ÎÊý: EE_address:  дÈëEEPROMµÄÊ×µØÖ·.
//       DataAddress: дÈëÔ´Êý¾ÝµÄ»º³åµÄÊ×µØÖ·.
//       number:      дÈëµÄ×Ö½Ú³¤¶È.
// ·µ»Ø: non.
// °æ±¾: V1.0, 2012-10-22
//========================================================================
void EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number)
{
	F0 = EA;
	EA = 0;		//½ûÖ¹ÖжÏ
	IAP_CONTR = ENABLE_IAP;
	IAP_CMD   = CMD_PROGRAM;
	do
	{
		IAP_ADDRH = EE_address / 256;		//Ë͵ØÖ·¸ß×Ö½Ú£¨µØÖ·ÐèÒª¸Ä±äʱ²ÅÐèÖØÐÂË͵ØÖ·£©
		IAP_ADDRL = EE_address % 256;		//Ë͵ØÖ·µÍ×Ö½Ú
		IAP_DATA  = *DataAddress;			//ËÍÊý¾Ýµ½IAP_DATA£¬Ö»ÓÐÊý¾Ý¸Ä±äʱ²ÅÐèÖØÐÂËÍ
		IAP_TRIG  = 0x5a;	IAP_TRIG  = 0xa5;
		_nop_();
		EE_address++;
		DataAddress++;
	}while(--number);

	DisableEEPROM();
	EA = F0;		//ÖØÐÂÔÊÐíÖжÏ
}


void IAP_Gyro(void)   //ÍÓÂÝÒÇУ׼
{
	u8	i,j;
	((int *)&tmp)[0] = g_x;	//¶ÁÈ¡ÍÓÂÝÒÇÊý¾Ý
	((int *)&tmp)[1] = g_y; 
	((int *)&tmp)[2] = g_z;
	((int *)&tmp)[3] = 0x55aa;

	((float *)&tmp)[2] = a_x;
	((float *)&tmp)[3] = a_y;

	for(i=0,j=0; i<16; i++)	j += tmp[i];
	j = ~j + 1;
	tmp[i] = j;

	EEPROM_SectorErase(EE_ADDRESS1); //ÉÈÇø²Á³ý
	EEPROM_write_n(EE_ADDRESS1, tmp, 17);
}

void IAPRead(void)		//¶ÁÈ¡ÍÓÂÝÒǾ²²î
{
	u8	i,j;

	EEPROM_read_n(EE_ADDRESS1, tmp, 17);
	for(i=0,j=0; i<17; i++)	j += tmp[i];

	if((j == 0) && (((int *)&tmp)[3] == 0x55aa))		//ÅжÏÊý¾ÝÊÇ·ñÒѾ­¸üйý£¬¸üйý²Å¶ÁÈ¡Êý¾Ý
	{
		g_x = ((int *)&tmp)[0];
		g_y = ((int *)&tmp)[1];
		g_z = ((int *)&tmp)[2];
		a_x = ((float *)&tmp)[2];
		a_y = ((float *)&tmp)[3];
	}
	else
	{
		g_x = 0;
		g_y = 0;
		g_z = 0;
		a_x = 0;
		a_y = 0;
	}

}


STC8单片机读写内部EEPROM KEIL工程文件源码: /* STC8 内部EEPROM测试 从手册717页上可以看出 STC8的 EEPROM空间为1k 地址在0000h-03ffh 地址也是1024的大小 次程序结合手册 编写 大同小异 程序的主要目的是 先清楚地址0 到512 (一个扇区)的数据 然后读取 清楚扇区的数据 如果清楚成功 则读到的数据都为0xff 然后在向里写入 1-ff 1-ff 512个这样的字节 然后在读里面的字节 判断是否和写入的一样 整个过程都是通过串口在不停的上传给电脑 重点强调 更新数据一定是要先擦除整个扇区 才能更新 这是和外部E2的比较大的区别 但是和flash的写法差不多 要求 下载时 STC8 内部晶振为11.0592 电脑打开串口的波特率为9600 */ #include "stc8.h" #define u8 unsigned char #define u16 unsigned int #define CMD_IDLE 0 //空闲模式 #define CMD_READ 1 //IAP字节读命令 #define CMD_PROGRAM 2 //IAP字节编程命令 #define CMD_ERASE 3 //IAP字节擦除命令 #define ENABLE_IAP 0X82 //if SYSCLK<20MHz //测试地址 #define IAP_ADDRESS 0X0000 //从手册上可以看出 STC15F2K60S2的EEPROM地址是0x0000- 0x03ff 正好是1k的地址空间 sbit led=P5^5; //P3.5口LED灯定义 //延时函数 void delay(u8 n) { while(n--); } //关闭IAP void IapIdle() { IAP_CONTR=0; //关闭IAP功能 IAP_CMD =0; //清除命令寄存器 IAP_TRIG =0; //清楚触发寄存器 IAP_ADDRH=0X80; //将地址设置到非IAP区域 IAP_ADDRL=0; } //从ISP/IAP/EEPROM区域读取一个字节 u8 IapReadByte(u16 addr) { u8 dat; //数据缓冲区 IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_READ; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 dat=IAP_DATA; //读ISP/IAP/EEPROM数据 IapIdle(); //关闭IAP功能 return dat; //返回 } //写一个字节数据到ISP/IAP/EEPROM区域 void IapProgramByte(u16 addr,u8 dat) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_PROGRAM; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_DATA=dat; //写ISP/IAP/EEPROM数据 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 IapIdle(); //关闭IAP功能 } //扇区擦除 void IapEraseSector(u16 addr) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_ERASE; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDR
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值