上一期文章,我們講了基于STM32的抗干擾方法:增加硬件失效時(shí)軟件復(fù)位及看門(mén)狗功能。這期我們將介紹基于CW32 的抗干擾問(wèn)題。
在1、2期文章和視頻中(可進(jìn)入”MCU研究實(shí)驗(yàn)室”公眾號(hào)查看原文),為了公平起見(jiàn),所有的MCU使用的是同一個(gè)工程程序,(不同的MCU,時(shí)鐘和GPIO的配置略有不同,使用宏定義區(qū)分MCU),除了使用滴答時(shí)鐘和基本GPIO操作外,沒(méi)有任何抗干擾手段,全靠MCU內(nèi)部自身的抗干擾能力進(jìn)行的測(cè)試。結(jié)果,只有芯源CW32 MCU沒(méi)有徹底死機(jī)外,其它均有死機(jī)現(xiàn)象。
這種死機(jī)現(xiàn)象,在我們實(shí)際開(kāi)發(fā)產(chǎn)品時(shí),是禁止發(fā)生的。為了對(duì)付這種干擾,除了硬件上有些技術(shù)對(duì)策,那軟件上又有些什么呢?
當(dāng)然是我們最熟悉的看門(mén)狗了。“看門(mén)狗”這個(gè)神器在“古老的年代”51時(shí)期,那是沒(méi)有的,需要在外面加一個(gè)“昂貴”的芯片來(lái)實(shí)現(xiàn)。當(dāng)然,現(xiàn)在新時(shí)代,所有的ARM MCU基本上都標(biāo)配了看門(mén)狗外設(shè)。
CW32在抗干擾測(cè)試時(shí),也偶有自身復(fù)位現(xiàn)象。當(dāng)然如果我們?cè)黾恿丝撮T(mén)狗抗干擾技術(shù),那設(shè)計(jì)出來(lái)的產(chǎn)品不是更穩(wěn)定嗎!
看門(mén)狗是啥呢,我們來(lái)看一下,CW32芯片的用戶手冊(cè),關(guān)于看門(mén)狗的介紹。
這里我們就不詳細(xì)展開(kāi)其內(nèi)容了。直接來(lái)看核心代碼:
//系統(tǒng)時(shí)鐘配置為48M HSI倍數(shù) #include "main.h" #include "cw32f030_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:需要顯示的數(shù)字,no:0顯示左邊數(shù)碼管,1顯示右邊數(shù)碼管 void SEG_DisplayNum(unsigned int num, unsigned int no) { GPIO_WritePin(CW_GPIOA,0xffff,GPIO_Pin_RESET);//關(guān)段碼、位碼 GPIO_WritePin(CW_GPIOB,0xffff,GPIO_Pin_RESET);// switch(num) //開(kāi)斷碼 { case 0: //ABCDEF GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGF,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET); break; case 1: //BC GPIO_WritePin(CW_GPIOA,SEGB|SEGC,GPIO_Pin_SET); break; case 2: //ABDEG GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGG,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET); break; case 3: //ABCDG GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGG,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD,GPIO_Pin_SET); break; case 4://BCFG GPIO_WritePin(CW_GPIOA,SEGF|SEGB|SEGC|SEGG,GPIO_Pin_SET); break; case 5://ACDFG GPIO_WritePin(CW_GPIOA,SEGA|SEGC|SEGG|SEGF,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD,GPIO_Pin_SET); break; case 6: //ACDEFG GPIO_WritePin(CW_GPIOA,SEGA|SEGC|SEGG|SEGF,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET); break; case 7: //ABC GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC,GPIO_Pin_SET); break; case 8: //ABCDEFG GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD|SEGE,GPIO_Pin_SET); break; case 9: //ABCDFG GPIO_WritePin(CW_GPIOA,SEGA|SEGB|SEGC|SEGG|SEGF,GPIO_Pin_SET); GPIO_WritePin(CW_GPIOB,SEGD,GPIO_Pin_SET); break; case 10: //DP 顯示DP GPIO_WritePin(CW_GPIOB,SEGDP,GPIO_Pin_SET); break; default: break; } if(no==1) PB12_SETHIGH();//開(kāi)位碼 else PB11_SETHIGH();//開(kāi)位碼 } void RCC_Configuration(void) { /* 0. HSI使能并校準(zhǔn) */ RCC_HSI_Enable(RCC_HSIOSC_DIV6); /* 1. 設(shè)置HCLK和PCLK的分頻系數(shù)*/ RCC_HCLKPRS_Config(RCC_HCLK_DIV1); RCC_PCLKPRS_Config(RCC_PCLK_DIV1); /* 2. 使能PLL,通過(guò)PLL倍頻到64MHz */ RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000, 6); // HSI 默認(rèn)輸出頻率8MHz __RCC_FLASH_CLK_ENABLE(); FLASH_SetLatency(FLASH_Latency_3); /* 3. 時(shí)鐘切換到PLL */ RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL); RCC_SystemCoreClockUpdate(48000000); } void GPIOInit(void) { GPIO_InitTypeDef GPIO_InitStruct; __RCC_GPIOB_CLK_ENABLE(); __RCC_GPIOA_CLK_ENABLE(); //數(shù)碼管斷碼位碼 IO初始化 GPIO_InitStruct.IT = GPIO_IT_NONE; //LED1 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pins = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_Init(CW_GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pins = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15; GPIO_Init(CW_GPIOB, &GPIO_InitStruct); } int main() { unsigned long i; unsigned int num=0; IWDT_InitTypeDef IWDT_InitStruct = {0}; for(i=0;i<60000;i++); //上電延時(shí) RCC_Configuration(); //時(shí)鐘配置 GPIOInit(); //數(shù)碼管GPIO初始化 //使用獨(dú)立看門(mén)狗功能 CW_SYSCTRL->APBEN1_f.IWDT = 1U; //使能IWDT模塊 IWDT_InitStruct.IWDT_ITState = ENABLE; IWDT_InitStruct.IWDT_OverFlowAction = IWDT_OVERFLOW_ACTION_INT; //溢出后產(chǎn)生中斷不復(fù)位 IWDT_InitStruct.IWDT_Pause = IWDT_SLEEP_PAUSE; IWDT_InitStruct.IWDT_Prescaler = IWDT_Prescaler_DIV4; IWDT_InitStruct.IWDT_ReloadValue = (IWDT_FREQ >> 2) / 1000 * 280 - 1; // 由于IWDT的時(shí)鐘為RC10K, 設(shè)置為280實(shí)際溢出時(shí)間為256ms左右 IWDT_InitStruct.IWDT_WindowValue = 0xFFF; IWDT_Init(&IWDT_InitStruct); IWDT_Cmd(); __disable_irq(); NVIC_EnableIRQ(WDT_IRQn); __enable_irq(); while(1) { num++; //一個(gè)循環(huán),數(shù)據(jù)加1 if(num>=100)num=0; //限數(shù)0-99 SEG_DisplayNum(num/10,0); //顯示數(shù)據(jù)十位 for(i=0;i<60000;i++); //延時(shí) SEG_DisplayNum(num%10,1); //顯示數(shù)據(jù)個(gè)位 for(i=0;i<60000;i++); //延時(shí) IWDT_Refresh(); //喂狗 SEG_DisplayNum(num/10,0); //顯示數(shù)據(jù)十位 for(i=0;i<60000;i++); //延時(shí) IWDT_Refresh(); //喂狗 SEG_DisplayNum(num%10,1); //顯示數(shù)據(jù)個(gè)位 for(i=0;i<60000;i++); //延時(shí) SEG_DisplayNum(num/10,0); //顯示數(shù)據(jù)十位 for(i=0;i<60000;i++); //延時(shí) IWDT_Refresh(); //喂狗 SEG_DisplayNum(num%10,1); //顯示數(shù)據(jù)個(gè)位 for(i=0;i<60000;i++); //延時(shí) IWDT_Refresh(); //喂狗 } } //CW32看門(mén)狗中斷函數(shù) void WDT_IRQHandler(void) { unsigned int j; if(CW_IWDT->SR & IWDT_SR_OV_Msk) { //獨(dú)立看門(mén)狗溢出發(fā)生 IWDT_ClearOVFlag(); /*清除標(biāo)志 */ while (1) { SEG_DisplayNum(10,1); //顯示右測(cè)數(shù)碼管的小數(shù)點(diǎn)位 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(); //軟件復(fù)位,系統(tǒng)重新運(yùn)行。 } } }
這里的代碼與1、2期代碼不同,我們使用官方標(biāo)準(zhǔn)庫(kù)來(lái)重新編寫(xiě)。其中數(shù)碼管的動(dòng)態(tài)掃描沒(méi)有使用滴答時(shí)鐘,而是在主程序中直接用延時(shí)來(lái)完成。區(qū)別于之前的代碼,我們?cè)黾恿霜?dú)立看門(mén)狗的功能。看門(mén)狗的喂狗操作在MAIN函數(shù)的大循環(huán)里,數(shù)碼管的動(dòng)態(tài)掃描中實(shí)現(xiàn)。
當(dāng)程序發(fā)生死機(jī)時(shí),MAIN函數(shù)的大循環(huán)將暫停運(yùn)行,數(shù)碼管隨機(jī)顯示最近一次數(shù)值,不進(jìn)行動(dòng)態(tài)掃描,所以,只有一位數(shù)碼管顯示。同時(shí),喂狗暫停。
看門(mén)狗的代碼配置為產(chǎn)生中斷不復(fù)位。與STM32不同,看門(mén)狗可以停止復(fù)位,先進(jìn)中斷。因此,當(dāng)看門(mén)狗時(shí)間到,進(jìn)入看門(mén)狗中斷函數(shù)WDT_IRQHandler()中,在中斷函數(shù)中,將右則數(shù)碼管小數(shù)點(diǎn)顯示出來(lái),并進(jìn)行軟件復(fù)位。這樣通過(guò)小數(shù)點(diǎn)顯示再判斷看門(mén)狗事件的發(fā)生。
除了看門(mén)狗復(fù)位,還有一種軟件復(fù)位方式。當(dāng)MCU發(fā)生硬件失效時(shí),會(huì)進(jìn)入Hardfault中數(shù)函數(shù)。Hardfault是優(yōu)先級(jí)別為-1的固定類型中斷,無(wú)需初始化設(shè)置。常常在MCU死機(jī)時(shí),不知明的會(huì)進(jìn)入Hardfault中斷。因此,在Hardfault中斷函數(shù)中,添加軟件復(fù)位功能也是一種防死機(jī)現(xiàn)象的方法。
Hardfault中斷函數(shù)中代碼如下:
void HardFault_Handler(void) { /* USER CODE BEGIN HardFault_IRQn */ unsigned int j; /* USER CODE END HardFault_IRQn */ while (1) { /* USER CODE BEGIN W1_HardFault_IRQn */ 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(); } /* USER CODE END W1_HardFault_IRQn */ } }
34這就是CW32關(guān)于看門(mén)狗的一個(gè)介紹。
CW32芯片本身在內(nèi)部設(shè)計(jì)的時(shí)候充分考慮了各種ESD抗干擾手段,所以即使軟件上不加任何軟件抗干擾處理,它自身已經(jīng)有比較強(qiáng)的抗干擾能力了。然后,所以我們做實(shí)驗(yàn)的結(jié)果,沒(méi)有STM32那么明顯,就是加看門(mén)狗和不加看門(mén)狗都沒(méi)那么明顯,它本身就可以扛得住各種干擾了。
但是,一個(gè)規(guī)范性的程序,一個(gè)可靠性的軟硬設(shè)計(jì)都非常重要。建議用戶在產(chǎn)品開(kāi)發(fā)的時(shí)候,還是應(yīng)該把看門(mén)狗功能加上去。因?yàn)橥饷婵赡苡欣讚簦懈鞣N電網(wǎng)的波動(dòng),各種意外。那么當(dāng)意外發(fā)生的時(shí)候,MCU不能死機(jī),但可以復(fù)位,可以重新運(yùn)行,不能死鎖。所以我們要養(yǎng)成良好的編程習(xí)慣,養(yǎng)成良好的產(chǎn)品設(shè)計(jì)思維,要把我們抗干擾這個(gè)手段加上去,這也是我們給大家一直來(lái)做這個(gè)抗干擾實(shí)驗(yàn)的一個(gè)目的和意義所在。
審核編輯:湯梓紅
-
單片機(jī)
+關(guān)注
關(guān)注
6061文章
44861瀏覽量
645932 -
mcu
+關(guān)注
關(guān)注
146文章
17797瀏覽量
359494 -
看門(mén)狗
+關(guān)注
關(guān)注
10文章
577瀏覽量
71522 -
抗干擾
+關(guān)注
關(guān)注
4文章
324瀏覽量
35035 -
GPIO
+關(guān)注
關(guān)注
16文章
1251瀏覽量
53459 -
CW32
+關(guān)注
關(guān)注
1文章
242瀏覽量
1061 -
武漢芯源
+關(guān)注
關(guān)注
1文章
67瀏覽量
417
發(fā)布評(píng)論請(qǐng)先 登錄
CW32在“打狗棒”的閃電攻擊下的波形分析——MCU抗干擾實(shí)驗(yàn)系列專題(6)

“看門(mén)狗“VS“打狗棒”,誰(shuí)勝誰(shuí)負(fù)?(STM32篇)—MCU抗干擾實(shí)驗(yàn)系列專題(3)

STM32中的獨(dú)立看門(mén)狗和窗口看門(mén)狗是什么

MCU獨(dú)立看門(mén)狗和窗口看門(mén)狗的區(qū)別
關(guān)于獨(dú)立看門(mén)狗的一點(diǎn)經(jīng)驗(yàn)


“看門(mén)狗”VS“打狗棒”,誰(shuí)勝誰(shuí)負(fù)?(CW32篇)——MCU抗干擾實(shí)驗(yàn)系列專題(4)# MCU抗干擾
什么是stm32看門(mén)狗?獨(dú)立看門(mén)狗和窗口看門(mén)狗工作原理解析

對(duì)于MCU看門(mén)狗IIWDG WWDG喂狗時(shí)間的配置參考

MCU獨(dú)立看門(mén)狗與窗口看門(mén)狗的區(qū)別

MCU獨(dú)立看門(mén)狗與窗口看門(mén)狗的區(qū)別

【嵌入式系統(tǒng)】獨(dú)立看門(mén)狗原理+看門(mén)狗實(shí)驗(yàn)分析

STM32中的獨(dú)立看門(mén)狗和窗口看門(mén)狗
STM32中的獨(dú)立看門(mén)狗和窗口看門(mén)狗

MCU如何集成看門(mén)狗的功能

評(píng)論