STM32 PWM波驱动模拟舵机(库函数版)

发布者:w2628203123最新更新时间:2020-06-16 来源: eefocus关键字:STM32  PWM波  驱动模拟舵机  库函数版 手机看文章 扫描二维码
随时随地手机看文章

数字舵机 vs 模拟舵机 “数字舵机区别于传统的模拟舵机,模拟舵机需要给它不停的发送PWM信号,才能让它保持在规定的位置或者让它按照某个速度转动,数字舵机则只需要发送一次PWM信号就能保持在规定的某个位置。”


"到底模拟舵机与数码舵机在实际使用中有什么区别呢?我自己总结大致有以下几点:


1 数码舵机在位置准确度方面要高于模拟舵机。

2 在同样标称1.6公斤的舵机面前数码舵机在实际表现中会感觉更加“力气大”而模拟舵机就会“肉”点。

3 模拟舵机由于控制芯片是模拟电路,所以即便是相同型号的舵机会存在小小的性能差异,而数码舵机在一致性方面就非常好。

4 数码舵机一般均采用PID优化算法,所以,线性要好过模拟舵机。

5 对于高灵敏度的控制,建议选择数码舵机,如直升机的控制,高速固定翼飞机,高速滑翔机,比赛用车膜型,云台的控制等

6 对于不是特别需要灵敏度的场合,如低速固定翼(二战飞机,练习机,低速滑翔机等),船模,娱乐用车模等。可以考虑模拟舵机。


"(http://www.321mx.com/blog/548.html)


基本上参考《STM32不完全手册——库函数版本》


pwm.c 初始化函数


//PWM输出初始化

//arr:自动重装值

//psc:时钟预分频数

 

void TIM_PWM_Init(u16 arr,u16 psc)

{  

GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

TIM_OCInitTypeDef  TIM_OCInitStructure;

 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE);// 使能定时器时钟TIM2/TIM3/TIM4

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);  //使能GPIOA/GPIOB外设时钟使能

                                                                     

 

   //设置该引脚为复用输出功能,输出TIM2 CH3(PA2复用输出)、TIM2 CH4(PA3复用输出)的PWM脉冲波形

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //TIM2_CH3(PA2复用输出)、TIM2 CH4(PA3复用输出)

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9; //TIM3的3、4通道,TIM4的3、4通道

  GPIO_Init(GPIOB,&GPIO_InitStructure);     //B口的0、1对应TIM3的3、4通道,B口的8、9对应TIM4的3、4通道,设置为复用推挽输出

 

TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 50HZ

TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频

TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

 

 

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能

TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高

 

 

  TIM_OC3Init(TIM2, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //CH3预装载使能

  TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //CH4预装载使能

  TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH3预装载使能

  TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //CH4预装载使能

TIM_OC3Init(TIM4, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);  //CH3预装载使能

  TIM_OC4Init(TIM4, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //CH4预装载使能

TIM_ARRPreloadConfig(TIM2, ENABLE); //使能TIMx在ARR上的预装载寄存器

TIM_CtrlPWMOutputs(TIM2,ENABLE); //MOE 主输出使能

TIM_Cmd(TIM2, ENABLE);  //使能TIM2

TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器

TIM_CtrlPWMOutputs(TIM3,ENABLE); //MOE 主输出使能

TIM_Cmd(TIM3, ENABLE);  //使能TIM3

TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在ARR上的预装载寄存器

TIM_CtrlPWMOutputs(TIM4,ENABLE); //MOE 主输出使能

TIM_Cmd(TIM4, ENABLE);  //使能TIM4

}


int main(void)

{

u16 pwmval1=749;//1.5ms->90度


delay_init(); //延时函数初始化


TIM_PWM_Init(9999,143);//不分频。PWM 频率=72*10^6/(9999+1)/(143+1)=50Hz


while(1)

{

//调节占空比pwmval1/(9999+1)

TIM_SetCompare3(TIM2,pwmval1);TIM_SetCompare4(TIM2,pwmval1);

TIM_SetCompare3(TIM3,pwmval1);TIM_SetCompare4(TIM3,pwmval1);

TIM_SetCompare3(TIM4,pwmval1);TIM_SetCompare4(TIM4,pwmval1);

}


}


以下转自:http://www.cnblogs.com/ghdnui/articles/3429732.html


void TIM_Configuration(void)

{

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    TIM_OCInitTypeDef  TIM_OCInitStructure;

    GPIO_InitTypeDef    GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 , ENABLE);

    

    

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //TIM3的1、2通道    ,产生PWM

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA,&GPIO_InitStructure);       //PA的6,7口对应TIM3的1、2通道,设置为复用推挽输出

 

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; //TIM4的1、2、3、4通道

    GPIO_Init(GPIOB,&GPIO_InitStructure);     //B口的6,7,8,9对应TIM4的1、2、3、4通道,设置为复用推挽输出

 

    TIM_TimeBaseStructure.TIM_Period =9999;           //自动重载周期值

    TIM_TimeBaseStructure.TIM_Prescaler =143;          //预分频值 ,这里是50HZ

    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;        //时钟分割

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;      //计数摸式为向上计数

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);         //TIM3,和TIM4用的相同配置,写入配置  ,PWM频率为50HZ

                                                                      

    //设定占空比

    

    TIM_OCStructInit(& TIM_OCInitStructure);      //恢复初始

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //定时器模式为pwm模式1

    TIM_OCInitStructure.TIM_Pulse =0;              //脉冲值,即输出都是低电平

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //极性为高

    

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);     //将配置数据写入TIM3的通道1

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);    //预装载使能

    TIM_OC2Init(TIM3, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

 

    TIM_OC1Init(TIM4, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_OC2Init(TIM4, &TIM_OCInitStructure);

    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_OC3Init(TIM4, &TIM_OCInitStructure);

    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);

    TIM_OC4Init(TIM4, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);//TIM4的4个通道都用相同的配置

    TIM_Cmd(TIM3, ENABLE);

    TIM_CtrlPWMOutputs(TIM3, ENABLE);

    TIM_Cmd(TIM4, ENABLE);

    TIM_CtrlPWMOutputs(TIM4, ENABLE);          //使能PWM模式

}


void SetJointAngle(u8 ID, float angle)

{

    switch(ID)

    {

        case 0:                                      //-90°~90°   

            angle=angle+90.0;                      

            angle=(u16)(50.0*angle/9.0+249.0);     

            TIM_SetCompare1(TIM3,angle);        

            break;

                                                 //0°~180°

        case 1:

            angle=(u16)(4.175*angle+409.25);

            TIM_SetCompare2(TIM3,angle);          

            break;

 

 

        case 2:                                    //-150°~0°

            angle=-angle;

            angle=(u16)(4.175*angle+480.0);

            TIM_SetCompare1(TIM4,angle);

            break;

 

        case 3:

            angle=-180-angle;

            angle=-angle;

            angle=(u16)(4.175*angle+315.0);

        

 

            TIM_SetCompare2(TIM4,angle);

            break;

                                              //-90°~90°

        case 4:

            angle=90.0+angle;

[1] [2]
关键字:STM32  PWM波  驱动模拟舵机  库函数版 引用地址:STM32 PWM波驱动模拟舵机(库函数版)

上一篇:STM32自学笔记——定时器及PWM输出
下一篇:STM32通用定时器TIM实现PWM波配置步骤

推荐阅读最新更新时间:2024-11-17 14:20

STM32外部中断操作
CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有76个中断,包括16个内核中断和60个可屏蔽中断,具有16级可编程的中断优先级。 NVIC NVIC Nested Vectored Interrupt Controller 嵌套向量中断控制。在STM32的标准外设库和MDK定义的中断相关的变量和结构体类型,大多都是以NVIC开头的,例如 NVIC_InitTypeDef 。 NVIC_Type NVIC寄存器结构体。在MDK380a中,这个结构体是定义在stm32f10x_map.h中,具
[单片机]
STM32系列第14篇--TFTLCD驱动原理
ALINETEK2.8寸 TFTLCD模块特点 240*320分辨率 16位真彩显示(65536色) 自带电阻触摸屏 自带背光电路 注意:模块是3.3V供电的,不支持5V电压的MCU,如果是5VMCU,必须在信号线串接120R电阻使用。 ALINETEK2.8寸 TFTLCD接口说明(16位80并口) LCD_CS:LCD片选信号 LCD_WR:LCD写信号 LCD_RD:LCD读信号 DB :16位双向数据线。 LCD_RST:硬复位LCD信号 LCD_RS:命令/数据标志(0:命令,1:数据) BL_CTR:背光控制信号 T_MISO/T_MOSI/T_PEN/T_CS/T_CLK,触摸
[单片机]
<font color='red'>STM32</font>系列第14篇--TFTLCD<font color='red'>驱动</font>原理
stm32串口usart的使用
一、串口的定义 用来与外界交互数据。 二、usart的配置: 1、开启时钟。 stm32的usart1挂载在apb2上,USART2、usart3挂载在apb1上。 2、串口的基本配置。 void USART1_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_DeInit (USART1 ); USART_InitStructure .USART_BaudRate =9600; USART_InitStructure .USART_WordLength =USART_WordLength_8b ; USART_InitStructure .USA
[单片机]
STM32之BKP后备域库函数介绍
1.BKP_DeInit函数的功能是将外设BKP的全部寄存器重设为默认值。 2.BKP_TamperPinLevelConfig函数的功能是设置侵入检测引脚的有效电平。 .BKP_TamperPinLevel可取的值有.BKP_TamperPinLevel_High/_Low.分别是检测高低电平。 3.BKP_TamperPinCmd函数的功能是使能或失能引脚的侵入检测功能。 BKP_TamperPinCmd(enable); 4.BKP_WriteBackupRegister函数的功能是想指定的后备寄存器中写入用户程序数据。他分别可以选用1~10不同的数据寄存器。 BKP_WriteBackupRegister(BKP_DR1,
[单片机]
STM32如何实现W25X16的汉字字库存储
系统中使用过多的汉字会出现芯片容量不够用的问题,可将数据存储在外部FLASH中,在需要使用时进行调用即可。本文是通过STM32串口1实现对W25X16的汉字字库存储。软件层面,配置串口1和SPI1即可,程序初始化后,在对W25X16进行写之前,必须先擦除,可以一个字节、一页、一扇区、一块以及整片擦除。写字库前,我们用整片擦除方式,如下: 整个程序中,关键在于串口接收中断函数的编写,如下: u32 WriteAddress=0; void USART1_IRQHandler(void) { u8 Res; if(USART_GeTITStatus(USART1,USART_IT_RXNE)!=RESET) { USART_Cle
[单片机]
<font color='red'>STM32</font>如何实现W25X16的汉字字库存储
STM32开发设计中FSMC可能遇到问题应对方案
本文将就使用FSMC可能遇到的问题进行说明。希望能对大家的学习有所帮助。 一、端口配置 1、 由于FSMC写NOR时序与8080接口的时序十分相识,因此我们采用模拟8080时序, 2、 STM32的引脚图如图所示。 3、根据上图我们可以得出,FSMC的数据端口D 如下 4、我们使用的是 FSMC 的信号线 NE1 作为控制 8080 的 CSX 片选信号,所以我们把本成配置为 FSMC_Bank1_NORSRAM1 (NE1 片选BANK1)。由上图得FSMC-NE1 ==PD7 ---------LCD-CS 5、数据地址的选择 本成员用于设置 FSMC 接口的数据宽度,可被设置为 8Bit 或 16b
[单片机]
<font color='red'>STM32</font>开发设计中FSMC可能遇到问题应对方案
stm32 hard fault及堆栈探究
在调试RTC过程中,程序在主循环中执行两次后就进入hard fault的while(1)中断,keil显示调试窗口显示imprecise data bus error。完善RTC配置的时序也无济于事。网上查到一些hard fault的资料: STM32F10xxx Cortex-M3 programming manual 2.3.2对hard fault, bus fault等有具体的解释。keil的网站上也有概括性的解释:hard fault由bus fault, memory management fault或usage fault引起,前者有固定的仅次于NMI的高优先级;调试过程中出现的bus error属于bus fau
[单片机]
<font color='red'>stm32</font> hard fault及堆栈探究
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved