日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

STM32F103ZE单片机在WWDG窗口看门狗的EWI中断中喂狗导致系统复位的原因及解决办法(中断函数重入问题)

發布時間:2024/4/18 windows 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F103ZE单片机在WWDG窗口看门狗的EWI中断中喂狗导致系统复位的原因及解决办法(中断函数重入问题) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版權聲明:本文為博主原創文章,歡迎轉載?? ?https://blog.csdn.net/ZLK1214/article/details/78308058
程序開啟了WWDG的Early wakeup(EWI)中斷,在中斷中喂狗,但系統不停地復位。

HCLK=72MHz, PCLK1=4.5MHz, PCLK2=72MHz

程序如下:

#include <stdio.h>
#include <stm32f10x.h>
?
int fputc(int ch, FILE *fp)
{
?? ?if (fp == stdout)
?? ?{
?? ??? ?if (ch == '\n')
?? ??? ?{
?? ??? ??? ?while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
?? ??? ??? ?USART_SendData(USART1, '\r');
?? ??? ?}
?? ??? ?while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
?? ??? ?USART_SendData(USART1, ch);
?? ?}
?? ?return ch;
}
?
int main(void)
{
?? ?GPIO_InitTypeDef gpio;
?? ?USART_InitTypeDef usart;
?? ?
?? ?RCC_PCLK1Config(RCC_HCLK_Div16);
?? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);?// 打開WWDG的時鐘后, 計數器就開始空轉
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
?? ?
?? ?gpio.GPIO_Mode = GPIO_Mode_AF_PP;
?? ?gpio.GPIO_Pin = GPIO_Pin_9;
?? ?gpio.GPIO_Speed = GPIO_Speed_50MHz;
?? ?GPIO_Init(GPIOA, &gpio);
?? ?
?? ?USART_StructInit(&usart);
?? ?usart.USART_BaudRate = 115200;
?? ?usart.USART_Mode = USART_Mode_Tx;
?? ?USART_Init(USART1, &usart);
?? ?USART_Cmd(USART1, ENABLE);
?? ?
?? ?if (RCC_GetFlagStatus(RCC_FLAG_PINRST) == SET)
?? ??? ?printf("PIN reset!\n");
?? ?if (RCC_GetFlagStatus(RCC_FLAG_PORRST) == SET)
?? ??? ?printf("POR reset!\n");
?? ?if (RCC_GetFlagStatus(RCC_FLAG_WWDGRST) == SET)
?? ??? ?printf("WWDG reset!\n");
?? ?RCC_ClearFlag();
?? ?
?? ?WWDG_Enable(94);?// 啟動看門狗并在沒有窗口值的情況下喂狗
?? ?WWDG_SetPrescaler(WWDG_Prescaler_8);
?? ?WWDG_SetWindowValue(74);?// 設置窗口值
?? ?WWDG_EnableIT();
?? ?NVIC_EnableIRQ(WWDG_IRQn);
?? ?
?? ?while (1);
}
?
void WWDG_IRQHandler(void)
{
?? ?WWDG_ClearFlag();
?? ?WWDG_SetCounter(94);
}
不過只要去掉RCC_PCLK1Config(RCC_HCLK_Div16)這句話,讓PCLK1回到默認的36MHz,系統就不再復位了。


于是配置DBGMCU_Config(DBGMCU_WWDG_STOP, ENABLE),設置調試時WWDG暫停。然后打開ST-Link調試,發現系統復位前WWDG_IRQHandler中斷函數連續執行了兩次,第一次執行時T=0x40,正常喂狗,緊接著又再次重入了中斷,T=0x5e,這個時候喂狗就引發了系統復位,因為此時計數值T>窗口值W。

問題的原因找到了,這是因為程序的執行速度(HCLK)太快,而中斷標志位EWIF的清除需要一定的時間(PCLK1),前者的速度是后者的16倍,雖然在中斷函數里面調用了清除中斷標志位的函數,但是到了中斷執行完畢后EWIF都還未來得及清除,所以中斷又再次重入了,第二次喂狗就引發了系統復位。

解決辦法就是,清除標志位后等待一下標志位真正清除,然后再喂狗,退出中斷。保證中斷只執行一次。

void WWDG_IRQHandler(void)
{
? WWDG_ClearFlag();
? while (WWDG_GetFlagStatus() == SET); // 等待中斷標志位真正清除, 防止中斷重入
? WWDG_SetCounter(94);
}
當HCLK=2*PCLK2時不需要等待,因為標志位的清除速度能夠跟得上中斷的執行速度。


程序一開始的時候就在RCC中打開了WWDG外設的時鐘,這時WDGA=0,窗口看門狗未啟用但處于空轉狀態,EWIF的置位規律如下:

T=127
T=126
T=125
...
T=66
T=65
T=64 *** EWIF置位, 手動清除標志位
T=63
...
T=2
T=1
T=0 *** EWIF置位, 手動清除標志位
T=127
T=126
...
T=66
T=65
T=64 *** EWIF置位, 手動清除標志位
T=63
...
在一個計數周期內EWIF會自動置位兩次。但在窗口看門狗啟動之前(WDGA=0),即使打開了EWI中斷,也不會進入中斷函數WWDG_IRQHandler執行。只有WDGA=1且EWIF=1時才會觸發中斷。
---------------------?
作者:巨大八爪魚?
來源:CSDN?
原文:https://blog.csdn.net/ZLK1214/article/details/78308058?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

總結

以上是生活随笔為你收集整理的STM32F103ZE单片机在WWDG窗口看门狗的EWI中断中喂狗导致系统复位的原因及解决办法(中断函数重入问题)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。