📄 iap_sstmcu.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 + -