STC8H 如何实现 IAP 存储浮点数(float 类型),并在必要的时候恢复
在STC8H单片机中实现IAP(In-Application Programming)存储和恢复浮点数(float类型)需要以下步骤:
核心思路:将float数据转换为字节流存入Flash,读取时再还原为float。STC8H的IAP操作需注意扇区擦除和字节写入的规范。
1. 准备工作
1.1 确认Flash特性
-
STC8H的Flash分为多个扇区(如512字节/扇区),写入前必须先擦除整个扇区(全FF状态)。
-
每次写入单位为 1字节,但需按扇区管理。
1.2 包含头文件
#include <STC8H.H>
#include <intrins.h> // 用于_nop_()延时
#include <string.h> // 用于memcpy
2. 关键函数实现
2.1 Flash解锁与配置
void IAP_Disable() {
IAP_CONTR = 0; // 关闭IAP功能
IAP_CMD = 0; // 清除命令
IAP_TRIG = 0; // 清除触发
IAP_ADDRH = 0xFF; // 重置地址
IAP_ADDRL = 0xFF;
}
void IAP_Enable() {
IAP_CONTR = 0x80; // 使能IAP,设置等待时间(根据时钟调整)
IAP_TPS = 12; // 假设系统时钟12MHz,参考手册配置
}
2.2 扇区擦除
void IAP_EraseSector(uint16_t addr) {
IAP_Enable();
IAP_CMD = 0x03; // 扇区擦除命令
IAP_ADDRH = (uint8_t)(addr >> 8);
IAP_ADDRL = (uint8_t)(addr & 0xFF);
IAP_TRIG = 0x5A; // 触发命令
IAP_TRIG = 0xA5;
_nop_();
IAP_Disable();
}
2.3 写入浮点数(转为字节流)
void IAP_WriteFloat(uint16_t addr, float value) {
uint8_t *p = (uint8_t *)&value; // 将float指针转为uint8_t指针
IAP_Enable();
IAP_CMD = 0x02; // 字节写入命令
for (uint8_t i = 0; i < 4; i++) {
IAP_ADDRH = (uint8_t)((addr + i) >> 8);
IAP_ADDRL = (uint8_t)((addr + i) & 0xFF);
IAP_DATA = p[i]; // 写入1字节
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
_nop_();
}
IAP_Disable();
}
2.4 读取浮点数(字节流还原)
float IAP_ReadFloat(uint16_t addr) {
float value;
uint8_t *p = (uint8_t *)&value;
IAP_Enable();
IAP_CMD = 0x01; // 字节读取命令
for (uint8_t i = 0; i < 4; i++) {
IAP_ADDRH = (uint8_t)((addr + i) >> 8);
IAP_ADDRL = (uint8_t)((addr + i) & 0xFF);
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5;
p[i] = IAP_DATA; // 读取1字节
_nop_();
}
IAP_Disable();
return value;
}
3. 使用示例
3.1 存储浮点数
#define FLASH_ADDR 0x0400 // 选择一个空闲扇区(需对齐扇区地址,如0x0400)
void main() {
float sensorValue = 3.14159;
// 步骤1:擦除目标扇区
IAP_EraseSector(FLASH_ADDR);
// 步骤2:写入float数据
IAP_WriteFloat(FLASH_ADDR, sensorValue);
// 步骤3:读取验证
float readValue = IAP_ReadFloat(FLASH_ADDR);
while (1);
}
3.2 恢复浮点数
float loadStoredFloat() {
return IAP_ReadFloat(FLASH_ADDR);
}
4. 注意事项
-
地址对齐:
-
确保写入地址不跨扇区,且位于空闲Flash区域(避开程序代码区)。
-
检查STC8H手册确认Flash大小(如8K/16K等)。
-
-
数据安全:
-
写入前必须擦除扇区,否则写入可能失败。
-
可添加CRC校验防止数据损坏。
-
-
性能优化:
-
批量存储时,建议一次性写入多个数据减少擦除次数。
-
若频繁写入,考虑磨损均衡算法(如EEPROM模拟库)。
-
-
时钟配置:
-
IAP_TPS需根据系统时钟频率设置(参考手册公式)。
-
5. 扩展建议
-
存储多个float:
将数据打包为结构体,用memcpy转换字节流:typedef struct { float data1; float data2; } SensorData; SensorData sd = {1.23, 4.56}; IAP_WriteBytes(FLASH_ADDR, (uint8_t *)&sd, sizeof(SensorData)); -
错误处理:
添加Flash操作状态检查(如STC8H的IAP_STATUS寄存器)。
通过上述方法,可可靠地在STC8H中实现浮点数的IAP存储与恢复。

浙公网安备 33010602011771号