1. 程式人生 > 其它 >記筆記了——定時器自動重灌值是什麼意思

記筆記了——定時器自動重灌值是什麼意思

馬下——大神的知識
原文連結:https://blog.csdn.net/chenyuanlidejiyi/article/details/108715097

1

在日常使用定時器的時候我們往往會通過改變重灌載值來實現不同時間的一個定時,就像我在一個專案功能中,使用的定時器7,剛開始我設定的是

//該CPU時鐘是48M,分頻係數為48,則48M/48=1M--->對應的是1us
//整個產生的中斷時間是=CPU時鐘/(分頻係數+1)*(重灌載值+1),這裡對應的就是1us*5000=5000us=5ms

  htim7.Instance = TIM7;
  htim7.Init.Prescaler = 4800-1;  //分頻係數   0.1ms,跳動一下需要0.1ms。
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;//向上計數器
  htim7.Init.Period = 52-1;   //自動裝載值,跳動52下需要5.2ms。
  htim7.Instance->CNT=0;
  htim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;//時鐘分頻因子
  htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

  HAL_TIM_Base_Init(&htim7);
  HAL_TIM_Base_Start_IT(&htim7);

這樣的話定時器7就是每5.2ms進入一次中斷,同時我程式碼中還有一個外部中斷,我在外部中斷中改變定時器7的ARR值,

__HAL_TIM_DISABLE(&htim7);
htim7.Instance->CNT=0;
htim7.Instance->ARR=105-1;//跳動105下需要10.5ms。
__HAL_TIM_ENABLE(&htim7);

想讓他後面10.5ms進入一次中斷,(注意重新設定重灌載值的時候最好先關閉定時器,設定引數,再開啟),按照之前對重灌載值的理解,只要修改ARR暫存器,就會修改他的週期時間,那麼產生更新中斷的時間也就變了,但是我通過邏輯分析儀測出的現象是,程式碼執行完我外部中斷中修改ARR的命令,並沒有在10.5ms後進入定時器7的中斷服務函式,而是先在5.2ms後進入中斷服務函式,再在10.5ms後進入定時器7的中斷服務函式。然後通過查詢資料,定時器的暫存器有一個這樣的功能:

這裡有一個ARR的緩衝器,關於這個緩衝器我是這樣理解的,
當開啟緩衝器的時候,修改ARR的值,他會先將這個值放到緩衝器裡,那麼這樣的話這個值作用的就是下下一個週期;當關閉緩衝器,修改ARR的值,直接作用於下個週期。即:
TIM_CR1_ARPE=1,有緩衝區,對ARR修改影響的是下下一個週期的定時長度;
TIM_CR1_ARPE=0,無緩衝區,對ARR修改影響的是下一個週期的定時長度;
然後在發現在初始化的時候
htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
這個引數定義的就是開啟緩衝器的開關

#define TIM_AUTORELOAD_PRELOAD_DISABLE    (0x0000U)    /*!< TIMx_ARR register is not buffered */
#define TIM_AUTORELOAD_PRELOAD_ENABLE    (TIM_CR1_ARPE)  /*!< TIMx_ARR register is buffered */

之後我將這個引數改為TIM_AUTORELOAD_PRELOAD_DISABLE 時,通過驗證,確實是這個問題。