原理了解
高級定時(shí)器中有一個(gè)重復(fù)計(jì)數(shù)器,本實(shí)驗(yàn)輸出指定個(gè)數(shù)PWM就是利用了重復(fù)計(jì)數(shù)器的特性,先來看看重復(fù)計(jì)數(shù)器的特性是什么:
計(jì)數(shù)器每次上溢或下溢都能使重復(fù)計(jì)數(shù)器減1,減到0時(shí),再發(fā)生一次溢出就會產(chǎn)生更新事件
這是什么意思呢,這里舉個(gè)例子比如說我設(shè)定重復(fù)計(jì)數(shù)器的值為3,則計(jì)數(shù)器上溢一次則重復(fù)計(jì)數(shù)器的值變?yōu)?,再繼續(xù)上溢知道重復(fù)計(jì)數(shù)器的值變?yōu)?,此時(shí)在溢出一次,則產(chǎn)生更新中斷,即如果重復(fù)計(jì)數(shù)器的值為3,則計(jì)數(shù)器需要溢出4次才會產(chǎn)生更新事件,那么結(jié)合本實(shí)驗(yàn)輸出指定數(shù)量的PWM波,通過將N-1寫入重復(fù)計(jì)數(shù)器中,則可以產(chǎn)生N個(gè)PWM波。
從上圖來看,當(dāng)RCR為0時(shí),計(jì)數(shù)器每溢出一次就會產(chǎn)生更新事件;當(dāng)RCR為1時(shí),計(jì)數(shù)器每溢出兩次就會產(chǎn)生更新事件,以此類推;那么這里著重看一下最后一個(gè)是怎么產(chǎn)生更新事件,當(dāng)由軟件產(chǎn)生一次更新事件后,計(jì)數(shù)器的值會回到初始狀態(tài)即0或最大值,然后再溢出4次再次產(chǎn)生更新事件,即軟件產(chǎn)生了更新事件后,將會把RCR的值裝載進(jìn)影子寄存器中,重新開始計(jì)數(shù)。
STM32CubeMx配置
定時(shí)器及通道配置
這里使用定時(shí)器8通道一作為我們的PWM輸出,配置如下:
選擇內(nèi)部時(shí)鐘源,通道一配置為PWM輸出,然后設(shè)置PWM周期的頻率,這里以2KHz設(shè)置,根據(jù)公式:
Tout= ((arr+1)*(psc+1))/Tclk
先代入PSC為7200-1,Tclk為72M(系統(tǒng)時(shí)鐘源),則可算出arr為5000-1。
配置PWM為模式一,pulse為設(shè)置占空比,設(shè)置為arr一半則占空比為50%,輸出極性為高。
打開定時(shí)器8更新中斷,設(shè)置搶占優(yōu)先級及相應(yīng)優(yōu)先級(根據(jù)用戶自身需求)
GPIO口選擇
查看數(shù)據(jù)手冊
PC6為定時(shí)器八通道一的復(fù)用口,同時(shí)查看硬件原理圖:
選擇PE5作為輸入驗(yàn)證程序輸出指定數(shù)量PWM,通過生成N個(gè)PWM使LED亮N次;選擇PB5作為輸出,控制LED亮滅證明程序燒寫成功。
添加PE4按鍵,通過按鍵更改生成的PWM數(shù)量。
STM32CubeMx配置如下:
配置完成后就可生成工程了。
工程生成及代碼編寫
工程文件
生成工程后,可以看到左邊已經(jīng)有了相關(guān)代碼:
在輸出指定數(shù)量PWM波中有如下幾個(gè)比較重要的函數(shù):
void MX_TIM8_Init(void); //定時(shí)器八初始化函數(shù)
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle); //相關(guān)時(shí)鐘使能、中斷開啟函數(shù)
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); //使能PWM輸出
HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource); //產(chǎn)生指定事件
void TIM8_UP_IRQHandler(void); //定時(shí)器8中斷處理服務(wù)函數(shù)
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); //定時(shí)器中斷公共處理函數(shù)
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); //更新中斷回調(diào)函數(shù),需要用戶重寫該函數(shù)
__HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__); //這是一個(gè)宏定義,使能中斷
__HAL_TIM_ENABLE(__HANDLE__); //這是一個(gè)宏定義,使能計(jì)數(shù)器
代碼編寫
tim.c編寫
首先打開tim.c文件:
可以看到里面已經(jīng)幫我們完成了STM32CubeMx配置的初始化,需要完成輸出指定數(shù)量PWM波功能我們需要開啟PWM輸出及使能更新中斷,即在用戶代碼區(qū)中添加如下函數(shù):
__HAL_TIM_ENABLE_IT(&htim8, TIM_IT_UPDATE);
HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
中斷相關(guān)函數(shù)
打開stm32f1xx_it.c文件可以看到中斷的處理函數(shù)已經(jīng)寫好了:
需要做的則是編寫中斷回調(diào)函數(shù),即:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
實(shí)現(xiàn)功能函數(shù)
首先為了實(shí)現(xiàn)輸出指定PWM波實(shí)驗(yàn),這里新添一個(gè)atimp.c文件方便管理:
atim.c及atim.h編寫
#include "atimp.h"
static uint8_t g_npwm_set = 0; //pwm設(shè)置輸出數(shù)量
//輸出pwm個(gè)數(shù)配置函數(shù)
void atim_timx_npwm_chy_set(uint8_t npwm)
{
if(0 == npwm)
return;
g_npwm_set = npwm;
HAL_TIM_GenerateEvent(&htim8, TIM_EVENTSOURCE_UPDATE); //通過軟件啟動更新中斷
__HAL_TIM_ENABLE(&htim8); //使能計(jì)數(shù)器
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM8)
{
if(g_npwm_set) //判斷設(shè)置的pwm數(shù)量
{
TIM8->RCR = g_npwm_set-1; //要想產(chǎn)生N個(gè)pwm將N-1放入RCR寄存器中
HAL_TIM_GenerateEvent(&htim8, TIM_EVENTSOURCE_UPDATE); //通過軟件啟動更新中斷將設(shè)定值放入影子寄存器中
__HAL_TIM_ENABLE(&htim8); //使能計(jì)數(shù)器產(chǎn)生進(jìn)行PWM輸出
g_npwm_set = 0;
}
else
{
TIM8->CR1 &= ~(1 << 0); //關(guān)閉計(jì)數(shù)器
}
}
}
#ifndef __ATIMP_H__
#define __ATIMP_H__
#include "main.h"
#include "tim.h"
void atim_timx_npwm_chy_set(uint8_t npwm);
#endif
用到按鍵,再添加一個(gè)key.c文件文章來源:http://www.zghlxwxcb.cn/news/detail-784530.html
key.c及key.h編寫
#include "key.h"
uint8_t key_scan()
{
static uint8_t key_sta = 1;
uint8_t key_value = 0;
if(key_sta && (KEY0 == 0))
{
HAL_Delay(10);
key_sta = 0;
if(KEY0 == 0)
key_value = KEY0_PRESS;
}
else if(KEY0)
{
key_sta = 1;
}
return key_value;
}
#ifndef __KEY_H
#define __KEY_H
#include "main.h"
#define KEY0_PRESS 1 //PE4按下狀態(tài)
#define KEY0 HAL_GPIO_ReadPin(GPIOE, KEY0_Pin) //讀取當(dāng)前PE4狀態(tài)
uint8_t key_scan(void);
#endif
main.c編寫
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM8_Init();
/* USER CODE BEGIN 2 */
uint8_t key = 0; //記錄鍵值
uint8_t t =0;
atim_timx_npwm_chy_set(5); //設(shè)置PWM輸出5次
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
key = key_scan();
if(key == KEY0_PRESS)
{
atim_timx_npwm_chy_set(3); //設(shè)置PWM輸出3次
}
/*LED翻轉(zhuǎn)證明程序正常工作*/
t++;
if(t > 20)
{
t = 0;
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
HAL_Delay(10);
}
/* USER CODE END 3 */
}
至此,代碼就編寫完成啦。文章來源地址http://www.zghlxwxcb.cn/news/detail-784530.html
到了這里,關(guān)于STM32高級定時(shí)器輸出指定數(shù)量PWM(STM32CubeMx配置)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!