main.c
#include "stm32f10x.h"
#include "RS232_module.h"
#include "RS485_module.h"
#include "Display_module.h"
#include "Flash_module.h"
#include "Progess_module.h"
#include "System_module.h"
#include "Iwdg_hard_dri.h"
#include
#include
int main(void)
{
//系统初始化
STM32APP_Init();
//初始化看门狗4s
IWDG_Init(6,625);
//模块初始化
Ds_NetInit();
Ds_TimInit();
Ds_DisplayInit();
//获取复位状态
Ds_GetRest();
//获取序列号
Ds_GetXULIEversions();
if(memcmp((u32*)ARMAPP_upstatus,"SUCCESS_UPDATA_M3APP",20) == 0)
{
//升级成功
g_bSendARMUpdateStatusFlag = TRUE;
g_bARMUpdateStatus = 0xAA;
printf("updata m3 app is sucess \r\n");
}
STMFLASH_ERASEBANK(ARMAPP_upstatus);
while(1)
{
if(UPMCU_FLAG == TRUE)
{
RS485_TX_ENABLE; //关掉串口接收485数据
Ds_UPDATAMCU(); //升级mcu
Rs485_Init_Flag = TRUE; //清除485缓冲区
RS485_RX_ENABLE; //使能串口接收485
UPMCU_FLAG = FALSE;
}
else
{
//300ms
if(Tim_to_Dispalystate == TRUE)
{
Ds_M3Display();
Tim_to_Dispalystate = FALSE;
}
//100ms
if(Tim_to_gate485state == TRUE)
{
Get_Rs485_State();
Tim_to_gate485state = FALSE;
}
//20ms
if(Tim_to_gate232state == TRUE)
{
Get_Rs232_State();
Tim_to_gate232state = FALSE;
}
}
//喂狗
IWDG_Feed();
}
}
Progess_module.c
#include "stm32f10x.h"
#include "RS232_module.h"
#include "RS232_commun.h"
#include "RS485_module.h"
#include "Tim_module.h"
#include "Display_module.h"
#include "Printf_Select.h"
#include "Flash_module.h"
#include "System_module.h"
#include "Time_hard_dri.h"
#include "Iwdg_hard_dri.h"
#include "Display_module.h"
#include "ProductTypedef.h"
#include
#include
u8 const work[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xa1,0x86,0x8e
};
u8 const pro1[][2]={
{0x8c,0xc0},{0x8c,0xf9},
{0x8c,0xa4},{0x8c,0xb0},
{0x8c,0x99},{0x8c,0x92},
{0x8c,0x82},{0x8c,0xf8},
{0x8c,0x80},{0x8c,0x90},
};
u8 const error1[][2]={
{0x86,0xc0},{0x86,0xf9},
{0x86,0xa4},{0x86,0xb0},
{0x86,0x99},{0x86,0x92},
{0x86,0x82},{0x86,0xf8},
{0x86,0x80},{0x86,0x90},
};
u8 const error2[][3]={
{0x86,0xf9,0xc0},
{0x86,0xf9,0xf9},
};
u8 error_pos;
u8 pro_pos;
u8 Dispos_tim;
u8 ba_pos;
void Ds_NetInit(void)
{
RS232_Init(UART_Fir); //初始化232 UART1
Rs485_Init_Flag = TRUE;//先清除485缓冲
RS485_RX_ENABLE; //使能485 接收
RS485_Init(UART_Sec); //初始化485 UART2
Printf_Debug_Init(UART_Thou); //初始化调试口 UART4
}
void Ds_TimInit(void)
{
Tim_select_Init(Tim_Thr); //3//1.8s RS232心跳
Tim_select_Init(Tim_tw); // 20ms获取一次状态 232
Tim_select_Init(Tim_Fou); //100ms获取一次状态485
Tim_select_Init(Tim_Five); //300ms 更新 显示 18s RS232 通讯故障 9s云灯故障 升级mcu 3s超时
}
void Ds_DisplayInit(void)
{
CD4094_Init();//显示初始化
LED_Init(); //灯初始化
LED_STATE_OFF; //状态灯亮
LED_ERROR_OFF;//故障灯亮
LED_CLOUD_OFF; //云灯亮
LED_UPdata_ON; //电源指示灯亮
g_uCurrentKeyRelatedLevel = 0; //档位初始为0
Cd4094DataOutPut(work[g_uCurrentKeyRelatedLevel ]); //显示0档待机
}
//NRST引脚上的低电平复位
int Ds_ResetSelect(void)
{
if(RCC_GetFlagStatus(RCC_FLAG_IWDGRST) == SET) //看门狗复位
return 11 ;
if(RCC_GetFlagStatus(RCC_FLAG_PINRST) == SET) //引脚复位
return 1;
if(RCC_GetFlagStatus(RCC_FLAG_LPWRRST) == SET) //低电平复位
return 12;
if(RCC_GetFlagStatus(RCC_FLAG_PORRST) == SET) //POR/PDR复位
return 3;
return 4;
}
void Ds_GetRest(void)
{
M3Risk.ucChildRisk = Ds_ResetSelect();
// printf("reset is %d\r\n",M3Risk.Risk_nu);
if(M3Risk.ucChildRisk !=1)
M3Risk.Risk_nu = 1;
else
M3Risk.Risk_nu = 0;
}
void Ds_GetXULIEversions(void)
{
STMFLASH_ReadByte_buf(BACK_M3DAT_ADDR_START ,M3_XULIEversions,5);
g_uHardwareType = M3_XULIEversions[0];
memcpy(&g_uiProductSn,&M3_XULIEversions[1],4);
printf("g_uHardwareType is %d\r\n",g_uHardwareType);
printf("g_uiProductSn is %d\r\n",g_uiProductSn);
if((M3_XULIEversions[0] == 255) && (M3_XULIEversions[1] == 255) && (M3_XULIEversions[2] == 255)
&&(M3_XULIEversions[3] == 255)&&(M3_XULIEversions[4] == 255))
{
g_uHardwareType = HardwareType;
g_uiProductSn = ProductSn;
printf("g_uHardwareType is %d\r\n",g_uHardwareType);
printf("g_uiProductSn is %d\r\n",g_uiProductSn);
}
}
void Ds_UPDATAMCU(void)
{
IWDG_Feed();//喂狗
LED_UPdata_ON;
LED_ERROR_ON;//
LED_CLOUD_ON; //
LED_STATE_ON;
TIM2_Stop(); //关掉获取232状态
TIM4_Stop(); //关掉获取485状态
TIM3_Stop(); //停止心跳
printf("main is into upmcu_app\r\n");
if(UPMCUCFI_FLAG == TRUE)
{
UPDATA_MCUAPP(BACK_MCUDAT_ADDR_START); //升级机芯配置
UPMCUCFI_FLAG = FALSE;
}
else
{
UPDATA_MCUAPP(BACK_MCUAPP_ADDR_START); //升级机芯程序
}
IWDG_Feed();//喂狗
Tim_select_Init(Tim_Thr); //3//1.8s心跳
Tim_select_Init(Tim_tw); // 20ms获取一次状态 232
Tim_select_Init(Tim_Fou); //100ms获取一次状态485
LED_STATE_OFF; //状态灯亮
LED_ERROR_OFF;//故障灯灭
LED_CLOUD_OFF; //云灯灭
LED_UPdata_ON; //电源指示指示灯
g_uCurrentKeyRelatedLevel = 0; //档位初始为0
Cd4094DataOutPut(work[g_uCurrentKeyRelatedLevel]); //显示0档待机
printf("leve updata_mcu\r\n");
}
void Dis_FEpos(void)
{
Dispos_tim ++;
if(Dispos_tim >= 2)
{
Dispos_tim = 0;
error_pos ++;
if(error_pos >= ba_pos)
error_pos = 0;
}
}
void Dis_FPpos(void)
{
Dispos_tim ++;
if(Dispos_tim >= 2)
{
Dispos_tim = 0;
pro_pos ++;
if(pro_pos >= ba_pos)
pro_pos = 0;
}
}
void Dis_ErrorInit(void)
{
Dis_c = 0;
Dis_e = 0;
Dispos_tim = 0;
error_pos = 0;
if(Error_value <= 9)
{
ba_pos = 2;
CD4094_Changeshow(error1[Error_value ][error_pos]);
Error_or_pro_lcd();
}
else
{
ba_pos = 3;
CD4094_Changeshow(error2[Error_value - 10 ][error_pos]);
Error_or_pro_lcd();
}
Dis_FEpos();
}
void Dis_PorInit(void)
{
Dis_c = 0;
Dis_e = 0;
Dispos_tim = 0;
pro_pos = 0;
ba_pos = 2;
CD4094_Changeshow(pro1[Pro_value ][pro_pos]);
Error_or_pro_lcd();
Dis_FPpos();
}
void Dis_ProProgess(void)
{
CD4094_Changeshow(pro1[Pro_value][pro_pos]);
Error_or_pro_lcd();
Dis_FPpos();
}
void Dis_ErrorProgess(void)
{
switch(ba_pos)
{
case 2:
CD4094_Changeshow(error1[Error_value ][error_pos]);
Error_or_pro_lcd();
break;
case 3:
CD4094_Changeshow(error2[Error_value - 10][error_pos]);
Error_or_pro_lcd();
break;
}
Dis_FEpos();
}
void Ds_M3Display(void)
{
static SysState_S prestate;
static u8 pretKeyRelatedLevel = 0;
switch(Rs232Sate.eMainState)
{
case IDLE_STATE:
switch(prestate.eMainState)
{
case IDLE_STATE:
break;
default:
LED_STATE_OFF;
LED_ERROR_OFF;
Cd4094DataOutPut(work[0]); //显示0档待机
break;
}
break;
case WORKING_STATE:
switch(prestate.eMainState)
{
case WORKING_STATE:
if(pretKeyRelatedLevel != g_uCurrentKeyRelatedLevel )
{
Cd4094DataOutPut(work[g_uCurrentKeyRelatedLevel]);
pretKeyRelatedLevel = g_uCurrentKeyRelatedLevel;
}
break;
default:
LED_STATE_ON;
LED_ERROR_OFF;
Cd4094DataOutPut(work[g_uCurrentKeyRelatedLevel]);
pretKeyRelatedLevel = g_uCurrentKeyRelatedLevel;
break;
}
break;
case PRO_STATE:
#if (STM32_15KWCOOK ||STM32_15KWSOUP)
switch(Rs232Sate.ucChildState)
{
case NO_PAN_PRO:
switch(prestate.eMainState)
{
case PRO_STATE:
CD4094_Changeshow(work[g_uCurrentKeyRelatedLevel]);
Nopan_Pro_lcd();
break;
default:
Dis_c = 0;
Dis_p = 0;
break;
}
break;
default:
switch(prestate.eMainState)
{
case PRO_STATE:
Dis_ProProgess();
break;
default:
Dis_PorInit();
break;
}
break;
}
#elif STM32_20KWCOOK
switch(prestate.eMainState)
{
case PRO_STATE:
Dis_ProProgess();
break;
default:
Dis_PorInit();
break;
}
#endif
break;
case ERROR_STATE:
switch(prestate.eMainState)
{
case ERROR_STATE:
Dis_ErrorProgess();
break;
default:
Dis_ErrorInit();
break;
}
break;
default :
break;
}
prestate = Rs232Sate;
}
#include "stm32f10x.h"
#include "System_module.h"
#include "Flash_module.h"
void MYRCC_DeInit(void)
{
RCC->APB1RSTR = 0x00000000;//复位结束
RCC->APB2RSTR = 0x00000000;
RCC->AHBENR = 0x00000014; //睡眠模式闪存和SRAM时钟使能.其他关闭.
RCC->APB2ENR = 0x00000000; //外设时钟关闭.
RCC->APB1ENR = 0x00000000;
RCC->CR |= 0x00000001; //使能内部高速时钟HSION
RCC->CFGR &= 0xF8FF0000; //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
RCC->CR &= 0xFEF6FFFF; //复位HSEON,CSSON,PLLON
RCC->CR &= 0xFFFBFFFF; //复位HSEBYP
RCC->CFGR &= 0xFF80FFFF; //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
RCC->CIR = 0x00000000; //关闭所有中断
//配置向量表
}
void Stm32_Clock_Init(u8 PLL)
{
unsigned char temp=0;
// MYRCC_DeInit(); //复位并配置向量表
RCC->CR|=0x00010000; //外部高速时钟使能HSEON
while(!(RCC->CR>>17));//等待外部时钟就绪
RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
PLL-=2;//抵消2个单位
RCC->CFGR|=PLL<<18; //设置PLL值 2~16
RCC->CFGR|=1<<16; //PLLSRC ON
FLASH->ACR|=0x32; //FLASH 2个延时周期
RCC->CR|=0x01000000; //PLLON
while(!(RCC->CR>>25));//等待PLL锁定
RCC->CFGR|=0x00000002;//PLL作为系统时钟
while(temp!=0x02) //等待PLL作为系统时钟设置成功
{
temp=RCC->CFGR>>2;
temp&=0x03;
}
}
#define IAP_ADDR 0X08000000
void IapProgramRun(void)
{
u32 IapSpInitVal; //IAP程序的SP初值.
u32 IapJumpAddr; //IAP程序的跳转地址.即,IAP程序的入口.
void (*pIapFun)(void); //定义一个函数指针.用于指向APP程序入口.
MYRCC_DeInit(); //恢复NVIC为复位状态.使中断不再发生.
IapSpInitVal = *(u32 *)IAP_ADDR; //取APP的SP初值.
IapJumpAddr = *(u32 *)(IAP_ADDR + 4); //取程序入口.
__set_MSP (IapSpInitVal); //设置SP.
pIapFun = (void (*)(void))IapJumpAddr; //生成跳转函数.
(*pIapFun) (); //跳转.不再返回.
}
void STM32APP_Init(void)
{
MYRCC_DeInit();
NVIC_SetVectorTable (NVIC_VectTab_FLASH, RUN_M3APP_VECTABLE); //设置APP的向量表
Stm32_Clock_Init(Clock_72MHZ); //72mhz
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
}
#include "stm32f10x.h"
#include "Flash_module.h"
void STMFLASH_WriteByte_buf(u32 addr , u8 *p , u16 Byte_Num)
{
u16 HalfWord;
u16 byte_nu;
byte_nu = Byte_Num%2;
Byte_Num = Byte_Num/2;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(addr);
while(Byte_Num --)
{
HalfWord=*(p);
HalfWord|=*(p+1)<<8;
FLASH_ProgramHalfWord(addr, HalfWord);
addr += 2;
p+=2;
}
if( byte_nu>0)
{
HalfWord = *p;
FLASH_ProgramHalfWord(addr, HalfWord);
}
FLASH_Lock();
}
void STMFLASH_WriteHalfWord_buf(u32 addr , u16 *p , u16 Byte_Num)
{
u16 HalfWord;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(addr);
while(Byte_Num --)
{
HalfWord=*(p++);
FLASH_ProgramHalfWord(addr, HalfWord);
addr += 2;
}
FLASH_Lock();
}
void STMFLASH_ReadByte_buf(u32 ReadAddr, u8 *pBuffer,u16 NumToWrite)
{
u16 i;
for(i =0 ;i { pBuffer[i] = (u8)(*(u32*)ReadAddr); ReadAddr +=1; } } void STMFLASH_ReadHalfWord_buf(u32 ReadAddr, u16 *pBuffer,u16 NumToWrite) { u16 i; for(i =0 ;i { pBuffer[i] = (u16)(*(u32*)ReadAddr); ReadAddr +=2; } } void STMFLASH_ERASEBANK(u32 bankaddr) { u16 i = 100; FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); FLASH_ErasePage(bankaddr); while(i--); FLASH_Lock(); } #ifndef __FASH_MODULE__ #define __FASH_MODULE__ #include "stm32f10x.h" #define STM32_FLASH_BASE 0x08000000 #define STM32_FLASH_SIZE 512 // 单位k #define OneKbit 1024 #define PAGE_SIZE 2048 #define PAGE_NU 255 #define BOOTLOADER_ADDR_START 0x08000000 #define RUN_M3APP_VECTABLE 0x00010000 #define BOOTLOADER_VECTABLE 0x0 #define RUN_M3APP_ADDR_START 0x08010000 // 0x08010 000 --- 0x0802 8FFF #define RUN_M3APP_PAGE_SIZE ( PAGE_SIZE * 50 ) #define RUN_M3DAT_ADDR_START 0x08029000 //0x0802 9000---- 0X0802 B7FF #define RUN_M3DAT_PAGE_SIZE ( PAGE_SIZE * 5 ) #define BACK_M3APP_ADDR_START 0x0802b800 #define BACK_M3APP_PAGE_SIZE ( PAGE_SIZE * 50 ) #define BACK_M3DAT_ADDR_START 0x08044800 #define BACK_M3DAT_PAGE_SIZE ( PAGE_SIZE * 5 ) #define BACK_MCUAPP_ADDR_START 0x08047000 #define BACK_MCUAPP_PAGE_SIZE ( PAGE_SIZE * 50 ) #define BACK_MCUDAT_ADDR_START 0x08060000 #define BACK_MCUDAT_PAGE_SIZE ( PAGE_SIZE * 5 ) #define ARMAPP_upstatus 0x08062800 #define ARMAPP_upstatus_PAGE_SIZE ( PAGE_SIZE *1) #define ARMCFG_upstatus 0x08063000 #define ARMCFG_upstatus_PAGE_SIZE ( PAGE_SIZE *1) #define PRODUCT_ID_MAX_SIZE 5 //max size of all product device #define RS485_RECE_MAX ( PAGE_SIZE *20) void STMFLASH_WriteByte_buf(u32 , u8 * , u16 ); void STMFLASH_WriteHalfWord_buf(u32 , u16 * , u16 ); void STMFLASH_ReadByte_buf(u32 , u8 *,u16 ); void STMFLASH_ReadHalfWord_buf(u32 , u16 *,u16 ); void STMFLASH_ERASEBANK(u32 ); typedef enum RS485_UPdatetype { ARMAPP, }RS485_UPdatetype_E; typedef struct UpdateFilePacket_Stru { u8 ucDevType; //cmd type define in UplinkCmdType_E u32 uiTotalLen; //total len of update file u32 uiLenOffset; //total len of update file int uinDataPackNum; u8 bufProductID[PRODUCT_ID_MAX_SIZE];//product NO. + SN u32 uiFileNameLen; //len of update file name u8 pFileName[60]; //update file name u8 pDataBuf[RS485_RECE_MAX]; //data of file }UpdateFilePacket_S; typedef struct FlashW_buf { u8 UPdateW_buf[ PAGE_SIZE]; u16 UPdateW_Pagenu; u16 UPdateW_Bytenu; }upFlashW_buf; #endif #include "stm32f10x.h" #include "CRC16.h" u16 GetCRC16Code( u8 *pCalcBuf,u32 nSize) { u32 i = 0; u32 j = 0; u16 usReturnValue = 0xFFFF; u16 usNew = 0xA001; for (i=0; i { usReturnValue ^= pCalcBuf[i]; for(j=0; j<8; ++j) { if(usReturnValue & 0x0001) { usReturnValue >>= 1; usReturnValue ^= usNew; } else { usReturnValue >>= 1; } } } return usReturnValue; } void Write_Data_toFlash(u8 *File_RECEBUF ,u32 recelen ,u32 FlashAddr) { u8 i; u16 pagenu; u16 Bytenu; u16 upadte_statue[2]; u16 buf[2]; pagenu = recelen /PAGE_SIZE ; Bytenu = recelen % PAGE_SIZE; upadte_statue[0] = pagenu; upadte_statue[1] = Bytenu; printf("pagenu is %d\r\n" ,pagenu); printf("Bytenu is %d\r\n" , Bytenu); //喂狗 IWDG_Feed(); WFlash_buf.UPdateW_Pagenu = pagenu; WFlash_buf.UPdateW_Bytenu = Bytenu; STMFLASH_WriteHalfWord_buf(FlashAddr -4 , upadte_statue , 2 ); STMFLASH_ReadHalfWord_buf(FlashAddr -4 , buf, 2); printf(" read buf[0] is %d\r\n",buf[0]); printf(" read buf[1] is %d\r\n",buf[1]); #if 1 if(pagenu > 0) { for(i = 0;i { memcpy(WFlash_buf.UPdateW_buf,File_RECEBUF, PAGE_SIZE); STMFLASH_WriteByte_buf(FlashAddr , WFlash_buf.UPdateW_buf , PAGE_SIZE); File_RECEBUF +=PAGE_SIZE; FlashAddr +=PAGE_SIZE; printf("write paegnu is %d\r\n",i); } } memset(WFlash_buf.UPdateW_buf,0x00,PAGE_SIZE); memcpy(WFlash_buf.UPdateW_buf,File_RECEBUF, Bytenu); STMFLASH_WriteByte_buf(FlashAddr , WFlash_buf.UPdateW_buf , Bytenu); #endif } Write_Data_toFlash(g_sUpdateInfo.pDataBuf ,g_sUpdateInfo.uiTotalLen ,BACK_MCUAPP_ADDR_START); //写上升级标志 STMFLASH_WriteByte_buf(ARMAPP_upstatus ,updataM3status , strlen(updataM3status)); STMFLASH_ReadByte_buf(ARMAPP_upstatus , debugupdata,strlen(updataM3status)); debugupdata[strlen(updataM3status)] = '\0' ; printf("debugupdata is %s\r\n",debugupdata); RS485_delay(); NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x0); IapProgramRun(); //跳转向Bootloader #include "stm32f10x.h" #include "Iwdg_hard_dri.h" //初始化独立看门狗 //prer:分频数:0~7(只有低 3 位有效!) //分频因子=4*2^prer.但最大值只能是 256! //rlr:重装载寄存器值:低 11 位有效. //时间计算(大概):Tout=((4*2^prer)*rlr)/40 (ms). //prer 4 rlr 625 时间是1s void IWDG_Init(u8 prer,u16 rlr) { IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //①使能对寄存器 I 写操作 IWDG_SetPrescaler(prer); //②设置 IWDG 预分频值:设置 IWDG 预分频值 IWDG_SetReload(rlr); //②设置 IWDG 重装载值 IWDG_ReloadCounter(); //③按照 IWDG 重装载寄存器的值重装载 IWDG 计数器 IWDG_Enable(); //④使能 IWDG } //喂独立看门狗 void IWDG_Feed(void) { IWDG_ReloadCounter();//reload }