l 16位的向上、向下、向上/向下(中心對齊)計數模式,支持自動重裝載html
l 16位的預分頻器編程
l 每一個定時器都有多個獨立通道,每一個通道可用於函數
* 輸入捕獲ui
* 輸出比較spa
* PWM輸出code
* 單脈衝模式htm
l 高級定時器還能夠產生互補輸出blog
l 能夠產生中斷/DMA請求:事件
* 更新事件:計數器向上/向下溢出,計數器初始化(經過軟或者內部/外部觸發)get
* 觸發事件:計數器啓動,中止,初始化或者有內部/外部觸發計數
* 輸入捕獲
* 輸出比較
向上計數
計數器從0向上計數(遞增)到自動裝載值,而後再次回到0開始計數,併產生一個計數溢出事件
向下計數
計數器從自動裝載值向下計數(遞減)到0,而後再次回到自動裝載值開始計數,併產生一個計數器向下溢出事件
中央對齊模式(向上/向下計數)
計數器從0開始計數到自動裝載值-1,併產生一個計數器溢出事件,而後再向下計數到0+1,併產生一個計數溢出事件,而後再向上計數。
time=(ARR+1)*(PSC+1)/Tclk
ARR爲自動裝載值
PSC:預分頻係數
Tclk:定時器的APB時鐘,一般等於系統時鐘
如:
tclk爲72M
psc爲7199
arr爲4999
time=(4999+1)*(7199+1)/72 000 000 = 0.5s = 500ms
這裏須要注意的是你所須要使用的定時器是掛載在APB1仍是APB2。相應的要調節他們時鐘頻率
選擇
選擇內部時鐘
基礎配置,這裏配置的是1秒計數
l Prescaler (PSC- 16 bits value),預分頻器(PSC- 16位值)
l Counter Mode,計數器模式:
up 向上
down 向下
Center Aligned mode 中心對齊模式
l Counter Period (AutoReload Register - 16 bits value),重裝載值
l auto-reload preload,自動重裝載開啓
開啓更新中斷
中斷優先級數字越低越高
中斷開啓
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
溢出事件回調函數
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){ if(htim->Instance == TIM1){ HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//單獨輸出電平取反 } }
開啓中斷
HAL_TIM_Base_Start_IT(&htim1);
PWM即脈衝寬度調製,是一種模擬控制方式,一般用於LED的亮度調節。其實就是快速的高低電平變化讓人感受不出來。
1HZ表示1秒變化一個週期
在家用交流點中:
50HZ表示電流每秒鐘來回變化50次,方向改變100次。
50HZ是50個週期,因此有50個正玄波形
這個圖表示的是1HZ變化,1個週期,1個正玄波
50HZ表示每一個週期的時間=1S/50=0.02S=20ms
單片機檢測交流電能夠200ms內沒有檢測到高電平,則表示無輸入。
在計算機cpu等使用1khz=1000hz
在電磁波和機械波等,1Khz=1024hz
在PWM中
hz是頻率的單位
1hz 表示PWM的週期是一秒
1Khz表示一秒鐘有一千個週期,也就是週期是1ms
1KKhz、1Mhz表示一秒鐘有100萬個週期,也就是週期是1us
y秒=1/xHZ
1/1000=0.001S=1ms
1/1000000=0.000001S=1us
若是實現週期是100us
100us=0.0001S=1/0.0001= 10,000HZ
ARR爲自動裝載值
CCRx 爲捕獲比較寄存器值
預分頻係數決定了PWM的時鐘速度
ARR的大小決定了PWM的週期
CRRx決定了輸出有效信號的時間
有效信號:
高電平
低電平
PWM模式:
模式1,無論是向上仍是向下計數,當計數值小於重裝載值是輸出有效電平。
模式2,無論是向上仍是向下計數,當計數值小於重裝載值是輸出無效電平。
PWM週期計算
Fpwm = 100M / ((arr+1)*(psc+1))(單位:Hz)
Fpwm = 100M / (arr+1)/(psc+1)(單位:Hz)
arr 是計數值
psc 是預分頻值
如:
3. 主頻=100M
4. arr=100
5. psc=1000
100,000,000/100/1000=1000Hz
設置定時器使用內部時鐘
設置定時器的PWM通道1開啓
STM32F103C8T6對應的PWM通道爲PA8
設置基礎參數
Prescaler,分配係數爲36
Counter Period,重裝載值爲100
因此:
PWM的頻率爲:72 000 000/35/100=20 000 HZ(20KHZ),週期爲 1/20000= 0.00005秒
PWM脈寬調製的最大值與重裝載值一致,其範圍爲[0,100]
通道能夠設置的值:
Mode,PWM的模式,能夠選擇模式1或模式2
CH Polarity,有效電平,可選高或底
初始化
//開啓PWM輸出 HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); //設置默認的佔空比值 __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,10);
while循環改變值
HAL_Delay(30);//延時30ms //變量修改 if(i<100) i++; else i=0; //設置佔空比值 __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,i);
經過檢查定時器通道上的邊沿信號,在邊沿信號跳變(上升沿或者降低沿)的時候,將當前定時器的計數值存儲到對應的捕獲/比較寄存器裏面,完成一次捕獲。
一般用於檢測高電平持續時間、低電平持續時間、兩次降低沿的持續時間、兩次上升沿的持續時間
濾波器:
裏能夠設置以什麼頻率採集多少次有效電平才說明邊沿觸發成功,如設置的是上升沿觸發,當上升沿發生時,濾波器或以fDTS的頻率採集ICF設置的次數,每次檢測是不是高電平,這樣能夠防止誤觸發所帶來的計算干擾。
邊沿檢測器:
設置捕獲的觸發邊沿,能夠設置上升沿或降低沿
通道選擇
經過寄存器能夠設置其它通道輸入的值到該通道上
如通道1和通道2均可以映射到IC1,但一般是通道1是IC1,通道2是IC2,每一個獨立一對一映射,互不干擾。
分頻器:
每2個事件觸發一次捕獲,如上升沿捕獲時,連續獲取到兩個上升沿後纔會觸發計數
每4個事件觸發一次捕獲
每8個事件觸發一次捕獲
開啓TIM4的通道1做爲輸入捕獲通道,對應是PB6引腳
Internal Clock表示內部時鐘
input capture direct mode 表示輸入捕獲
根據硬件鏈接,這裏設置爲上拉
開啓中斷
基礎配置
時鐘:72 000 000 /72 = 1 000 000 HZ= 1MHZ,因此計數一次爲1us
最大計數值爲65536,約爲65ms
prolarity selection 爲觸發計數邊沿,降低沿
測量低電平的持續時間,先降低沿後上升沿,記錄計數值,最終輸出us單位。
通用函數
//變量存儲 typedef struct { uint8_t flg; //0爲未開始,1已經開始,2爲結束 uint16_t num;//計數值 uint16_t num_period;//溢出次數 }COUNT_TEMP; COUNT_TEMP count_temp={0}; //捕獲中斷髮送時的回調函數 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { //判判定時器2 if(TIM2 == htim->Instance){ if ( count_temp.flg == 0 ) { // 清零定時器計數 __HAL_TIM_SET_COUNTER(htim,0); //設置上升沿觸發 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); count_temp .flg = 1; //設置已經開始 count_temp .num_period = 0; //溢出計數清零 count_temp .num = 0; //計數清零 } else { // 獲取定時器計數值 count_temp .num = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2); //設置降低沿觸發 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); count_temp .flg = 2; } } } //定時器溢出回調函數 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(TIM2 == htim->Instance){ //每次溢出時間爲65536us if(count_temp.flg==1)//還未成功捕獲 { if(count_temp.num_period==0XFFFF)//電平太長了 { count_temp.flg=2; //標記成功捕獲了一次 count_temp .num=0XFFFF; }else count_temp .num_period ++; } } }
初始化
//開啓定時器溢出中斷 HAL_TIM_Base_Start_IT(&htim2); //開啓輸入捕獲中斷,設置降低沿觸發中斷 __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); //啓動輸入捕獲
while循環
//等待測量完畢 if(count_temp.flg == 2 ) { //計數計數值,0xFFFF爲最大計數 uint32_t ulTime = (uint32_t)count_temp .num_period * 0xFFFF + count_temp .num; //輸出測量的值 printf ( "低電平時間:%d us\n",ulTime); count_temp .flg = 0; }
原文地址:https://www.cnblogs.com/dongxiaodong/p/14351398.html