12.[STM32]PWM脉宽调制-舵机控制(一篇足以)

文章目录

  • 1. 舵机简介
  • 1.1 舵机控制
  • 2. 占空比调节函数
  • 3.结语
  • 附录:全部程序
  • 🍌
    🍌🍌
    作者简介:大家好啊,我叫DW,每天分享一些我新学到的知识,期待和大家一起进步
    🍋
    🍋🍋
    系列专栏:STM32
    🍎
    🍎🍎
    🍎🍎🍎
    🌞小实验目标:控制舵机旋转🌞
    🍊如有写得不好的地方欢迎大家指正🍊
    创作时间:🍊🍊🍊2022年5月2日🍊🍊🍊

    1. 舵机简介

    在机器人机电控制系统中,舵机控制效果是性能的重要影响因素。舵机可以在微机电系统和航模中作为基本的输出执行机构,其简单的控制和输出使得单片机系统非常容易与之接口。
    舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前在高档遥控玩具,如航模,包括飞机模型,潜艇模型;遥控机器人中已经使用得比较普遍。舵机是一种俗称,其实是一种伺服马达。

    本次实验使用的舵机是MG90S。

    1.1 舵机控制

    舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度伺服为例,那么对应的控制关系是这样的:
    0.5ms————–0度;
    1.0ms————45度;
    1.5ms————90度;
    2.0ms———–135度;
    2.5ms———–180度;

    因此,我们只需要让IO口产生相应的脉宽就可以控制舵机的角度。如何产生PWM波:11.[STM32]PWM脉宽调制-呼吸灯

    2. 占空比调节函数

    PWM占空比的调节通过TIM_SetCompare函数进行相应调节。通过查找资料,我们可以知道有
    TIM_SetCompare1
    TIM_SetCompare2
    TIM_SetCompare3
    TIM_SetCompare4
    共四个,它们分别可以控制着CH1-CH4的占空比。

    函数原形:
    void TIM_SetCompare1(TIM_TypeDef* TIMx, u16 Compare1)

    第一个参数传入相应定时器,本次实验选择TIM3的CH1,故选择TIM_SetCompare1、TIM3。
    第二个参数是捕获比较 1 寄存器新值,即定时时间。

    例如,我们想要控制舵机旋转,需要产生周期为20ms的脉冲,其操作如下:

     PWM_UserConfig(200-1,7200-1);//50hz 20ms  72000   
     //72 000 000/7200=10 000 Hz
     //10 000*0.020=200 
    

    每次进入中断服务程序间隔时间为:时间=1/频率×次数

    重装载值Period为200,也就是计数到200产生一个更新事件或者中断(定时到了)。
    计算过程:
    时间=1/频率×次数 ,次数=时间x频率=0.020(20ms)x10 000=200

     PWM_UserConfig(200-1,7200-1);
    

    那么,我们想要产生1ms的脉宽该如何操作呢?
    x=10 000hz*0.001=10,即Compare1=10,就可以实现舵机旋转45°。

    TIM_SetCompare1(TIM3,10);
    

    按照这个方法我们可以计算出其他对应的角度:

    TIM_SetCompare1(TIM3,5);//0°
    TIM_SetCompare1(TIM3,10);//45°
    TIM_SetCompare1(TIM3,15);//90°
    TIM_SetCompare1(TIM3,20);//135°
    TIM_SetCompare1(TIM3,25);//180°

    3.结语

    今天的分享就到这里,谢谢大家的耐心阅读,如果觉得有用的话给个👍👍👍

    🌜🌜🌜本章结束,我们下一章见🌜🌜🌜

    参考资料:
    1.STM32固件库手册
    2.正点原子STM32不完全手册_库函数版本
    3.学习视频链接

    资料已上传,需要自取

    附录:全部程序

    //main.c
    #include "sys.h"
    #include "delay.h"
    #include "pwm.h"
    
    
     int main(void)
     {		
    	 
    	 //u8 flag = 0,time = 0;
    	 
    	 delay_init();
    	 PWM_UserConfig(200-1,7200-1);//50hz 20ms  72000   
    	 
    	 while(1){
    		 
    			TIM_SetCompare1(TIM3,5);//0
    		 delay_ms(500);
    		 TIM_SetCompare1(TIM3,10);//45
    		 delay_ms(500);
    		  // TIM_SetCompare1(TIM3,15);//90
    			//TIM_SetCompare1(TIM3,20);//135
    			//TIM_SetCompare1(TIM3,25);//180
    		  //DuoJi();
    		 
     }
    }
     
    //pwm.c
    #include "pwm.h"
    
    
    
    void PWM_UserConfig(u16 Period,u16 Prescaler){
    	
    	
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef  TIM_InitStructure;
    	TIM_OCInitTypeDef PWM_InitStructure;
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	
    	//PA1 TIM2_CH2
    	GPIO_InitStructure.GPIO_Pin = CH1;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    	GPIO_Init(PWM_PROT,&GPIO_InitStructure);
    	
    	TIM_InitStructure.TIM_Period = Period;
    	TIM_InitStructure.TIM_Prescaler = Prescaler;
    	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//不分割
    	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
    	TIM_InitStructure.TIM_RepetitionCounter = DISABLE;//不重复计数
    	TIM_TimeBaseInit(TIM3,&TIM_InitStructure);
    	TIM_Cmd(TIM3,ENABLE);//开启全局使能
    
    	//PWM配置
    	PWM_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    	PWM_InitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出使能
    	PWM_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//输出极性高
    	TIM_OC1Init(TIM3,&PWM_InitStructure);//通道几就选oc几
    	
    	TIM_OC1PreloadConfig(TIM3,ENABLE);//预装在寄存器 
    	TIM_SetCompare1(TIM3,0);//控制占空比
    }
    void DuoJi(void){
    
    	u16 com[] = {5,10,15,20,25,20,15,10,5};
    	
    	for(u8 i = 0;i<9;i++){
    	
    		TIM_SetCompare1(TIM3,com[i]);
    		delay_ms(500);
    	
    	}
    }
    
    //pwm.h
    #ifndef __PWM_H
    #define __PWM_H
    
    #include "sys.h"
    #include "delay.h"
    
    #define CH1 GPIO_Pin_6
    #define PWM_PROT GPIOA
    
    void PWM_UserConfig(u16 Period,u16 Prescaler);
    void DuoJi(void);
    #endif
    
    
    
    
    物联沃分享整理
    物联沃-IOTWORD物联网 » 12.[STM32]PWM脉宽调制-舵机控制(一篇足以)

    发表回复