目錄
一、簡(jiǎn)介
1.定時(shí)器簡(jiǎn)介
2.輸入捕獲簡(jiǎn)介
3.原理介紹
二、HAL庫配置
1.時(shí)鐘樹的設(shè)置
2.定時(shí)器時(shí)鐘源選擇
2.1 計(jì)數(shù)脈沖(代碼對(duì)應(yīng)3.1)
2.2 輸入捕獲(對(duì)應(yīng)代碼3.2)
?三、代碼編寫
實(shí)驗(yàn)?zāi)康模豪枚〞r(shí)器輸入捕獲實(shí)現(xiàn)LED翻轉(zhuǎn);按鍵充當(dāng)外部時(shí)鐘源,實(shí)現(xiàn)LED翻轉(zhuǎn)
實(shí)驗(yàn)平臺(tái):正點(diǎn)原子精英板
一、簡(jiǎn)介
1.定時(shí)器簡(jiǎn)介
參考:STM32 hal庫使用筆記(二)中斷—定時(shí)器中斷_亂碼小伙的博客-CSDN博客
2.輸入捕獲簡(jiǎn)介
? ? IC(Input Capture)輸入捕獲 輸入捕獲模式下,當(dāng)通道輸入引腳出現(xiàn)指定電平跳變時(shí),當(dāng)前CNT的值將被鎖存到CCR中,可用于測(cè)量PWM波形的頻率、占空比、脈沖間隔、電平持續(xù)時(shí)間等參數(shù)。
3.原理介紹
? ? 以下純屬個(gè)人理解,歡迎大家交流和指正,可能會(huì)有不準(zhǔn)確的地方。
? ? 輸入捕獲,大部分利用的是內(nèi)部時(shí)鐘作為時(shí)鐘源,設(shè)置PSC的值來決定計(jì)數(shù)器的計(jì)數(shù)頻率(即發(fā)生一次脈沖的時(shí)間),再配合設(shè)置的ARR的值可以得出定時(shí)器的周期/頻率。當(dāng)使能輸入捕獲以后,配合輸入捕獲回調(diào)函數(shù),記錄輸入脈沖的次數(shù)(包括上升沿/下降沿/雙邊沿)。那么周期*脈沖次數(shù)可以得出脈沖源的頻率/周期。
? ?計(jì)數(shù)脈沖我的理解是原理上簡(jiǎn)單很多,主要是將芯片上某個(gè)引腳復(fù)用為定時(shí)器的通道從而作為定時(shí)器的時(shí)鐘源,每輸入一次脈沖(高/低/雙邊),CNT的值加一,從而可以計(jì)算脈沖的數(shù)值,同樣也可以開啟定時(shí)中斷,設(shè)置ARR的值,當(dāng)達(dá)到預(yù)設(shè)值會(huì)觸發(fā)中斷,從而完成中斷回調(diào)函數(shù)中的操作。不過這樣的話,無法軟件得出脈沖的工作周期/頻率,因?yàn)槎〞r(shí)器的觸發(fā)中斷的周期無法軟件計(jì)算。
? ? 本次實(shí)驗(yàn)只是簡(jiǎn)單測(cè)試原理。
二、HAL庫配置
1.時(shí)鐘樹的設(shè)置
參考:STM32 hal庫使用筆記(一)GPIO的使用—流水燈_亂碼小伙的博客-CSDN博客
2.定時(shí)器時(shí)鐘源選擇
2.1 計(jì)數(shù)脈沖(代碼對(duì)應(yīng)3.1)
? ? 利用按鍵即PA0作為時(shí)鐘源,輸入脈沖,并開啟對(duì)應(yīng)中斷引腳。
?配置參數(shù):
由于只是簡(jiǎn)單測(cè)試,測(cè)試原理:輸入5次上升沿,LED燈點(diǎn)亮。由于按鍵一端接的是高電平,所以觸發(fā)極性選擇:上升沿。開啟自動(dòng)重裝。LED燈的配置省略。
PA0的配置,下拉輸入。
配置完成后生成代碼即可。
2.2 輸入捕獲(對(duì)應(yīng)代碼3.2)
? ?主要是利用按鍵輸入上升沿,檢驗(yàn)輸入捕獲回調(diào)函數(shù)是否能夠使用。打開NVIC對(duì)應(yīng)中斷,配置優(yōu)先級(jí)(默認(rèn)就行,反正只有一個(gè)中斷)。
?三、代碼編寫
3.1
? ?使用HAL庫后,定時(shí)器初始化,參數(shù)配置,公共服務(wù)函數(shù)等都已經(jīng)完成,用戶只需要打開中斷,配置回調(diào)函數(shù)即可。
void MX_TIM2_Init(void)
{
TIM_SlaveConfigTypeDef sSlaveConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1;//按鍵有抖動(dòng),所以次數(shù)設(shè)置為1,能實(shí)現(xiàn)即可,后面會(huì)出文章繼續(xù)補(bǔ)充,本次只是檢測(cè)原理
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1;
sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;
sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING;
sSlaveConfig.TriggerFilter = 0;
if (HAL_TIM_SlaveConfigSynchro(&htim2, &sSlaveConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_Base_Start_IT(&htim2);//用戶添加,使能中斷
}
?tim.c的用戶編碼區(qū)添加中斷更新回調(diào)函數(shù)
? ? 特別主要的是:我配置完成后上電會(huì)自動(dòng)進(jìn)入一次回調(diào)函數(shù),百度后的說法是中斷使能等參數(shù)配置時(shí)順序的問題,暫未實(shí)驗(yàn)成功,所以代碼中軟件屏蔽掉了。大家如果有解決辦法,希望分享。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
static unsigned i;
i++;
if (htim->Instance == TIM2)
{
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
}
if(i==1)
{
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
}
}
?實(shí)驗(yàn)效果:
定時(shí)器計(jì)算脈沖數(shù)
3.2
同理,用戶只需使能中斷和使能輸入捕獲即可。
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7200;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 5000;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); /* 用戶添加,使能輸入捕獲 */
__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE); /* 用戶添加,使能更新中斷 */
}
在tim.c中添加中斷更新回調(diào)函數(shù)和輸入捕獲回調(diào)函數(shù)即可:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2)
{
HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin);
}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
TIM_RESET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1); /* 一定要先清除原來的設(shè)置 */
TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING); /* 配置TIM5通道1上升沿捕獲 */
}
}
實(shí)驗(yàn)效果:LED0定時(shí)閃爍,每收到一次上升沿會(huì)使得LED1翻轉(zhuǎn)
定時(shí)器輸入捕獲文章來源:http://www.zghlxwxcb.cn/news/detail-759886.html
歡迎大家交流和指正??!!不勝欣喜!文章來源地址http://www.zghlxwxcb.cn/news/detail-759886.html
到了這里,關(guān)于STM32 hal庫使用筆記(三)定時(shí)器—輸入捕獲和計(jì)數(shù)脈沖的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!