⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iap_sstmcu.c

📁 一个用SST单片机实现单字节FLASH数据存储代替EEPROM的实用例子
💻 C
字号:
/***********************************************************************************************************
* IAP_SSTMCU.c - SST89X564/554 SST89X516/58/54/52RD2的IAP在使用中编程的常用函数
*            弘微科技(SPAC)  田伯运    
*  	WEB: www.spacltd.com.cn 		TEL:0755-26010579   E-MAIL:andy.tian@spacltd.com.cn
* 功能介绍: 
   SST的MCU内部FLASH的基本操作函数,包括扇区擦除,字节编程,字节校验等常用函数,
  用户可根据这些基本功能,延伸出MCU的程序在线升级,数据存储等功能.
***********************************************************************************************************/

#include <SST89x5xxRD2.H>		//加入SST MCU单片机的头文件,这样就剩去了许多的特殊寄存器的声明
#include <stdio.h>
/***********************************************************************************************************
* 定义 SST单片机的各种IAP命令
***********************************************************************************************************/
#define SFCM_SE 0x0B; /* 扇区擦除命令字(Sector-Erase)为0X0B */
#define SFCM_VB 0x0C; /* 字节校验命令字(Byte-Verify)为0X0C */
#define SFCM_PB 0x0E; /* 字节校验命令字(Byte-Program)为0X0E */

/***********************************************************************************************************
* Function Prototype,用到的函数声明
***********************************************************************************************************/
void sector_erase(unsigned short int dataAddr);	//扇区擦除函数,擦除的地址为dataAddr
void byte_program(unsigned short int dataAddr, unsigned char dataByte);//字节编程函数
bit byte_modify(unsigned short int dataAddr,unsigned char dataByte)	;//修改一个地址单元的内容为dataByte
unsigned char byte_verify(unsigned short int dataAddr); //字节校验函数
unsigned char ready();		//检查是否擦除或编程的操作是否已经完成
void error();		//超时错误

extern unsigned char ErrorCode; /*FLASH编程的是否成功的标志,ErrorCode=0:IAP编程成功;ErrorCode=1:IAP编程失败;*/

/**************************** SST单片机的IAP函数  **********************************************/

/***********************************************************************************************************
*  扇区擦除函数--sector_erase(unsigned short int dataAddr)
*  输入参数:     dataAddr---擦除的扇区地址
***********************************************************************************************************/
void sector_erase(unsigned short int dataAddr)
{
unsigned short int destAddr = dataAddr;
	SFCF = SFCF | 0x40; // SFCF.6=1: IAP功能使能
	SFAH = destAddr>>8; // 将扇区地址的高8位装入FLASH的高8位地址寄存器(SFAH)中
	SFAL = destAddr; 	// 将扇区地址的低8位装入FLASH的低8位地址寄存器(SFAL)中
	SFAL = destAddr; 	// 将扇区地址的低8位装入FLASH的低8位地址寄存器(SFAL)中
	SFCM = SFCM_SE; 	// 在FLASH的命令寄存器(SFCM)中填入扇区擦除命令--SFCM_SE=0X0B
	if(!ready())		// 等待擦除完毕
		error();		// 等待超时--错误
	SFCF = SFCF & ~0x40; // SFCF.6=0: IAP功能禁止
	return;
}
/***********************************************************************************************************
* 字节编程函数---byte_program()
* 输入参数:     dataAddr---编程的字节地址
* 输入参数:     dataByte---编程的数据
***********************************************************************************************************/
void byte_program(unsigned short int dataAddr, unsigned char dataByte)
{
unsigned short int destAddr = dataAddr;
	SFCF = SFCF | 0x40; // SFCF.6=1: IAP功能使能
	SFAH = destAddr>>8; // 将扇区地址的高8位装入FLASH的高8位地址寄存器(SFAH)中
	SFAL = destAddr; 	// 将扇区地址的低8位装入FLASH的低8位地址寄存器(SFAL)中
	SFDT = dataByte; 	// 在FLASH的数据寄存器(SFDT)中填入编程的数据--dataByte
	SFCM = SFCM_PB; 	// 在FLASH的命令寄存器(SFCM)中填入字节编程命令--SFCM_PB=0X0E
	if(!ready())		// 等待编程完毕
		error();		// 等待超时--错误
	SFCF = SFCF & ~0x40; // SFCF.6=0: IAP功能禁止
	return;
}
/***********************************************************************************************************
* 字节校验读函数---byte_verify()
* 输入参数:     dataAddr---校验读的字节地址
* 返回参数:		readByte---读出的单元数值
***********************************************************************************************************/
unsigned char byte_verify(unsigned short int dataAddr)
{
unsigned short int destAddr = dataAddr;
unsigned char readByte;
	SFCF = SFCF | 0x40; // SFCF.6=1: IAP功能使能
	SFAH = destAddr>>8; // 将扇区地址的高8位装入FLASH的高8位地址寄存器(SFAH)中
	SFAL = destAddr; 	// 将扇区地址的低8位装入FLASH的低8位地址寄存器(SFAL)中
	SFCM = SFCM_VB; 	// 在FLASH的命令寄存器(SFCM)中填入字节校验命令--SFCM_PB=0X0E
	readByte = SFDT;	// 取得读到的单元数据
	SFCF = SFCF & 0xBF; // SFCF.6=0: 关闭IAP功能
	SFDT = 0;	
	return readByte;	//返回读到的数据
}
/***********************************************************************************************************
* 检查IAP操作是否完成函数---ready()
* 输入参数:  	无
* 返回参数:  	1--IAP操作(FLASH擦除或字节编程)完成成功标志
*				0--IAP操作超时错误退出
***********************************************************************************************************/
unsigned char ready()
{
	unsigned int TimeOut = 0;
	
	while (TimeOut < 1000)
		{
			if ((SFST&4) == 0) 		//SFST.2=0:IAP操作完成
			{ 
				SFCF = SFCF & 0xBF; //IAP操作完成,关闭IAP功能--SFCF.6=0 
				SFDT = 0; 			
				return 1; 			//返回成功标志--1
			}
			TimeOut++;
		}
		
	SFCF = SFCF & 0xBF; 			//时间超时,关闭IAP功能--SFCF.6=0
	SFDT = 0; 						/*any value other than 0x55*/
	return 0; 						//返回失败标志--0
}

/***********************************************************************************************************
* IAP操作失败指示函数,
***********************************************************************************************************/
void error()
{
	ErrorCode=1; 	//置IAP失败标志--ErrorCode=1
	//LED_ERR=0;		//点亮错误灯,关闭成功灯,表示编程出错失败.
	//LED_OK=1;
	while(1) 		//程序停止
	{}
}
/***********************************************************************************************************
* 字节编程函数---byte_modify()
* 输入参数:     dataAddr---编程的字节地址
* 输入参数:     dataByte---编程的数据
***********************************************************************************************************/
bit byte_modify(unsigned  int dataAddr, unsigned char dataByte)
{
	unsigned  int destAddr = dataAddr;
	unsigned  int Addr_Sector = destAddr & 0xff80;			//要修改数据所站的扇区的起始地址
	unsigned char temp,counter=0x80;								//作为计数器,一个扇区
	unsigned  char xdata Ram_Buffer[0x80];					//定义内部扩展RAM的0x80个单元作为一个扇区数据的缓冲区

	if(dataByte==(dataByte&(byte_verify(dataAddr))))		//如果要写的单元原来内容只需1->0的过程,而没有0->1的过程,
		{													//就不用擦除整个扇区,而只需使用字节编程命令即可,减少FLASH的擦写次数,延长FLASH的使用寿命
			byte_program(dataAddr,dataByte);				
			if (dataByte==byte_verify(dataAddr)) return 1;	//读出的数据等于要写的数据,返回1
				else return 0;								//读出的数据不等于要写的数据,返回0
			}
	else 										//如果有0->1的过程,就必须进行扇区擦除,将整个扇区的内容,重新写一遍.

	temp = AUXR;								//暂存AUXR辅助寄存器.以便用完128个RAM的BUFFER后恢复.
	AUXR  = 0x00;								//使用SST89E516内部的768 RAM,EXRAM=0,
	counter=0x80;								//一个扇区有128个存储单元,
	for (counter=0;counter<0x80;counter++)		//读一个扇区(128个字节)的内容到扩展RAM缓冲区中
		{
			Ram_Buffer[counter]=byte_verify(Addr_Sector);
			Addr_Sector++;
			}
	Ram_Buffer[destAddr&0x007f]=dataByte;		//在RAM缓冲区中写入新的修改后数据
	Addr_Sector=destAddr&0xff80;				//重新置要修改扇区的首地址
	sector_erase(Addr_Sector);					//将这个要修改单元所在的扇区进行全部擦除
	for (counter=0;counter<0x80;counter++)		//将修改后的扇区内容重新写回到这个扇区内
		{
			byte_program(Addr_Sector,Ram_Buffer[counter]);	//对扇区中的单元写入一个扇区更改后的内容
			Addr_Sector++;									//指向下一个地址单元
			}
	AUXR = temp;								//恢复为占用前的AUXR
	if (dataByte==byte_verify(dataAddr)) return 1;	//读出的数据等于要写的数据,返回1
	else return 0;									//读出的数据不等于要写的数据,返回0
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -