STM32 study notes (13)

STM32F103ZET6 PWM output experiment



Preface

The learning of STM32 can be divided into 3 versions.
1. Register version
2. Library function version
3. HAL library version
Due to personal reasons, I choose the library function version to learn STM32.


Tip: Problems such as software installation will not be explained! ! !

1. Basic Principles of PWM

1 Introduction

Pulse Width Modulation (PWM) is the abbreviation of "Pulse Width Modulation" in English, and pulse width modulation for short. It is a very effective technology that uses the digital output of a microprocessor to control analog circuits. The simpler point is the control of the pulse width.
Duty cycle: refers to the proportion of power-on time relative to the total time in a pulse cycle. The duty ratio has the following meanings in the telecommunications field: for example, the pulse width is 1 μs, and the duty ratio of a pulse sequence with a signal period of 4 μs is 0.25.

2. PWM working process

Insert picture description here
Insert picture description here
Insert picture description here

2. Related registers

1. Capture/compare mode register (TIMx_CCMR1/2)

Insert picture description here
Mode setting bit OCxM, this part consists of 3 bits. A total of 7 modes can be configured. We are using PWM mode, so these 3 bits must be set to 110/111. The difference between these two PWM modes is that the polarity of the output level is opposite.

2. Capture/compare enable register (TIMx_CCER)

Insert picture description here

3. Capture/compare register (TIMx_CCR1~4)

Insert picture description here
There are 4 registers in total, corresponding to 4 output channels CH1~4.
In the output mode, the value of this register is compared with the value of CNT, and the corresponding action is generated according to the comparison result. Using this, we can control the PWM output pulse width by modifying the value of this register.

Three, operation steps

1. Corresponding pins

Insert picture description here

2. Operation steps

Insert picture description here

Fourth, the program source code

1.timer.h

code show as below:

#ifndef __TIMER_H
#define __TIMER_H

#include "sys.h"

void TIM3_Int_Init(u16 arr,u16 psc);
void TIM3_PWM(u16 arr,u16 psc);
#endif

2.timer.c

code show as below:

#include "timer.h"
#include "led.h"

void TIM3_Int_Init(u16 arr,u16 psc)
{
    
    
	TIM_TimeBaseInitTypeDef IM_TimeBaseInitstr;
	NVIC_InitTypeDef NVIC_Initstr;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器时钟使能
	
	IM_TimeBaseInitstr.TIM_Period=arr;
	IM_TimeBaseInitstr.TIM_Prescaler=psc;
	IM_TimeBaseInitstr.TIM_CounterMode=TIM_CounterMode_Up;
	IM_TimeBaseInitstr.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM3, &IM_TimeBaseInitstr);//初始化时钟
	
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//开启定时器中断
	
	NVIC_Initstr.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_Initstr.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_Initstr);//配置NVIC
	
	TIM_Cmd(TIM3, ENABLE);//使能定时器
}
void TIM3_IRQHandler(void)//中断服务函数
{
    
    
	if(TIM_GetITStatus(TIM3, TIM_IT_Update)==SET)
	{
    
    
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//清除更新中断标志
		LED1=!LED1;
	}
}
void TIM3_PWM(u16 arr,u16 psc)
{
    
    
	GPIO_InitTypeDef GPIO_Initstr;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstr;
	TIM_OCInitTypeDef TIM_OCInitstr;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//定时器时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//GPIOB和复用时钟
	
	GPIO_Initstr.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Initstr.GPIO_Pin=GPIO_Pin_5;
	GPIO_Initstr.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_Initstr);//初始化IO口为复用功能输出
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3 , ENABLE);//重映射,定时器3通道2映射PB5
	
	TIM_TimeBaseInitstr.TIM_Period=arr;
	TIM_TimeBaseInitstr.TIM_Prescaler=psc;
	TIM_TimeBaseInitstr.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitstr.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitstr);//初始化定时器3
	
	TIM_OCInitstr.TIM_OCMode=TIM_OCMode_PWM2;
	TIM_OCInitstr.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitstr.TIM_OCPolarity=TIM_OCPolarity_High ;
	TIM_OC2Init(TIM3, &TIM_OCInitstr);//设置定时器3通道2PWM的模式
	
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能预装载寄存器
	TIM_Cmd(TIM3, ENABLE);//使能定时器
}

3.main.c

code show as below:

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "beep.h"
#include "key.h"
#include "timer.h"

int main(void)
{
    
    
	u16 led1pwmval;
	u8 dir=1;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	delay_init();
    LED_Init();
	Beep_Init();
	KEY_Init();
	TIM3_PWM(899,0);//不分频,PWM 频率=72000/900=80Khz
	while(1)
	{
    
    
		delay_ms(10);
		if(dir) led1pwmval++;
		else led1pwmval--;
		if(led1pwmval>300) dir=0;
		if(led1pwmval==0) dir=1;
		TIM_SetCompare2(TIM3, led1pwmval);
	}
}

5. Experimental results

Use the PWM function of Timer 3 to output a PWM wave with a variable duty cycle to drive the LED light, so as to achieve the LED light [PB5] brightness from dark to bright and from bright to dark, and so on.


to sum up

1. After watching the video, be sure to write the program yourself.
2. Before programming the program, analyze the program and reason about the experimental phenomenon.
3. If the experimental phenomenon is inconsistent with the reasoning, the program must be carefully analyzed.

Guess you like

Origin blog.csdn.net/weixin_44935259/article/details/112908021