在本次項目中,限於空間要求咱們選用了STM32F030F4做爲控制芯片。這款MCU不但封裝緊湊,並且自帶的Flash空間也很是有限,因此咱們選擇了LL庫實現。本文咱們將說明如何經過LL庫實現PWM信號的輸出。編程
1、概述函數
咱們知道STM32的TIM計時器能夠輸出PWM信號,這測咱們也採用STM32F030F4中的TIM3通用計時器來實現咱們想要的功能。TIM3通用計時器由一個16位的自動從新加載計數器組成,由一個可編程的預約標器驅動。其結構以下圖所示:spa
它能夠用於各類目的,包括測量輸入信號的脈衝長度(輸入捕獲)或生成輸出波形(輸出比較和PWM)。使用定時器預標量和RCC時鐘控制器預標量,輸出的PWM脈衝長度和波形週期能夠調整從幾微秒到幾毫秒。咱們這裏實現一個佔空比0%到100%可調,頻率爲200Hz的PWM波形。blog
2、TIM配置it
咱們在使用TIM3輸出PWM波,咱們必須對其進行相應的配置。關於TIM3的配置咱們須要關注:TIM3控制寄存器1 (TIM3_CR1)、TIM3預置寄存器(TIM3_PSC)、TIM3自動重載寄存器(TIM3_ARR)以及對應通道的捕獲比較寄存器。io
首先來看一看TIM3控制寄存器1 (TIM3_CR1),這個寄存器用於配置TIM計時器。其結構以下:ast
對於TIM3控制寄存器1 (TIM3_CR1)咱們主要須要說一下計數器使能(CEN)位。而其它的位經過初始化函數設置就能夠了。軟件
TIM3預置寄存器(TIM3_PSC)用以配置TIM計數器的工做頻率,這個工做頻率的計算是:psc的工做頻率/(psc的值+1)。其結構以下:配置
TIM3自動重載寄存器(TIM3_ARR)用以配置輸出PWM波的頻率或者說週期。由於這個值就是計數器的計數週期。其結構以下:下載
咱們設置了技術器的時鐘頻率,計數的週期,要想獲得PWM波,咱們還須要告訴TIM一個佔空比。關於佔空比其實是在捕獲比較寄存器中設置的。
3、PWM實現
咱們已經如何經過配置TIM獲得PWM波形輸出,咱們接下來就是經過軟件來實現咱們的想法。其配置代碼以下:
/* TIM3 初始化配置 */
static void TIM3_Init_Configuration(void)
{
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* TIM3時鐘使能 */
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
/* TIM3初始化配置 */
TIM_InitStruct.Prescaler = 47;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = TIMPERIOD;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
LL_TIM_Init(TIM3, &TIM_InitStruct);
LL_TIM_DisableARRPreload(TIM3);
LL_TIM_OC_EnablePreload(TIM3, LL_TIM_CHANNEL_CH4);
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
TIM_OC_InitStruct.CompareValue = 0;
TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
LL_TIM_OC_Init(TIM3, LL_TIM_CHANNEL_CH4, &TIM_OC_InitStruct);
LL_TIM_OC_DisableFast(TIM3, LL_TIM_CHANNEL_CH4);
LL_TIM_SetTriggerOutput(TIM3, LL_TIM_TRGO_RESET);
LL_TIM_DisableMasterSlaveMode(TIM3);
/* TIM使用GPIO時鐘使能 */
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
/* TIM3 GPIO配置:PB1 ------> TIM3_CH4 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_1;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
LL_TIM_CC_EnableChannel(TIM3,LL_TIM_CHANNEL_CH4);
LL_TIM_EnableCounter(TIM3);
}
在這段配置代碼中,有幾個值須要說一下。Prescaler 值咱們設爲47,因此在48MHz的系統時鐘下,TIM計數器的工做頻率就是1MHz。Autoreload 的值咱們設爲了5000,因此能夠獲得PWM的頻率爲200Hz。CompareValue值設爲了0,因此咱們只能獲得佔空比爲0%的PWM。若咱們想要獲得佔空比爲50%的PWM,則CompareValue值應設爲2500才行。配置完成後各寄存器的值以下圖所示:
這要獲得的只是固定佔空比的PWM波,若想動態修改佔空比則須要修改捕獲比較寄存器的值。使用函數LL_TIM_OC_SetCompareCH4(TIM3,pulse)就能夠了,其中pulse是處於0到Autoreload 的值的整數。
4、總結
咱們經過上述操做,就實現了基於LL庫的PWM波的輸出。咱們將代碼下載到目標板,並修改佔空比和監視器波形輸出。
上圖是佔空比爲50%的波形圖。
上圖是佔空比爲20%的波形圖。
上圖是佔空比爲80%的波形圖。
歡迎關注: