Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

STM32 PWM-Based DC Motor Speed Regulation

Tech 2

Hardware Compnoents

  • STM32 microcontroller (e.g., STM32F4 series)
  • DC motor
  • Motor driver IC (e.g., L298N or DRV8833)
  • Power supply

Software Configuration

The STM32's timer peripheral is used to generate a PWM signal. The timer's auto-reload register (ARR) defines the period, and the capture/compare register (CCR) sets the pulse width (duty cycle).

Implementation

Peripheral Initialization

Configure a GPIO pin for alternate function output, connected to a timer channel. Enitialize the timer in PWM mode.

#include "stm32f4xx.h"

// PWM parameters
#define PWM_FREQ_HZ 20000
#define PWM_PERIOD_TICKS 1000
#define INITIAL_PULSE_WIDTH 300

void ConfigureMotorPins(void) {
    GPIO_InitTypeDef gpio_init;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    gpio_init.GPIO_Pin = GPIO_Pin_6;
    gpio_init.GPIO_Mode = GPIO_Mode_AF;
    gpio_init.GPIO_OType = GPIO_OType_PP;
    gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
    gpio_init.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &gpio_init);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);
}

void SetupPWMTimer(void) {
    TIM_TimeBaseInitTypeDef tim_base_init;
    TIM_OCInitTypeDef tim_oc_init;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    tim_base_init.TIM_Period = PWM_PERIOD_TICKS - 1;
    tim_base_init.TIM_Prescaler = (SystemCoreClock / PWM_FREQ_HZ) - 1;
    tim_base_init.TIM_ClockDivision = TIM_CKD_DIV1;
    tim_base_init.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &tim_base_init);

    tim_oc_init.TIM_OCMode = TIM_OCMode_PWM1;
    tim_oc_init.TIM_OutputState = TIM_OutputState_Enable;
    tim_oc_init.TIM_Pulse = INITIAL_PULSE_WIDTH;
    tim_oc_init.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &tim_oc_init);

    TIM_Cmd(TIM3, ENABLE);
}

Adjusting Motor Speed

The motor speed is controlled by varying the duty cycle. This is done by updating the CCR value.

void SetMotorSpeed(uint16_t pulse_width) {
    TIM_SetCompare1(TIM3, pulse_width);
}

int main(void) {
    ConfigureMotorPins();
    SetupPWMTimer();

    while (1) {
        // Example: Ramp up speed
        for (uint16_t width = 100; width < PWM_PERIOD_TICKS; width += 50) {
            SetMotorSpeed(width);
            // Insert a small delay
            for (volatile int i = 0; i < 100000; i++);
        }
    }
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.