feat: add STM32 four-channel weighing firmware

This commit is contained in:
FinleyHsu
2026-07-28 11:01:55 +08:00
commit 1282b9b77e
205 changed files with 80376 additions and 0 deletions
@@ -0,0 +1,459 @@
/*************************** (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*******************/