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 <string.h>

#include <stdio.h>



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 <string.h>

#include <stdio.h>



 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<NumToWrite;i++)

{

pBuffer[i] = (u8)(*(u32*)ReadAddr);

ReadAddr +=1;

}

}


void  STMFLASH_ReadHalfWord_buf(u32 ReadAddr, u16 *pBuffer,u16 NumToWrite)

{


u16 i;


for(i =0 ;i<NumToWrite;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<nSize; ++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<pagenu;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                     

}