Files
GarbageCanCenter_Woer_stm/STM32_4路称重_Git提交精简工程/src/HARDWARE/STMFLASH/stmflash.c
T

460 lines
15 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*************************** (C) COPYRIGHT 2017 CXHY ****************************
* 文件名 stmflash.c
* 描 述 STM32-FLASH操作函数
* 版 本 V1.0
* 作 者 XuZhongPing
* 日 期 2017/07/23
*********************************************************************************/
#include "stmflash.h"
#include "stdio.h"
#include "delay.h"
#include "timer.h"
#include "gsm_gprs.h"
#include "data_typedef.h"
#if STM32_FLASH_SIZE < 256 //中容量和小容量的MCU一页的大小都为1K字节
#define STM_SECTOR_SIZE 1024 //一页字节数
#else
#define STM_SECTOR_SIZE 2048
#endif
uint16_t STMFLASH_BUF[STM_SECTOR_SIZE/2]; //用于保存一个扇区的数据缓存,擦除扇区时需先读取原来保存的数据,然后再重新写入
/*
***********************************************************************
* 函 数 名: STMFLASH_ReadHalfWord
* 功能说明: 读取指定地址的半字(16位数据)
* 形 参:faddr:读地址(此地址必须为2的倍数!!)
* 返 回 值: 对应地址保存的数据
***********************************************************************
*/
uint16_t STMFLASH_ReadHalfWord(uint32_t faddr)
{
return *(vu16*)faddr;
}
/*
***********************************************************************
* 函 数 名: STMFLASH_Write_NoCheck
* 功能说明: 不检查的向指定地址写入数据
* 形 参:WriteAddr:起始地址
* pBuffer:数据指针
* NumToWrite:半字(16位)数
* 返 回 值: 无
***********************************************************************
*/
void STMFLASH_Write_NoCheck(uint32_t WriteAddr, uint16_t *pBuffer, uint16_t NumToWrite)
{
uint16_t i;
for(i = 0; i < NumToWrite; i++)
{
FLASH_ProgramHalfWord(WriteAddr, pBuffer[i]);
WriteAddr += 2; //地址增加2.
}
}
/*
***********************************************************************
* 函 数 名: STMFLASH_Write
* 功能说明: 从指定地址开始写入指定长度的数据
* 形 参:WriteAddr:起始地址(此地址必须为2的倍数!!)
* pBuffer:数据指针
* NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
* 返 回 值: 无
***********************************************************************
*/
void STMFLASH_Write(uint32_t WriteAddr, uint16_t *pBuffer, uint16_t NumToWrite)
{
uint32_t secpos; //扇区地址
uint16_t secoff; //扇区内偏移地址(16位字计算)
uint16_t secremain; //扇区内剩余地址(16位字计算)
uint32_t offaddr; //去掉0X08000000后的地址
uint16_t i;
if((WriteAddr < STM32_FLASH_BASE) || (WriteAddr >= (STM32_FLASH_BASE + 1024*STM32_FLASH_SIZE)))return; //非法地址
FLASH_Unlock(); //解锁
offaddr = WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
secpos = offaddr/STM_SECTOR_SIZE; //扇区地址 0~127 for STM32F103RBT6
secoff = (offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.)
secremain = STM_SECTOR_SIZE/2 - secoff; //扇区剩余空间大小
if(NumToWrite <= secremain) //不大于该扇区范围
{
secremain = NumToWrite;
}
while(1)
{
STMFLASH_Read(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, STMFLASH_BUF, STM_SECTOR_SIZE/2); //读出整个扇区的内容
for(i = 0; i < secremain; i++) //校验数据
{
if(STMFLASH_BUF[secoff + i] != 0XFFFF)break; //需要擦除
}
if(i<secremain) //需要擦除
{
FLASH_ErasePage(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE); //擦除这个扇区
for(i = 0; i < secremain; i++) //复制要写入的数据
{
STMFLASH_BUF[i + secoff] = pBuffer[i];
}
STMFLASH_Write_NoCheck(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE, STMFLASH_BUF, STM_SECTOR_SIZE/2); //写入整个扇区
}else{ //写已经擦除了的,直接写入扇区剩余区间.
STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);
}
if(NumToWrite == secremain) //写入结束了
{
break;
}else{ //写入未结束
secpos++; //扇区地址增1
secoff = 0; //偏移位置为0
pBuffer += secremain; //指针偏移
WriteAddr += secremain; //写地址偏移
NumToWrite -= secremain; //字节(16位)数递减
if(NumToWrite > (STM_SECTOR_SIZE/2)) //下一个扇区还是写不完
{
secremain = STM_SECTOR_SIZE/2;
}else{ //下一个扇区可以写完了
secremain = NumToWrite;
}
}
}
FLASH_Lock(); //上锁
}
/*
***********************************************************************
* 函 数 名: STMFLASH_Read
* 功能说明: 从指定地址开始读出指定长度的数据
* 形 参:ReadAddr:起始地址
* pBuffer:数据指针
* NumToRead:半字(16位)数
* 返 回 值: 无
***********************************************************************
*/
void STMFLASH_Read(uint32_t ReadAddr, uint16_t *pBuffer, uint16_t NumToRead)
{
uint16_t i;
for(i = 0; i < NumToRead; i++)
{
pBuffer[i] = STMFLASH_ReadHalfWord(ReadAddr); //读取2个字节.
ReadAddr += 2; //偏移2个字节.
}
}
/*
***********************************************************************
* 函 数 名: STMFLASH_WriteHalfWord
* 功能说明: 向指定FLASH地址写入一个16位数据
* 形 参:WriteAddr:起始地址
* WriteData:要写入的数据
* 返 回 值: 无
***********************************************************************
*/
void STMFLASH_WriteHalfWord(uint32_t WriteAddr, uint16_t WriteData)
{
// STMFLASH_Write(WriteAddr, &WriteData, 1); //写入一个字(16位)
FLASH_ProgramHalfWord(WriteAddr, WriteData);
}
/*
***********************************************************************
* 函 数 名: DeviceConfigErase
* 功能说明: 擦除参数保存区的flash
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void DeviceConfigErase(uint32_t WriteAddr)
{
uint32_t secpos; //扇区地址
uint16_t secoff; //扇区内偏移地址(16位字计算)
uint32_t offaddr; //去掉0X08000000后的地址
if((WriteAddr < STM32_FLASH_BASE) || (WriteAddr >= (STM32_FLASH_BASE + 1024*STM32_FLASH_SIZE)))return; //非法地址
offaddr = WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
secpos = offaddr/STM_SECTOR_SIZE; //扇区地址 0~127 for STM32F103RBT6
FLASH_ErasePage(secpos * STM_SECTOR_SIZE + STM32_FLASH_BASE); //擦除这个扇区
}
/*
***********************************************************************
* 函 数 名: SaveDeviceConfig
* 功能说明: 保存设备配置的参数
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void SaveDeviceConfig(void)
{
uint8_t i = 0;
uint16_t uTempData = 0;
uint32_t flashSaveAddr = 0;
flashSaveAddr = FLASH_SAVE_ADDR;
printf("\r\nTime1 = %d\r\n", time_value);
FLASH_Unlock(); //解锁
DeviceConfigErase(FLASH_SAVE_ADDR);
//数据保存成功标志位
uTempData = 0xFFFF;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//设备操作密码
uTempData = (uint16_t)(setPassword >> 16);
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)setPassword;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//设备客户号
uTempData = (uint16_t)(setCustomerID >> 16);
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)setCustomerID;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//设备类型及通道数量
uTempData = (uint16_t)(setDeviceType << 8) | setDevChannelNumbers;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//第1路投口相关参数
uTempData = (uint16_t)(setDevChannel1Type << 8) | setDevChannel1DisDepthVal;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)(setDevChannel1DisMaxVal << 8) | setDevChannel1DisAlarmPercent;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//第2路投口相关参数
uTempData = (uint16_t)(setDevChannel2Type << 8) | setDevChannel2DisDepthVal;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)(setDevChannel2DisMaxVal << 8) | setDevChannel2DisAlarmPercent;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//第3路投口相关参数
uTempData = (uint16_t)(setDevChannel3Type << 8) | setDevChannel3DisDepthVal;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)(setDevChannel3DisMaxVal << 8) | setDevChannel3DisAlarmPercent;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//第4路投口相关参数
uTempData = (uint16_t)(setDevChannel4Type << 8) | setDevChannel4DisDepthVal;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)(setDevChannel4DisMaxVal << 8) | setDevChannel4DisAlarmPercent;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
flashSaveAddr += 24; //预留32个字节用于保存投口通道参数
//禁用IC卡用户功能和启用收运IC卡二维码功能标志位
uTempData = (uint16_t)(setDisableICCardFunStatus << 8) | setEnableCleanQRCodeStatus;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
//设备编号长度
STMFLASH_WriteHalfWord(flashSaveAddr, setDeviceIdLength);
flashSaveAddr += 2;
printf("\r\nTime2 = %d\r\n", time_value);
//设备编号
for(i = 0; i < 32; i+=2)
{
uTempData = (uint16_t)(setDeviceIdBuf[i] << 8) | setDeviceIdBuf[i+1];
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
}
printf("\r\nTime3 = %d\r\n", time_value);
//服务器IP地址及端口号
uTempData = (uint16_t)(setIpAddr0 << 8) | setIpAddr1;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
uTempData = (uint16_t)(setIpAddr2 << 8) | setIpAddr3;
STMFLASH_WriteHalfWord(flashSaveAddr, uTempData);
flashSaveAddr += 2;
STMFLASH_WriteHalfWord(flashSaveAddr, setIpPort);
flashSaveAddr += 2;
//标志参数保存完成
uTempData = 0x0A0B;
STMFLASH_WriteHalfWord(FLASH_SAVE_ADDR, uTempData);
FLASH_Lock(); //上锁
printf("\r\nTime4 = %d\r\n", time_value);
printf("\r\n参数保存成功!\r\n");
}
/*
***********************************************************************
* 函 数 名: GetDeviceConfig
* 功能说明: 取得设备配置参数
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
uint8_t GetDeviceConfig(void)
{
uint8_t i = 0;
uint16_t uTempData = 0;
uint32_t flashSaveAddr = 0;
flashSaveAddr = FLASH_SAVE_ADDR;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
if(uTempData == 0x0A0B)
{
//设备操作密码
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setPassword = uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setPassword = (setPassword << 16) | uTempData;
//设备客户号
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setCustomerID = uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setCustomerID = (setCustomerID << 16) | uTempData;
//设备类型
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDeviceType = uTempData >> 8;
setDevChannelNumbers = (uint8_t)uTempData;
//第1路投口相关参数
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel1Type = uTempData >> 8;
setDevChannel1DisDepthVal = (uint8_t)uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel1DisMaxVal = uTempData >> 8;
setDevChannel1DisAlarmPercent = (uint8_t)uTempData;
//第2路投口相关参数
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel2Type = uTempData >> 8;
setDevChannel2DisDepthVal = (uint8_t)uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel2DisMaxVal = uTempData >> 8;
setDevChannel2DisAlarmPercent = (uint8_t)uTempData;
//第3路投口相关参数
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel3Type = uTempData >> 8;
setDevChannel3DisDepthVal = (uint8_t)uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel3DisMaxVal = uTempData >> 8;
setDevChannel3DisAlarmPercent = (uint8_t)uTempData;
//第4路投口相关参数
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel4Type = uTempData >> 8;
setDevChannel4DisDepthVal = (uint8_t)uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDevChannel4DisMaxVal = uTempData >> 8;
setDevChannel4DisAlarmPercent = (uint8_t)uTempData;
flashSaveAddr += 24;
//禁用IC卡用户功能和启用收运IC卡二维码功能标志位
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDisableICCardFunStatus = uTempData >> 8;
setEnableCleanQRCodeStatus = (uint8_t)uTempData;
//设备编号长度
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDeviceIdLength = uTempData;
//设备编号
for(i = 0; i < 32; i+=2)
{
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setDeviceIdBuf[i] = uTempData >> 8;
setDeviceIdBuf[i+1] = (uint8_t)uTempData;
}
//服务器IP地址及端口号
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setIpAddr0 = uTempData >> 8;
setIpAddr1 = (uint8_t)uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setIpAddr2 = uTempData >> 8;
setIpAddr3 = (uint8_t)uTempData;
uTempData = STMFLASH_ReadHalfWord(flashSaveAddr);
flashSaveAddr += 2;
setIpPort = uTempData;
printf("\r\n参数读取成功!\r\n");
printf("\r\nSet P=%d; ID=%d; Type=%d; Cnt=%d; T1=%d, h1=%d, H1=%d, A1=%d; T2=%d, h2=%d, H2=%d, A2=%d, ICE=%d; ICQR=%d; "\
"devLen=%d; devID=%s; IP=%d.%d.%d.%d:%d\r\n",
setPassword,
setCustomerID,
setDeviceType,
setDevChannelNumbers,
setDevChannel1Type, setDevChannel1DisDepthVal, setDevChannel1DisMaxVal, setDevChannel1DisAlarmPercent,
setDevChannel2Type, setDevChannel2DisDepthVal, setDevChannel2DisMaxVal, setDevChannel2DisAlarmPercent,
setDisableICCardFunStatus,
setEnableCleanQRCodeStatus,
setDeviceIdLength,
setDeviceIdBuf,
setIpAddr0,setIpAddr1,setIpAddr2,setIpAddr3,setIpPort
);
return 0;
}else{
printf("\r\n还没有保存过设备参数!\r\n");
return 1;
}
}
/*
***********************************************************************
* 函 数 名: ResetDeviceConfig
* 功能说明: 恢复设备配置参数到出厂设置
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void ResetDeviceConfig(void)
{
FLASH_Unlock(); //解锁
DeviceConfigErase(FLASH_SAVE_ADDR);
FLASH_Lock(); //上锁
printf("\r\n设备配置参数已恢复成出厂设置!\r\n");
}
/******************** (C) COPYRIGHT 2017 CXHY *****END OF FILE*******************/