stm32学习资料
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 rn"); } 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},0xb0},0x99},0x92},0x82},0xf8},0x80},0x90}, }; u8 const error1[][2]={ {0x86,{0x86, {0x86, }; u8 const error2[][3]={ {0x86, {0x86, }; 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 %drn",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 %drn",g_uHardwareType); printf("g_uiProductSn is %drn",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 %drn",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_apprn"); 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_mcurn");
} 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,u16 ); void ?STMFLASH_ReadHalfWord_buf(u32,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 %drn",pagenu); printf("Bytenu is %drn",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 %drn",buf[0]); printf(" read buf[1] is %drn",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 %drn",i); } } memset(WFlash_buf.UPdateW_buf,0x00,PAGE_SIZE); memcpy(WFlash_buf.UPdateW_buf,Bytenu); STMFLASH_WriteByte_buf(FlashAddr ?,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)] = ' ' ; printf("debugupdata is %srn",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 ? ? ? ? ? ? ? ? ? ?? } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |