MCU:STM32F334C8T6
PWM, or pulse width modulation, can be used to drive motors, full-bridge circuits, etc. Those who have used STM32 know that its timer can easily achieve PWM output, and the advanced timer's TIMx_CHy and TIMx_CHyN can easily achieve the output of complementary PWM waveforms.
Advanced timer resources are limited. This article uses general-purpose timers to implement complementary PWM output, which is a good method when advanced timer resources are insufficient.
The STM32 timer PWM has two modes: PWM mode 1 and PWM mode 2
working principle:
PWM mode 1 - In upcounting, channel 1 is active as long as TIMx_CNT In downcounting, channel 1 is inactive (OC1REF='0') as long as TIMx_CNT>TIMx_CCR1 else active (OC1REF='1'). PWM mode 2 - In upcounting, channel 1 is inactive as long as TIMx_CNT In downcounting, channel 1 is active as long as TIMx_CNT>TIMx_CCR1 else inactive. The official manual describes channel 1. Other channels are similar. Consider the upward counting mode. Assume that the high level is the effective level, that is, the high level is active, use timer 3 PWM mode 1: TIM3_CNT PWM mode 2: TIM3_CNT It can be seen that no matter mode1 or mode2, the level flip is when the value in the counter TIM3_CNT reaches the value in TIM3_CCR1 (the number of times can control the duty cycle, see below) Based on this, the two channels of TIM (such as TIM3_CH1 and TIM3_CH2) can be configured as mode1 and mode2 respectively, so that two complementary PWMs can be output. This is method 1. In method 1, it is assumed that the high level is the active state. In fact, the active state can also be a low level. In this case, consider the same mode (mode1) acive high: TIM3_CNT Active low: TIM3_CNT Therefore, in the same mode, by configuring the effective levels of the two channels to high and low respectively, complementary PWM output can also be achieved. This is method 2. The principle is similar in down counting mode and will not be explained here. Two registers are mentioned above: CNT and CCR1 (channel x corresponds to CRx) CNT is the current count value of the timer, and CCR1 is the value used for comparison. When CNT reaches the value of CCR1, a level transition will occur. Another register ARR, the auto-load register, stores the auto-load value. When CNT reaches the value of ARR during up counting, it will be reset and start again from 0. When CNT reaches 0 during down counting, the value in ARR will be automatically loaded into CNT and start decrementing again. That is to say, the value in ARR is the counting cycle (the center's counting mode is not considered here) Assuming that the frequency we need is freq, the duty cycle is dutycycle, and the timer uses the system frequency SYSCLK, there is the following relationship: ARR = SYSCLK/freq, dutycycle=CCR1/ARR It can be seen that the frequency can be adjusted by changing ARR, and the duty cycle can be adjusted by changing CCR1. uint16_t period=0,pulsewidth=0; GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; period = 72*1000000/(100*1000); //Counting period, system frequency 72M, PWM output frequency 100k pulsewidth = 45*period/100; //Pulse width, duty cycle 45% // Enable the peripheral clock //Configure GPIO TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStruct.TIM_Period = period - 1;//ARR TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStruct); //OCInit structure initialization, fill in all parameters TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = pulsewidth; //CCR1 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; //TIM_OC1Init() turns on channel 1 //OC2 Method 1: Modify Mode TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; /********************************** //OC2 Method 2: Modify Polarity TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low; *************************************/ //TIM_OC2Init() turns on channel 2 //Finally turn on the clock TIM_Cmd(TIM3, ENABLE); The attached picture shows the results of personal testing. The two methods have the same effect. The test is based on STM32F334C8T6, frequency 100k, duty cycle 45%, complementary wave duty cycle 55% http://download.csdn.net/detail/wind4study/8559157method one:
Method Two:
Frequency and duty cycle adjustment:
Part of the code:
//Fill in other parameters of TIM_TimeBaseInitStruct
Download the complete code:
Previous article:STM32 realizes arbitrary angle phase-shifted full-bridge PWM
Next article:STM32F334 uses the serial port to send and receive data
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Overview of MCU bus, three-bus structure of MCU
- ESP8266 Zero-knowledge Tutorial: Using the WiFiScan Library
- Happy Goddess Day~~~~
- PCB development history
- Why open source hardware needs open source software
- UCC24624 Synchronous Rectifier Controller Improves LLC Resonant Converter Efficiency
- 4572.C2000 CLA FAQ V1.0
- Goodbye 2019, Hello 2020" + Transformation from Senior Technical Engineer to Purchasing and R&D
- The impact and value of collision avoidance systems in smart cars on society
- RISC-V MCU Development (Part 7): Code Debugging