后臺有許多讀者留言說先弄點干貨。今天應讀者要求,我們先來一篇干貨。大家有什么要求,歡迎留言,關于MCU的應用、測試要求,我們都會盡量滿足。
在上兩期文章和視頻中,為了公平起見,所有的MCU使用的是同一個工程程序,(不同的MCU,時鐘和GPIO的配置略有不同,使用宏定義區分MCU),除了使用滴答時鐘和基本GPIO操作外,沒有任何抗干擾手段,全靠MCU內部自身的抗干擾能力進行的測試。結果,只有芯源CW32MCU沒有徹底死機外,其它均有死機現象。
這種死機現象,在我們實際開發產品時,是禁止發生的。為了對付這種干擾,除了硬件上有些技術對策,那軟件上又有些什么呢?
當然是我們最熟悉的看門狗了。“看門狗”這個神器在“古老的年代”51時期,那是沒有的,需要在外面加一個“昂貴”的芯片來實現。當然,現在新時代,所有的ARM MCU基本上都標配了看門狗外設。
看門狗是啥,我們來看一下,STM32芯片的用戶手冊,關于看門狗的介紹。
▲圖1
這里我們就不詳細展開其內容了。直接來看核心代碼。
//摘要: /* 系統時鐘,使用內部高速HSI倍數,系統時鐘為48M。 */ //Programed by Cache.Lee 2023.1.4 #include "stm32f0xx.h" #include "stm32f0xx_gpio.h" //GPIOA #define SEGA GPIO_Pin_10 #define SEGB GPIO_Pin_9 #define SEGC GPIO_Pin_8 //GPIOB #define SEGD GPIO_Pin_14 #define SEGE GPIO_Pin_15 //GPIOA #define SEGF GPIO_Pin_11 #define SEGG GPIO_Pin_12 //GPIOB #define SEGDP GPIO_Pin_13 //num:需要顯示的數字,no:0顯示左邊數碼管,1顯示右邊數碼管 void SEG_DisplayNum(unsigned int num, unsigned int no) { GPIO_ResetBits(GPIOA,0xffff);//關段碼、位碼 GPIO_ResetBits(GPIOB,0xffff);//關段碼、位碼 switch(num) //開段碼 { case 0: //ABCDEF GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGF); GPIO_SetBits(GPIOB,SEGD|SEGE); break; case 1: //BC GPIO_SetBits(GPIOA,SEGB|SEGC); break; case 2: //ABDEG GPIO_SetBits(GPIOA,SEGA|SEGB|SEGG); GPIO_SetBits(GPIOB,SEGD|SEGE); break; case 3: //ABCDG GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGG); GPIO_SetBits(GPIOB,SEGD); break; case 4://BCFG GPIO_SetBits(GPIOA,SEGF|SEGB|SEGC|SEGG); break; case 5://ACDFG GPIO_SetBits(GPIOA,SEGA|SEGC|SEGG|SEGF); GPIO_SetBits(GPIOB,SEGD); break; case 6: //ACDEFG GPIO_SetBits(GPIOA,SEGA|SEGC|SEGG|SEGF); GPIO_SetBits(GPIOB,SEGD|SEGE); break; case 7: //ABC GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC); break; case 8: //ABCDEFG GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF); GPIO_SetBits(GPIOB,SEGD|SEGE); break; case 9: //ABCDFG GPIO_SetBits(GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF); GPIO_SetBits(GPIOB,SEGD); break; case 10: //DP 顯示DP GPIO_SetBits(GPIOB,SEGDP); break; default: break; } if(no==1) GPIO_SetBits(GPIOB,GPIO_Pin_12); else GPIO_SetBits(GPIOB,GPIO_Pin_11);//關位碼 } void GPIOInit(void) { GPIO_InitTypeDef GPIO_InitStructure; //數碼管斷碼位碼 IO初始化 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_Init(GPIOB, &GPIO_InitStructure); } int main(void) { unsigned long i; unsigned int num=0; for(i=0;i<60000;i++); //上電延時 GPIOInit(); /* IWDG timeout equal to 250 ms (the timeout may varies due to LSI frequency dispersion) */ /* Enable write access to IWDG_PR and IWDG_RLR registers */ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* IWDG counter clock: LSI/32 */ IWDG_SetPrescaler(IWDG_Prescaler_32); /* Set counter reload value to obtain 250ms IWDG TimeOut. Counter Reload Value = 250ms/IWDG counter clock period = 250ms / (LSI/32) = 0.25s / (LsiFreq/32) = LsiFreq/(32 * 4) = LsiFreq/128 */ IWDG_SetReload(40000/128); /* Reload IWDG counter */ IWDG_ReloadCounter(); /* Enable IWDG (the LSI oscillator will be enabled by hardware) */ IWDG_Enable(); SEG_DisplayNum(10,1); for(i=0;i<60000;i++); while(1) { num++; if(num>=100)num=0; SEG_DisplayNum(num/10,0); for(i=0;i<60000;i++); //延時 SEG_DisplayNum(num%10,1); for(i=0;i<60000;i++); //延時 SEG_DisplayNum(num/10,0); for(i=0;i<60000;i++); //延時 IWDG_ReloadCounter(); //喂狗 SEG_DisplayNum(num%10,1); for(i=0;i<60000;i++); //延時 SEG_DisplayNum(num/10,0); for(i=0;i<60000;i++); //延時 SEG_DisplayNum(num%10,1); for(i=0;i<60000;i++); //延時 IWDG_ReloadCounter(); //喂狗 } }
這里的代碼與上期代碼不同,我們使用官方標準庫來重新編寫。其中數碼管的動態掃描沒有使用滴答時鐘,而是在主程序中直接用延時來完成。區別于之前的代碼,我們增加了獨立看門狗的功能。看門狗的喂狗操作在MAIN函數的大循環里,數碼管的動態掃描中實現。
當程序發生死機時,MAIN函數的大循環將暫停運行,數碼管隨機顯示最近一次數值,不進行動態掃描,所以,只有一位數碼管顯示。同時,喂狗暫停。當看門狗時間到,將發生看門狗復位操作,系統將重新復位運行。這樣程序就實現了看門狗復位功能。
在實驗中,由于打狗棒電壓干擾的威力巨大,STM32芯片被打壞了幾個引腳。驅動A、F、G的端口功能異常,而且芯片略燙,應該是引腳被打壞了。但不影響下載,其它位碼顯示正常。
除了看門狗復位,還有一種軟件復位方式。當MCU發生硬件失效時,會進入Hardfault中數函數。Hardfault是優先級別為-1的固定類型中斷,無需初始化設置。常常在MCU死機時,不知明的會進入Hardfault中斷。因此,在Hardfault中斷函數中,添加軟件復位功能也是一種防死機現象的方法。代碼如下:
void HardFault_Handler(void) { unsigned int j; /* Go to infinite loop when Hard Fault exception occurs */ while (1) { SEG_DisplayNum(10,0); for(j=0;j<60000;j++); for(j=0;j<60000;j++); for(j=0;j<60000;j++); for(j=0;j<60000;j++); for(j=0;j<60000;j++); for(j=0;j<60000;j++); NVIC_SystemReset(); } }
審核編輯黃宇
-
mcu
+關注
關注
146文章
17370瀏覽量
352914 -
看門狗
+關注
關注
10文章
566瀏覽量
70979 -
STM32
+關注
關注
2273文章
10928瀏覽量
357895 -
時鐘
+關注
關注
11文章
1748瀏覽量
131878 -
抗干擾
+關注
關注
4文章
319瀏覽量
34716
發布評論請先 登錄
相關推薦
“看門狗”VS“打狗棒”,誰勝誰負?(CW32篇)——MCU抗干擾實驗系列專題(4)
![“<b class='flag-5'>看門狗</b>”<b class='flag-5'>VS</b>“<b class='flag-5'>打狗棒</b>”,<b class='flag-5'>誰</b><b class='flag-5'>勝</b><b class='flag-5'>誰</b><b class='flag-5'>負</b>?(CW32<b class='flag-5'>篇</b>)——<b class='flag-5'>MCU</b><b class='flag-5'>抗干擾</b><b class='flag-5'>實驗</b><b class='flag-5'>系列</b><b class='flag-5'>專題</b>(4)](https://file.elecfans.com/web2/M00/8A/F8/poYBAGPGIZOATvvBAAOzOz6MGOE736.png)
MCU獨立看門狗和窗口看門狗的區別
![](https://file1.elecfans.com/web2/M00/87/B4/wKgaomRmlSmAYAw2AACDz14sc7s512.png)
STM32看門狗配置(獨立看門狗IWDG和窗口看門狗WWDG)
![<b class='flag-5'>STM32</b><b class='flag-5'>看門狗</b>配置(獨立<b class='flag-5'>看門狗</b>IWDG和窗口<b class='flag-5'>看門狗</b>WWDG)](https://file1.elecfans.com//web2/M00/A6/E1/wKgZomUMQQeANJA7AAAvqvkO9zw240.png)
MCU獨立看門狗與窗口看門狗的區別
![<b class='flag-5'>MCU</b>獨立<b class='flag-5'>看門狗</b>與窗口<b class='flag-5'>看門狗</b>的區別](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
MCU獨立看門狗與窗口看門狗的區別
![<b class='flag-5'>MCU</b>獨立<b class='flag-5'>看門狗</b>與窗口<b class='flag-5'>看門狗</b>的區別](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
【MCU】基于STM32CubeMX 實現窗口看門狗 WWDG
![【<b class='flag-5'>MCU</b>】基于<b class='flag-5'>STM32</b>CubeMX 實現窗口<b class='flag-5'>看門狗</b> WWDG](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
STM32學習心得十六:獨立看門狗實驗
![<b class='flag-5'>STM32</b>學習心得十六:獨立<b class='flag-5'>看門狗</b><b class='flag-5'>實驗</b>](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論