STM32進階筆記——復位、時鐘與滴答定時器

??本專欄爭取每周三更新直到更新完成,期待大家的訂閱關注,歡迎互相學習交流。

封面圖

目錄

  • 一、復位
    • 1.1 軟件復位
    • 1.2 低功耗管理復位
  • 二、時鐘
    • 2.1 系統時鐘(SYSCLK)選擇
    • 2.2 系統時鐘初始化
  • 三、滴答定時器(Systick)
    • 3.1 SysTick部分寄存器
    • 3.2 SysTick相關函數
      • 3.2.1 SysTick時鐘源配置函數
      • 3.2.2 SysTick初始化函數

一、復位

??STM32F10系列單片機的復位方式有三種,分別是系統復位、上電復位和備份區復位,這里只介紹系統復位,另外兩種如果又想了解的友友可以參考芯片手冊,這里就不再介紹了。

??STM32的系統復位將復位所有寄存器至它們的復位狀態,以下幾種情況會觸發系統復位

  • NRST引腳上的低電平(外部復位),這實際也就是我們復位按鍵利用的復位方式。
  • 窗口看門狗計數終止(WWDG復位)
  • 獨立看門狗計數終止(IWDG復位)
  • 軟件復位(SW復位)
  • 低功耗管理復位

可通過查看RCC_CSR控制狀態寄存器中的復位狀態標志位識別復位事件來源。

疑問:復位標志位怎么清除,如果發生了復位,重啟后能否看到復位標志位

1.1 軟件復位

??通過將Cortex?-M3中斷應用和復位控制寄存器中的SYSRESETREQ位置’1’,可實現軟件復位。STM32的庫文件中提供了軟件復位函數

/*** @brief  Initiate a system reset request.** Initiate a system reset request to reset the MCU*/
static __INLINE void NVIC_SystemReset(void)
{SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk);                   /* Keep priority group unchanged */__DSB();                                                     /* Ensure completion of memory access */              while(1);                                                    /* wait until reset */
}

??需要注意的是,從SYSRESETREQ 被置為有效,到復位發生器執行復位命令,往往會有一個延時。在此延時期間,處理器仍然可以響應中斷請求。因此我們在軟件復位前,需要關閉全部中斷,同時在程序最開始的時候開啟全部中斷。STM32庫文件中也提供了一個關閉全部中斷和開啟全部中斷的函數

//關閉所有中斷
void INTX_DISABLE(void)
{		  __ASM volatile("cpsid i");
}
//開啟所有中斷
void INTX_ENABLE(void)
{__ASM volatile("cpsie i");		  
}

關于其他開啟和關閉全局中斷的方法大家可以自行搜索一下,這里就不再贅述了。

??下面我們來簡單嘗試以下系統的軟件復位,每次進入系統前都輸出一串字符串用來提示進入系統,設置延時一段時間后軟件復位系統,查看一下現象

現象

??通過串口的信息我們可以看到,軟件復位生效了。這里的main函數比較簡單,貼一下,僅供參考

int main(void)
{	delay_init();   //延時函數初始化	 uart_init(115200);   // 串口初始化printf ("Enter System!\r\n");while(1){// 延時delay_ms(1000);// 軟件復位INTX_DISABLE();NVIC_SystemReset();}
}

1.2 低功耗管理復位

??在以下兩種情況下可產生低功耗管理復位

  • 在進入待機模式時產生低功耗管理復位
    通過將用戶選擇字節中的nRST_STDBY位置’1’將使能該復位。這時,即使執行了進入待機模式的過程,系統將被復位而不是進入待機模式。
  • 在進入停止模式時產生低功耗管理復位
    通過將用戶選擇字節中的nRST_STOP位置’1’將使能該復位。這時,即使執行了進入停機
    模式的過程,系統將被復位而不是進入停機模式。

二、時鐘

??在介紹STM32F10系列的時鐘之前,先貼一下時鐘樹,可以對照時鐘數來看下面的內容

時鐘樹
??STM32有5個時鐘源,分別是HSI、HSE、PLL、LSI和LSE。

  • HSI是高速內部時鐘,RC振蕩器,頻率為8MHz,精度不高。
  • HSE是高速外部時鐘,可以接石英石/陶瓷諧振器,或者接外部時鐘源,頻率范圍是4MHz~16MHz
  • PLL實際是一個鎖相環,也可以理解為倍頻器,它的時鐘源可以選擇為 H S I 2 \frac{HSI}{2} 2HSI?、HSE或者 H S E 2 \frac{HSE}{2} 2HSE?,倍頻可以選擇x2~x16,但是它的輸出最大不可超過72MHz
  • LSI是低速內部時鐘,RC振蕩器,頻率為40KHz,提供獨立看門狗時鐘等。
  • LSE是低速外部時鐘,可以接頻率為32.768KHz的石英晶體,提供RTC時鐘。

??STM32的系統時鐘SYSCLK可以來源于三個時鐘源,分別是HSI、HSE和PLL時鐘。STM32也可以輸出時鐘信號,可以選擇一個時鐘信號出書到PA8引腳上,可選PLL輸出的二分頻、HSI、HSE或者系統時鐘作為時鐘源。

2.1 系統時鐘(SYSCLK)選擇

??系統復位后,HSI振蕩器被選為系統時鐘。我們可以通過設置時鐘配置寄存器(RCC_CFGR)來切換系統時鐘,在切換系統時鐘時,需要等待目標時鐘源準備就緒,當被選擇的時鐘沒有就緒時,系統時鐘不會發生切換。直至目標時鐘源準備就緒,才會發生切換。我們可以通過在時鐘控制寄存器(RCC_CR)里的狀態位指示哪個時鐘已經準備好了,哪個時鐘目前被用作系統時鐘。

在從停止或待機模式中返回時或直接或間接作為系統時鐘的HSE出現故障時,由硬件強制選擇HSI作為系統時鐘(如果時鐘安全系統已經啟動),關于時鐘安全系統(CSS)這就不再贅述。

2.2 系統時鐘初始化

??STM32的庫函數中提供了系統時鐘初始化函數

/*** @brief  Setup the microcontroller system*         Initialize the Embedded Flash Interface, the PLL and update the *         SystemCoreClock variable.* @note   This function should be used only after reset.* @param  None* @retval None*/
void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;#ifdef STM32F10X_CL/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;      
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers *//* Configure the Flash Latency cycles and enable prefetch buffer */SetSysClock();#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}

關于系統時鐘配置函數的內容,大家可以自行對照STM32中文參考手冊來查看具體每一行代碼的含義,當然也有英文注釋可參考,這里就不再贅述了。

??不知道大家是否好奇,我們在編程時并未特地調用過時鐘初始化函數SystemInit(),我們是在什么時候配置的系統時鐘呢?實際在STM32的啟動文件中已經調用過該函數,配置完了系統時鐘

配置系統時鐘

??關于STM32啟動文件的詳細注釋,大家可以移步至該帖查看,這里也不再貼出來了,STM32啟動文件詳解。

三、滴答定時器(Systick)

??SysTick定時器被捆綁在NVIC中,它通常用來做延時或者實時系統的心跳,使用SysTick可以節省一個定時器資源。

??SysTick定時器也可以叫做系統滴答定時器,它是一個24位的倒計數計時器,當它計數到0時,將從RELOAD寄存器中自動重裝載定時器初值。只要我們不把它在SysTick控制及狀態寄存器中的使能位清除,滴答定時器就一直在工作,即使在睡眠模式下也不會停止。SysTick有自己的中斷,中斷優先級可以設置。

3.1 SysTick部分寄存器

??接下來我們來看一下SysTick的一些寄存器。

  • SysTick控制及狀態寄存器(CTRL)
    SysTick控制及狀態寄存器
  • SysTick重裝載數值寄存器(LOAD)
    SysTick重裝載數值寄存器
  • SysTick當前數值寄存器(VAL)
    SysTick當前數值寄存器

3.2 SysTick相關函數

??STM32庫函數給出了SysTick的一些配置函數,這里我們簡單介紹一下,在看下面的函數時,大家可以對照上面的寄存器來分析一下每一行代碼的作用和含義。

3.2.1 SysTick時鐘源配置函數

/*** @brief  Configures the SysTick clock source.* @param  SysTick_CLKSource: specifies the SysTick clock source.*   This parameter can be one of the following values:*     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.*     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.* @retval None*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{/* Check the parameters */assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));if (SysTick_CLKSource == SysTick_CLKSource_HCLK){SysTick->CTRL |= SysTick_CLKSource_HCLK;}else{SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;}
}

??下面是一些相關的宏定義

#define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \((SOURCE) == SysTick_CLKSource_HCLK_Div8))

??對照上面對于SysTick控制及狀態寄存器的介紹我們可以知道,當SysTick時鐘源配置函數的輸入值為1時,選擇外部時鐘作為時鐘源,當輸入值為0時,選擇內部時鐘作為時鐘源。

3.2.2 SysTick初始化函數

/*** @brief  Initialize and start the SysTick counter and its interrupt.** @param   ticks   number of ticks between two interrupts* @return  1 = failed, 0 = successful** Initialise the system tick timer and its interrupt and start the* system tick timer / counter in free running mode to generate * periodical interrupts.*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk   | SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */return (0);                                                  /* Function successful */
}

??下面是一些相關的宏定義

/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */

??該函數的功能是使能SysTick,開啟中斷,函數的輸入參數ticks是設置兩次中斷間的間隔,也就是設置兩次中斷之間有多少個SysTick時鐘周期。我們如下配置就可以設置SysTick中斷時間間隔為1ms。

    SysTick_Config(SystemCoreClock / 1000);   // 設置SysTick中斷時間間隔為1ms

??這里介紹一下為什么按照上面的設置,SysTick兩次中斷之間的時間間隔為1ms。比如系統頻率為72MHz,我們設置的是每72K個SysTick周期進入一次中斷,也就是說進入中斷的時間間隔為72K / 72M,也就是1ms。

??其實我們用到的延時函數也是利用滴答定時器來實現的延時,這里我們就不再詳細介紹,大家有興趣的可以自行分析學習一下。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716629.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

部署bpmn項目實現activiti流程圖的在線繪制

本教程基于centos7.6環境中完成 github開源項目: https://github.com/Yiuman/bpmn-vue-activiti軟件&#xff1a;git、docker 1. 下載源代碼 git clone https://github.com/Yiuman/bpmn-vue-activiti.git2. 修改Dockerfile文件 聲明基礎鏡像&#xff0c;將項目打包&#xff…

EasyRecovery數據恢復軟件有什么優勢呢?

EasyRecovery數據恢復軟件具有以下優勢&#xff1a; 強大的恢復能力&#xff1a;EasyRecovery采用先進的掃描和恢復技術&#xff0c;能夠深度掃描存儲設備&#xff0c;尋找并恢復因各種原因丟失的數據。無論是誤刪除、格式化、分區損壞還是病毒感染&#xff0c;它都能提供有效…

設計模式(十一)策略模式

請直接看原文:設計模式&#xff08;十一&#xff09;策略模式_某移動支付系統在實現賬戶資金轉入和轉出時需要進行身份驗證,該系統為用戶提供了-CSDN博客 ----------------------------------------------------------------------------------------------------------------…

LeetCode01 - 35.搜索插入位置

一、題目要求 給定一個排序數組和一個目標值&#xff0c;在數組中找到目標值&#xff0c;并返回其索引。如果目標值不存在于數組中&#xff0c;返回它將會被按順序插入的位置。 請必須使用時間復雜度為 O(log n) 的算法 示例 1: 輸入: nums [1,3,5,6], target 5 輸出: 2示…

SpringMVC 學習(十一)之數據校驗

目錄 1 數據校驗介紹 2 普通校驗 3 分組校驗 4 參考文檔 1 數據校驗介紹 在實際的項目中&#xff0c;一般會有兩種校驗數據的方式&#xff1a;客戶端校驗和服務端校驗 客戶端校驗&#xff1a;這種校驗一般是在前端頁面使用 JS 代碼進行校驗&#xff0c;主要是驗證輸入數據…

文物預防性保護系統方案的需求分析

沒有文物保存環境監測&#xff0c;就不能實施有效的文物預防性保護。因此要建立文物預防性保護體系&#xff0c;一定要先有良好的文物狀態監測制度,進而進行科學有效的文物保護管理。所以,導入文物預防性保護監測與調控系統,首先就是要針對文物進行全年溫度、濕度、光照等關鍵參…

使用Zint庫生成一維碼/條形碼

下面代碼是是使用 Zint 庫生成 Code 128 類型的條形碼&#xff0c;并將生成的條形碼保存為 output.bmp 文件。下面是對代碼的詳細解釋&#xff1a; #include 和 #include <zint.h>&#xff1a;這兩行代碼包含了所需的頭文件&#xff0c;分別是標準輸入輸出流的頭文件和 Z…

LeetCode---【鏈表的操作】

目錄 206反轉鏈表【鏈表結構基礎】21合并兩個有序鏈表【遞歸】我的答案【錯誤】自己修改【超出時間限制】在官方那里學到的【然后自己復寫,錯誤】對照官方【自己修改】 160相交鏈表【未理解題目目的】在b站up那里學到的【然后自己復寫,錯誤】【超出時間限制】對照官方【自己修改…

(C語言)qsort函數模擬實現

前言 我們需先了解qsort函數 qsort函數詳解&#xff1a;http://t.csdnimg.cn/rTNv9 qsort函數可以排序多種數據類型&#xff0c;很是神奇&#xff0c;這是為什么&#xff0c;我們在里模擬實現這樣的功能 目錄 1. qsort函數模擬實現 2. 我們使用bubble_sort函數排序整形數…

探究前端的.less樣式文件 css的增強版

前言 .less 文件是一種層疊樣式表&#xff08;CSS&#xff09;預處理器語言的文件格式&#xff0c;簡稱 LESS&#xff08;Leaner Style Sheets&#xff09;。它擴展了 CSS 語言&#xff0c;增加了變量、混合、函數和許多其他技術&#xff0c;使得 CSS 更加易于維護和擴展。 與…

AntDesignVue之a-table中key不唯一問題處理的多種方式

AntDesignVue2之a-table中key不唯一問題處理的多種方式 文章目錄 AntDesignVue2之a-table中key不唯一問題處理的多種方式1. key不唯一問題1. 問題描述2. 解決方法1. 帶冒號的rowKey2 . 帶冒號的rowKey綁定表達式3. 不帶冒號的rowKey屬性 1. key不唯一問題 1. 問題描述 antdv: …

Sunshine v0.21.0 安裝卡住,閃退的問題解決

上期博客講了如何利用 Sunshine 和 Moonlight 實現 iPad 當作 Windows 副屏&#xff0c;用官方 Windows installer 安裝 Sunshine 過程中&#xff0c;遇到了安裝卡住&#xff08;這個是因為需要國外網絡環境&#xff09;&#xff0c;安裝后運行閃退的問題。 Sunshine 下載地址…

OpenCV 4基礎篇| OpenCV圖像的裁切

目錄 1. Numpy切片1.1 注意事項1.2 代碼示例 2. cv2.selectROI()2.1 語法結構2.2 注意事項2.3 代碼示例 3. Pillow.crop3.1 語法結構3.2 注意事項3.3 代碼示例 4. 擴展示例&#xff1a;單張大圖裁切成多張小圖5. 總結 1. Numpy切片 語法結構&#xff1a; retval img[y:yh, x…

以目標檢測和分類任務為例理解One-Hot Code

在目標檢測和分類任務中&#xff0c;每一個類別都需要一個編碼來表示&#xff0c;同時&#xff0c;這個編碼會用來計算網絡的loss。比如有貓&#xff0c;狗&#xff0c;豬三種動物&#xff0c;這三種動物相互獨立&#xff0c;在分類中&#xff0c;將其中任意一種分類為其他都同…

YOLOv9獨家原創改進|使用可改變核卷積AKConv改進RepNCSPELAN4

專欄介紹&#xff1a;YOLOv9改進系列 | 包含深度學習最新創新&#xff0c;主力高效漲點&#xff01;&#xff01;&#xff01; 一、改進點介紹 AKConv是一種具有任意數量的參數和任意采樣形狀的可變卷積核&#xff0c;對不規則特征有更好的提取效果。 RepNCSPELAN4是YOLOv9中的…

前端架構: 腳手架通用框架封裝之啟動檢查功能開發(教程四)

腳手架啟動前的檢查功能開發 接上文&#xff0c;仍舊在 abc-cli 項目中參考&#xff1a;https://blog.csdn.net/Tyro_java/article/details/136431320現在要在腳手架啟動前要做一些邏輯&#xff0c;可以在 hook 鉤子函數中去書寫比如&#xff0c;進行node版本的對比&#xff0…

2023年12月CCF-GESP編程能力等級認證Scratch圖形化編程四級真題解析

一、單選題(共15題,共30分) 第1題 現代計算機是指電子計算機,它所基于的是( )體系結構。 A:艾倫圖靈 B:馮諾依曼 C:阿塔納索夫 D:埃克特-莫克利 答案:B 第2題 默認小貓角色,執行下列程序,以下說法正確的是? ( ) A:舞臺上會出現無數個小貓 B:舞臺只會出現…

java spring 02. AbstractApplicationContext

spring創建對象的順序&#xff0c;先創建beanfactory&#xff0c;再會把xml文件讀取到spring。 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, Nullable ApplicationContext parent)throws BeansException {//調用父類的構造方法super(p…

Redis常用指令,jedis與持久化

1.redis常用指令 第一個是key的常用指令&#xff0c;第二個是數據庫的常用指令 前面的那些指令都是針對某一個數據類型操作的&#xff0c;現在的都是對所有的操作的 1.key常用指令 key應該設計哪些操作 key是一個字符串&#xff0c;通過key獲取redis中保存的數據 對于key…

flink重溫筆記(九):Flink 高級 API 開發——flink 四大基石之WaterMark(Time為核心)

Flink學習筆記 前言&#xff1a;今天是學習 flink 的第 9 天啦&#xff01;學習了 flink 四大基石之 Time的應用—> Watermark&#xff08;水印&#xff0c;也稱水位線&#xff09;&#xff0c;主要是解決數據由于網絡延遲問題&#xff0c;出現數據亂序或者遲到數據現象&…