Giỏ hàng
Danh mục sản phẩm

Lập trình PWM STM32

Đăng bởi Buiprohd@gmail.com ngày bình luận

Trong hướng dẫn này, tôi sẽ chia sẻ cách sử dụng PWM trên bảng Discovery STM32F4. PWM (Điều chế độ rộng xung) là một kỹ thuật để tạo ra điện áp tương tự (giá trị trung bình) bằng cách sử dụng các đầu ra kỹ thuật số của vi điều khiển. PWM được sử dụng trong điều khiển tốc độ động cơ DC, điều khiển động cơ servo, đèn LED mờ, tạo âm thanh và nhiều hơn nữa.

Thay đổi PWM Là tạo giá trị ON /OFF các giá trị 0,1 giữ nguyên chu kỳ T ,tần số không thay đổi

Vd đây là giá trị 25% chu kỳ PWM

Để tạo ra PWM với STM32F4, chúng ta có thể sử dụng bộ đếm thời gian. Bộ đếm thời gian có thể đếm từ 0 đến một giá trị nhất định và kích hoạt một số sự kiện ở giữa. Trong chế độ PWM, bộ hẹn giờ có thể điều khiển đầu ra kỹ thuật số của 1 hoặc nhiều kênh đầu ra. Khi bộ đếm thời gian đạt giá trị 0, tối đa hoặc so sánh, giá trị kênh đầu ra có thể được thay đổi để tạo tín hiệu PWM

Khởi tạo PWM

void TIM_Init()
{
    // Enable clock for TIM4
    // We use TIM4 because green LED (PD12) is connected
    // to TIM4_CH1 GPIO AF mapping
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    // Timer initialization struct
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;

    // Create 1kHz PWM
    // TIM4 is connected to APB1 bus that have default clock 84MHz
    // So, the frequency of TIM4 is 84MHz
    // We use prescaler 10 here
    // So, the frequency of TIM4 now is 8.4MHz
    TIM_TimeBaseInitStruct.TIM_Prescaler = 10;
    // TIM_Period determine the PWM frequency by this equation:
    // PWM_frequency = timer_clock / (TIM_Period + 1)
    // If we want 1kHz PWM we can calculate:
    // TIM_Period = (timer_clock / PWM_frequency) - 1
    // TIM_Period = (8.4MHz / 1kHz) - 1 = 8399
    TIM_TimeBaseInitStruct.TIM_Period = 8399;
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;

    // Initialize TIM4
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
    // Start TIM4
    TIM_Cmd(TIM4, ENABLE);
}
void PWM_Init()
{
    // PWM initialization struct
    TIM_OCInitTypeDef TIM_OCInitStruct;

    // Common PWM settings
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;

    // Duty cycle calculation equation:
    // TIM_Pulse = (((TIM_Period + 1) * duty_cycle) / 100) - 1
    // Ex. 25% duty cycle:
    //     TIM_Pulse = (((8399 + 1) * 25) / 100) - 1 = 2099
    //     TIM_Pulse = (((8399 + 1) * 75) / 100) - 1 = 6299
    // We initialize PWM value with duty cycle of 25%
    TIM_OCInitStruct.TIM_Pulse = 2099;
    TIM_OC1Init(TIM4, &TIM_OCInitStruct);
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
}
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"
#include "clock.h"
#include "delay.h"

int main(void)
{
    // Set clock to 168MHz
    CLOCK_SetClockTo168MHz();

    // Delay initialization
    DELAY_Init();

    // TIM4 initialization
    TIM_Init();

    // PWM initialization
    PWM_Init();

    /* Set clock for GPIOD ------------------------------------------ */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    // Set alternate function of GPIOD pin 12 as PWM outputs
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);

    // GPIOD pin 12 as outputs
    GPIO_InitTypeDef GPIO_InitStruct;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);
    /* -------------------------------------------------------------- */

    while (1)
    {
        // Set green LED brightness from 0 to max
        int i;
        for (i = 0; i <= 8399; i += 5)
        {
            // If we want to set PWM duty cycle after initialize,
            // we can't use TIM_OCInitStruct.TIM_Pulse,
            // but directly to TIM4 compare register 1 (CCR1)
            TIM4->CCR1 = i;
            DELAY_Ms(1);
        }
    }
}

 

 


Cũ hơn Mới hơn