【TIM/PWM】驱动舵机

用TIM函数配置PWM输出比较模块的函数
TIM_OCxInit();//OC就是Output Compare输出比较
TIM_OCStructInit();//初始化输出比较单元,给输出比较结构体赋一个默认值
TIM_SetCompare1();//单独更改CCR寄存器值的函数,在运行的时候更改占空比
(下面是一些小功能和运行时更改参数的函数)
TIM_ForcedOCxConfig();//配置强制输出模式,在运行中需要暂停输出波形并且强制输出高或低电平
(没啥用,因为强制输出高电平==设置100%占空比,强制输出低电平==设置0%占空比)
TIM_OCxPreloadConfig();//配置CCR寄存器的预装功能(影子寄存器——写入值不会立即生效,而是在更新事件后再生效)
TIM_CtrlPWMOutputs();//仅高级定时器使用,其输出PWM时,需要调用这个函数使能主输出,否则PWM不能正常输出

初始化PWM时从左至右参考该图流程
驱动舵机的关键
  • PWM 频率:  Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM周期对应计数器的一个溢出更新周期——PWM频率等于计数器的更新频率
  • PWM 占空比:  Duty = CCR / (ARR + 1)
  • PWM 分辨率:  Reso = 1 / (ARR + 1)
由图可知周期为20ms,时钟频率为72MHz(默认),分别可以解得PSC、ARR的值及其对应舵机输出轴转角
//PWM频率为【1/20ms=50Hz】
//此处PSC和ARR的值并不固定,可参考设置为【PSC+1】为72,【ARR+1】为20K
  • 重点:此处的CCR不与占空比有关,纯粹就是对舵机ms的表示,例如CCR=500时代表0.5ms,CCR=1000时代表1ms

1、完成驱动文件导入操作和编写驱动程序基本代码(参考之前文章)
//将【PWM】配置文件放在【Hardware】文件夹里
2、在PWM.c中初始化函数 PWM _Init
void PWM_Init(void)
{
//第一步:开启时钟(注意使用APB1的开启时钟函数,因为TIM2是APB1总线的外设)
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    
    
//第二步:选择时基单元的时钟(在stm32f10x_tim.h文件中查找函数)
    TIM_InternalClockConfig(TIM2);//这里选择为内部时钟
//时基单元就由内部时钟驱动了
    
    
//第三步:配置时基单元(在stm32f10x_tim.h文件中查找函数)
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//指定计数器模式(此处选择向上计数)
    TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;//指定要在下一次更新事件时加载到ARR自动重新加载寄存器中的周期值  ARR取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//指定用于划分TIM时钟的预分频器值    PSC取值[0,65535]
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//指定重复计数器的值(高级定时器才用得上,本项目给0)
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化时基单元
//第四步:初始化输出比较单元(通道)【引脚定义表】
//使用PA1口对应第一个输出比较通道
    TIM_OCInitTypeDef TIM_OCInitStructure;
    
//为了避免出现不确定因素,PWM需要先把结构体成员完整配置一遍默认初始值,再根据需要更改个别地方
    TIM_OCStructInit(&TIM_OCInitStructure);//给结构体赋初始值
    
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//设置输出比较的模式
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置输出比较的极性
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
    TIM_OCInitStructure.TIM_Pulse = 0;//设置CCR的值
    TIM_OC2Init(TIM2,&TIM_OCInitStructure);
//到此通道初始化完成,可以在TIM2的OC2通道上输出PWM波形
//波形需要借用GPIO口进行输出
//TIM2的OC2的通道借用了PA1【引脚定义表】
//第五步:初始化GPIO口
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
//不需要打开中断和配置NVIC
    
//第六步:启动定时器(在stm32f10x_tim.h文件中查找函数)
    TIM_Cmd(TIM2,ENABLE);
    
//至此PWM波形就能通过PA1输出了
//通过PWM的频率、占空比、分辨率计算公式可以得到ARR、PSC、CCR值
//当PSC=72-1    ARR=20000-1    CCR=1500时
//现象为舵机转到0°位置
}
3、在PWM.c中编写更改CCR函数 PWM_SetCompare2
//在运行过程中更改CCR值(改变占空比)CCR在初始化时为0
void PWM_SetCompare2(uint16_t Compare)//单独更改通道1的CCR值
{
    TIM_SetCompare2(TIM2,Compare);
}
//TIM_SetCompare函数设置的是CCR的值,不代表直接设置占空比,占空比是由【CCR】和【ARR+1】共同决定的
4、在PWM.h中声明初始化函数 PWM _In it更改CCR 函数 PWM_SetCompare2
void PWM_Init(void);
void PWM_SetCompare2(uint16_t Compare);
5、在主程序main.c中 #includ "PWM .h "
#include "PWM.h"
6、在主循环之前先初始化PWM
7、在主循环中编写程序主体
int main(void)
{
    PWM_Init();
    OLED_Init();
    
    PWM_SetCompare2(1500);//舵机转到0°
    while(1)
    {
    }
}
实现功能:上电后舵机转到0°

最终目标
一、编写函数,功能为舵机设置角度,参数为0°—180°,可以更直观的调整调度
  • 建立舵机模块完成驱动文件导入操作和编写驱动程序基本代码
//将【Servo】配置文件放在【Hardware】文件夹里
2、在Servo.c中初始化函数 Servo _Init
void Servo_Init(void)
{
    PWM_Init();//将其PWM底层初始化
}
3、在Servo.c中编写更改CCR函数 Servo_SetAngle
/*Angle参数计算
Angle=0°        CRR=500
Angle=180°        CRR=2500
通过一次函数可以得到Angle关系式为:SetAngle=Angle/180*2000+500
也就是用函数设置舵机角度为0°时,给CCR赋值500
                        为180°时,给CCR赋值2500
*/
void Servo_SetAngle(float Angle)
{
    PWM_SetCompare2(Angle/180*2000+500);
}
4、在Servo.h中声明初始化函数 Servo _Init和更改CCR函数 Servo_SetAngle
void Servo_Init(void);
void Servo_SetAngle(float Angle);
5、在主程序main.c中 #includ "Servo .h "(比之前用PWM更加直观,知道用的是什么外设)
#include "Servo.h"
//设置角度全部变量float Angle
float Angle;
6、在主循环之前先初始化Servo
  • 添加按键模块
1)在主程序main.c中 #includ "Key .h "
2)设置键码全局变量 uint8_t KeyNum;
3)初始化按键模块 Key_Init();
7、在主循环中编写程序主体
uint8_t KeyNum;
float Angle;
int main(void)
{
    Servo_Init();
    OLED_Init();
    Key_Init();
    OLED_ShowString(1,1,"Angle:");
    
    while(1)
    {
        KeyNum = Key_GetNum();
        if(KeyNum == 1)
        {
            Angle += 30;
        }
            if(Angle > 180)
            {
                Angle = 0;
            }
            Servo_SetAngle(Angle);
            OLED_ShowNum(1,7,Angle,3);
    }
}
实现功能:上电后OLED显示Angle:000,每按下一次按键角度加30,加到180时返回0角度

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32中,可以使用PWM信号来驱动舵机。根据引用\[1\]和引用\[2\]的代码片段,可以看出在STM32中使用定时器来生成PWM信号来控制舵机角度。具体的步骤如下: 1. 配置定时器的时钟和分频系数,以确定计数频率。例如,可以将定时器时钟设置为84MHz,分频系数设置为84,这样计数频率就为1MHz。 2. 根据舵机的控制原理,将定时器的重装载值设置为适当的值,以确定PWM的频率。例如,可以将重装载值设置为500,这样PWM的频率就为2kHz。 3. 使用TIM_SetCompare函数来设置定时器的比较值,从而控制舵机角度。根据引用\[2\]中的代码,可以将角度值转换为脉冲值,并将其设置为比较值。 4. 在主循环中,可以使用延时函数来控制舵机角度。根据引用\[1\]中的代码,可以使用TIM_SetCompare函数来设置舵机角度,并使用延时函数来控制舵机在不同角度之间的切换。 总结起来,使用STM32的定时器和PWM功能可以方便地驱动舵机,通过设置定时器的时钟、分频系数、重装载值和比较值,可以控制舵机角度。 #### 引用[.reference_title] - *1* *3* [STM32F407——PWM驱动舵机](https://blog.csdn.net/weixin_47316662/article/details/124554622)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32驱动舵机](https://blog.csdn.net/xiaoyuanwuhui/article/details/83713459)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值