STM32F4 PWM tutorial with TIMERs

http://stm32f4-discovery.net/2014/05/stm32f4-stm32f429-discovery-pwm-tutorial/


In this tutorial, I will show you, how to implement PWM outputs on STM32F4xx devices. This is for a lot of people pretty hard work, but believe me, it’s quite quick and easy. I will go step by step on how to make a PWM output on specific timer.

Update: I made a library for PWM, available here.



STM32F4 timers

They have up to 14 timers inside. Table below shows their description. You have to know, that let’s say F401 doesn’t have so many timers like F407 or F429. You have to always check manual for it’s chip if it has available timer.

Timer Type Resolution Prescaler Channels MAX INTERFACE CLOCK MAX TIMER CLOCK* APB
TIM1, TIM8 Advanced 16bit 16bit 4 SysClk/2 SysClk 2
TIM2, TIM5 General purpose 32bit 16bit 4 SysClk/4 SysClk, SysClk/2 1
TIM3, TIM4 General purpose 16bit 16bit 4 SysClk/4 SysClk, SysClk/2 1
TIM9 General purpose 16bit 16bit 2 SysClk/2 SysClk 2
TIM10, TIM11 General purpose 16bit 16bit 1 SysClk/2 SysClk 2
TIM12 General purpose 16bit 16bit 2 SysClk/4 SysClk, SysClk/2 1
TIM13, TIM14 General purpose 16bit 16bit 1 SysClk/4 SysClk, SysClk/2 1
TIM6, TIM7 Basic 16bit 16bit 0 SysClk/4 SysClk, SysClk/2 1

* Clock speed depends on which STM32F4xx device is used

Timer initialization

Before we can use PWM, we have to initialize timer. Because STM32F429 Discovery board does not have leds on PWM pins, I will use STM32F4 Discovery with 168MHz core clock for this example. Leds are connected to pins PD12 to PD15, what give us timer TIM4 with Output channels 1 to 4.

Initialize TIM4

Here we will initialize timer, for our PWM frequency. We have to set prescaler and period for how fast will it count and how much it will count for specific PWM frequency.

Initialize PWM 4 channels

Set PWM output channels to PWM.

Initialize outputs

Initialize and connect pins for specific TIM. Notice, that GPIOs have AF (Alternating Function) mode, because timer has full control on them.

Example

That’s it. You have not set your timer to work in PWM mode.


### STM32F4 DAC DMA HAL Library Implementation Tutorial In the context of implementing a Direct Memory Access (DMA) transfer with Digital-to-Analog Converter (DAC) on an STM32F4 microcontroller using the Hardware Abstraction Layer (HAL) library, several key components and configurations are essential to ensure proper operation. #### Configuration Overview The configuration process involves setting up the system clock through RCC settings as described previously[^2]. This ensures that all peripherals operate at their intended frequencies. For initializing the DAC along with its associated DMA channel, specific initialization structures must be configured properly: ```c // Initialize DAC handle structure. static DAC_HandleTypeDef hdac; void MX_DAC_Init(void) { DAC_ChannelConfTypeDef sConfig = {0}; /** Configure DAC peripheral */ hdac.Instance = DAC; if (HAL_DAC_Init(&hdac) != HAL_OK) { Error_Handler(); } /** Configure DAC channel */ sConfig.DAC_Trigger = DAC_TRIGGER_NONE; // Or set appropriate trigger source like TIM2_TRGO for waveform generation sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE; if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK) { Error_Handler(); } } ``` For configuring DMA alongside the DAC, it is necessary to specify both the memory address where data resides and the peripheral register into which this data will be transferred during each transaction. The following snippet demonstrates how to configure DMA for transferring values from RAM to the DAC's data holding register: ```c // Define DMA handle structure. static DMA_HandleTypeDef hdma_dac1; void MX_DMA_Init(void) { __HAL_RCC_DMA2_CLK_ENABLE(); /* Configure DMA request hdma_dac1 on stream5 */ hdma_dac1.Instance = DMA2_Stream5; hdma_dac1.Init.Channel = DMA_CHANNEL_7; hdma_dac1.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_dac1.Init.PeriphInc = DMA_PINC_DISABLE; hdma_dac1.Init.MemInc = DMA_MINC_ENABLE; hdma_dac1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_dac1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_dac1.Init.Mode = DMA_CIRCULAR; hdma_dac1.Init.Priority = DMA_PRIORITY_HIGH; hdma_dac1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma_dac1.Init.NoBurstModeThreshold = DMA_NBURST_THRESHOLD_FULL; hdma_dac1.Init.BufferSize = BUFFER_SIZE; hdma_dac1.InitPeripheralBaseAddress = (uint32_t)&(DAC->DHR12R1); hdma_dac1.InitMemoryBaseAddress = (uint32_t)data_buffer; if (HAL_DMA_Init(&hdma_dac1) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(&hdac, DMAPeriodElapsedCallback, hdma_dac1); } /* Start conversion after linking DMA */ if(HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1,(uint32_t)data_buffer,BUFFER_SIZE,DAC_ALIGN_12B_R)!= HAL_OK){ Error_Handler(); } ``` This setup allows continuous transmission of predefined buffer contents (`data_buffer`) via DMA directly into the DAC’s output without CPU intervention once started by `HAL_DAC_Start_DMA()` function call[^1]. Additionally, when working within projects involving timing requirements such as generating waveforms synchronized with timers, integrating timer resources can provide precise control over conversions' timing aspects[^3]: ```c // Timer Initialization Function static void MX_TIM2_Init(void) { htim2.Instance = TIM2; htim2.Init.Prescaler = PRESCALER_VALUE; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = PERIOD_VALUE; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) { Error_Handler(); } } // Linking Timer Event To Trigger DAC Conversion Through DMA Stream __HAL_TIM_SETOUTPUTCOMPAREVALUE(&htim2,TIM_CHANNEL_1,value_for_trigger); HAL_TIM_OC_Start(&htim2,TIM_CHANNEL_1); ``` By carefully planning these elements—clock configuration, DAC/DMA initialization functions, and optional synchronization mechanisms—the desired functionality may be achieved efficiently while adhering closely to best practices outlined in official documentation related to STM32 development environments.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值