江科大STM32定时器PWM输出比较功能详解

定时器输出比较功能(PWM)

  • 1、LED呼吸灯
  • 2、PWM驱动舵机
  • 3、PWM驱动电机

  • 定时器输出比较功能标准库编程的编程接口:

    1、LED呼吸灯

    ①PWM.c文件的代码如下:

    #include "stm32f10x.h"                  // Device header
    
    /*
    	使用定时器TIM2,通过通道CH1(PA0)输出PWM波
    */
    void PWM_Init(void)
    {
    	//1.使能时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	//2.选择内部时钟
    	TIM_InternalClockConfig(TIM2);
    	
    	//3.对时基单元进行配置
    	TIM_TimeBaseInitTypeDef TIM_TimeInitStruct;
    	TIM_TimeInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟源分频
    	TIM_TimeInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
    	TIM_TimeInitStruct.TIM_Period = 100 - 1;//计数器
    	TIM_TimeInitStruct.TIM_Prescaler = 7200 - 1;//预分频器
    	TIM_TimeInitStruct.TIM_RepetitionCounter = 0;//重复计数器
    	
    	TIM_TimeBaseInit(TIM2,&TIM_TimeInitStruct);
    	
    	//4.对输出比较单元进行配置
    	TIM_OCInitTypeDef TIM_OCInitStruct;
    	TIM_OCStructInit(&TIM_OCInitStruct);//给结构体默认初始值
    	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//选择PWM1模式
    	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//选择正极性
    	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//通道使能
    	TIM_OCInitStruct.TIM_Pulse = 0;//CCR的初始值
    	
    	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
    	
    	//5.配置CH1通道对应的引脚PA0
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	GPIO_InitTypeDef GPIOInitStruct;
    	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0;
    	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    	
    	GPIO_Init(GPIOA,&GPIOInitStruct);
    	
    	//6.使能定时器
    	TIM_Cmd(TIM2,ENABLE);
    }
    

    ②PWM.h文件的代码如下:

    #ifndef __PWM_H
    #define __PWM_H
    #include "stm32f10x.h"                  // Device header
    
    void PWM_Init(void);
    
    #endif
    

    ③主程序文件的代码如下:

    /*
    	LED呼吸灯,LED正极接PA0引脚,负极接GND。
    */
    
    #include "stm32f10x.h"                 
    #include "PWM.h"
    #include "Delay.h"
    
    uint16_t i;
    int main(void)
    {
    	PWM_Init();
    	
    	while(1)
    	{
    		for(i = 0;i <= 100 ;i++)
    		{
    			TIM_SetCompare1(TIM2,i);//改变CH1通道的CCR的值
    			Delay_ms(10);
    		}
    		
    		for(i = 0;i <= 100 ;i++)
    		{
    			TIM_SetCompare1(TIM2,100 - i);
    			Delay_ms(10);
    		}
    	}
    }	
    

    2、PWM驱动舵机


    ①PWM.c文件的代码如下:

    #include "stm32f10x.h"                  // Device header
    
    /*
    	使用定时器TIM2,通过通道CH1(PA0)输出PWM波
    */
    void PWM_Init(void)
    {
    	//1.使能时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	//2.选择内部时钟
    	TIM_InternalClockConfig(TIM2);
    	
    	//3.对时基单元进行配置
    	TIM_TimeBaseInitTypeDef TIM_TimeInitStruct;
    	TIM_TimeInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟源分频
    	TIM_TimeInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
    	TIM_TimeInitStruct.TIM_Period = 20000 - 1;//计数器,周期为20ms
    	TIM_TimeInitStruct.TIM_Prescaler = 72 - 1;//预分频器,分辨率为0.001ms 
    	TIM_TimeInitStruct.TIM_RepetitionCounter = 0;//重复计数器
    	
    	TIM_TimeBaseInit(TIM2,&TIM_TimeInitStruct);
    	
    	//4.对输出比较单元进行配置
    	TIM_OCInitTypeDef TIM_OCInitStruct;
    	TIM_OCStructInit(&TIM_OCInitStruct);//给结构体默认初始值
    	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//选择PWM1模式
    	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//选择正极性
    	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//通道使能
    	TIM_OCInitStruct.TIM_Pulse = 0;//CCR的初始值
    	
    	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
    	
    	//5.配置CH1通道对应的引脚PA0
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	GPIO_InitTypeDef GPIOInitStruct;
    	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0;
    	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    	
    	GPIO_Init(GPIOA,&GPIOInitStruct);
    	
    	//6.使能定时器
    	TIM_Cmd(TIM2,ENABLE);
    }
    

    ②PWM.h文件的代码如下:

    #ifndef __PWM_H
    #define __PWM_H
    #include "stm32f10x.h"                  // Device header
    
    void PWM_Init(void);
    
    #endif
    

    ③Servo.c文件的代码如下:

    #include "stm32f10x.h"                  // Device header
    #include "PWM.h"                  // Device header
    
    void Servo_Init(void)
    {
    	PWM_Init();
    }
    /*
    	  角度—— CCR
    
    		 0度 --- 500
    		45度 --- 1000
    	  90度 --- 1500
    	 135度 --- 2000
    	 180度 --- 2500
    */
    
    void Set_Angle(float Angle)
    {
    	uint16_t compare = Angle / 180 * 2000 + 500;
    	TIM_SetCompare1(TIM2,compare);
    }
    

    ④Servo.h文件的代码如下:

    #ifndef __Servo_H
    #define __Servo_H
    #include "stm32f10x.h"                  // Device header
    
    void Servo_Init(void);
    void Set_Angle(float Angle);
    
    #endif
    

    ⑤主程序文件的代码如下:

    /*
    	PWM驱动舵机,通过按键改变PWM的占空比
    */
    
    #include "stm32f10x.h" 
    #include "OLED.h"
    #include "Key.h"
    #include "Servo.h"
    
    float Angle = 0;
    int main(void)
    {
    	OLED_Init();
    	OLED_Clear();
    	Servo_Init();
    	Key_Init();
    	OLED_ShowString(1,1,"Angle:");
    	while(1)
    	{	
    		if(Key_Num() == 1)//按键按下
    		{
    			Angle += 30;
    			if(Angle > 180)
    			{
    				Angle = 0;	
    			}
    		Set_Angle(Angle);
    		OLED_ShowNum(1,7,Angle,3);
    		}
    	}
    }	
    

    3、PWM驱动电机

    使用的是TB6612模块驱动电机。

    PWM.c文件代码如下:

    #include "stm32f10x.h"                  // Device header
    
    /*
    	使用定时器TIM2,通过通道CH1(PA0)输出PWM波
    */
    void PWM_Init(void)
    {
    	//1.使能时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	//2.选择内部时钟
    	TIM_InternalClockConfig(TIM2);
    	
    	//3.对时基单元进行配置
    	TIM_TimeBaseInitTypeDef TIM_TimeInitStruct;
    	TIM_TimeInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟源分频
    	TIM_TimeInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
    	TIM_TimeInitStruct.TIM_Period = 100 - 1;//计数器,周期为20ms
    	TIM_TimeInitStruct.TIM_Prescaler = 36 - 1;//预分频器
    	TIM_TimeInitStruct.TIM_RepetitionCounter = 0;//重复计数器
    	
    	TIM_TimeBaseInit(TIM2,&TIM_TimeInitStruct);
    	
    	//4.对输出比较单元进行配置
    	TIM_OCInitTypeDef TIM_OCInitStruct;
    	TIM_OCStructInit(&TIM_OCInitStruct);//给结构体默认初始值
    	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;//选择PWM1模式
    	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;//选择正极性
    	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;//通道使能
    	TIM_OCInitStruct.TIM_Pulse = 0;//CCR的初始值
    	
    	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
    	
    	//5.配置CH1通道对应的引脚PA0
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	GPIO_InitTypeDef GPIOInitStruct;
    	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIOInitStruct.GPIO_Pin = GPIO_Pin_0;
    	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    	
    	GPIO_Init(GPIOA,&GPIOInitStruct);
    	
    	//6.使能定时器
    	TIM_Cmd(TIM2,ENABLE);
    }
    

    ②Motor.c文件代码如下:

    #include "stm32f10x.h"                  // Device header
    #include "PWM.h"                  // Device header
    
    
    void Motor_Init(void)
    {
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    	GPIO_InitTypeDef GPIOInitStruct;
    	GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIOInitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;//AIN1和AIN2引脚
    	GPIOInitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    	GPIO_Init(GPIOA,&GPIOInitStruct);
    	
    	PWM_Init();
    }
    
    void Motor_SetSpeed(int8_t Speed)
    {
    	if(Speed > 0)//正转
    	{
    		GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_RESET);
    		GPIO_WriteBit(GPIOA,GPIO_Pin_5,Bit_SET);
    		TIM_SetCompare1(TIM2,Speed);
    	}
    	if(Speed == 0)
    	{
    		GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_RESET);
    		GPIO_WriteBit(GPIOA,GPIO_Pin_5,Bit_RESET);
    		TIM_SetCompare1(TIM2,Speed);
    	}
    	if(Speed < 0)
    	{
    		GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_SET);
    		GPIO_WriteBit(GPIOA,GPIO_Pin_5,Bit_RESET);
    		TIM_SetCompare1(TIM2,-Speed);
    	}
    }
    

    ③Motor.h文件代码如下:

    #ifndef __Motor_H
    #define __Motor_H
    #include "stm32f10x.h"                  // Device header
    
    void Motor_Init(void);
    void Motor_SetSpeed(int8_t Speed);
    
    #endif
    

    ④主程序文件代码如下:

    /*
    	PWM驱动电机,通过按键改变PWM的占空比
    */
    
    #include "stm32f10x.h" 
    #include "OLED.h"
    #include "Key.h"
    #include "Motor.h"
    
    int8_t Speed = 0;
    int main(void)
    {
    	OLED_Init();
    	OLED_Clear();
    	Motor_Init();
    	Key_Init();
    	OLED_ShowString(1,1,"Speed:");
    
    	while(1)
    	{	
    		if(Key_Num() == 1)//按键按下
    		{
    			Speed += 20;
    			if(Speed > 100)
    			{
    				Speed = -100;	
    			}
    			Motor_SetSpeed(Speed);
    		}
    		OLED_ShowSignedNum(1,7,Speed,3);
    	}
    }	
    

    作者:浅陌pa

    物联沃分享整理
    物联沃-IOTWORD物联网 » 江科大STM32定时器PWM输出比较功能详解

    发表回复