stm32f407驱动20KG 270度舵机

news/2024/11/24 6:38:50/

这里写自定义目录标题

  • 前言
    • PWM概述
    • 代码讲解
    • 舵机原理

前言

在学习的过程中发现,及时复习是一个好的学习习惯,本文记录使用STM32F407ZGT6控制20KG 270度舵机的学习过程,以便日后复习。

PWM概述

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。广泛应用在从测量、通信到功率控制与变换的许多领域中。简单一点,就是对脉冲宽度的控制,PWM 原理如图:
请添加图片描述
“图一”

其中:
CNT:计数器

ARR:重装值寄存器

CCRx:比较寄存器

通过参考手册中可知,stm32f407出了定时器6,7没有产生PWM功能,其他定时器都有。我上网看了一些教程,发现大多都是利用PA0
的定时器2通道1产生PWM,但是我PA0使用了按键触发外部中断,所以换成了PA1定时器2通道2。
在这里插入图片描述
在配置PWM之前,再来说一个知识,占空比。
占空比:占空比是指在一个脉冲循环内,通电时间(可能是高电平也可能是低电平)相对于总时间所占的比例。
在这里插入图片描述
这里我上网找了一张图片,其实很简单,就是脉冲宽度占总时间的比例,就是占空比。

代码讲解

废话不多说,我们以便将代码,一边说,上代码:
首先初始化结构体,开启定时器2和端口A的时钟,这没什么好说的。

	GPIO_InitTypeDef 			GPIO_InitStructure;TIM_TimeBaseInitTypeDef  	TIM_TimeBaseStructure;TIM_OCInitTypeDef  			TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);  	//TIM2时钟使能  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//使能PORTA时钟

然后看stm32f407ZGT6的引脚定义,这小小的一步其实很关键,记得刚开始学习的时候没有看引脚定义,当时用到了PA14,但是PA14主功能并不是普通的GPIO,所以怎么都不能成功看到效果,我找到了PA1的引脚定义如下图
在这里插入图片描述
另外,我还找到了全面的STM32F407ZGT6引脚功能表,大家要使用请自动移步(好吧,只是我懒,懒得在搬过来了,见谅)https://blog.csdn.net/u011510016/article/details/100404880
通过图中可以看出PA1的主功能就是PA1,但是我们要使用它的定时器功能,所以要复用一下,关于复用的概念,我就不在此赘述了
直接上代码:

GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM2); //GPIOA1复用为定时器2

这个函数很好理解啊,就是把A端口1号引脚复用为定时器2模式
在这里插入图片描述
这里我帮大家找到了这个函数的注释,大家英语水平都很好,咱也就不翻译了,直接看就好,是不是嘎嘎简单!
接下来就是引脚的配置了

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;           //GPIOA1GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PA1

下面关于定时器的配置还是有必要好好絮叨絮叨滴,我先把代码奉上,然后一点点讲解

	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);//初始化定时器2//初始化TIM2 Channe2 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较使能输出TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低TIM_OCInitStructure.TIM_Pulse = 0;//比较初始值TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2是的预装载寄存器TIM_ARRPreloadConfig(TIM2,ENABLE);//ARPE使能TIM_Cmd(TIM2, ENABLE);  //使能TIM2										  

其实也不是很多,靓仔,听我一一道来:
我们先来看定时器分频和自动重装载值,这两句我觉得是最重要的了

TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值

这里我又为大家找来了一张图
在这里插入图片描述
大家不要看别的,直接看这
在这里插入图片描述

定时器2是普通定时器,它使能APB1硬件时钟,根据中文开发指南
在这里插入图片描述

APB1先是4分频,所以预分频要×2
定时器2时间计算方法: 频率=(168/4×2)/TIM_TimeBaseStructure.TIM_Prescaler
计数时间=TIM_TimeBaseStructure.TIM_Period /频率
就比如我的定时器分频TIM_TimeBaseStructure.TIM_Prescaler=psc;中psc为8399,那么它的频率就为84MHZ/8400=10000HZ,到此肯定会有靓仔有疑惑了——你他喵的psc定义的为8399,那么为什么你计算频率的时候除了8400呢,你小子框我
有问题很好,但是我没有骗你,为啥呢,因为我的计数初值为0,而0-8399为8400个数,所以是除8400!
好了,我们继续。
知道了我们的频率为10KHZ,那么就意味着计10000个数对应的时间为1秒,也就是说周期就为1/10000秒,也就是100ms。

好,分频值解释好了,我们再来说自动重装载值arr得定义意味着啥
看我文章的第一张图,也就是图一(好吧,这句话确实是句废花),自动重装载值,见名知意,就是自动重新装载的值(喵的,好像又是一句废花),就比如你设置从0开始计数,自动重装载值为100,那么计数就是0,1,2,3,…99,100,然后接下来自动又变为0,1,2,3,…99,100。(好吧,只可意会不可言传,受不了了,我就只能这么解释了)这两句解释完了,我们接着看。

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

PWM模式也是一个细节,在手册中是这么解释的:
以通用定时器 (TIM2 到 TIM5)计数模式为例:
110:PWM 模式 1––在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为有 效状态,否则为无效状态。在递减计数模式下,只要 TIMx_CNT>TIMx_CCR1,通道 1 便为 无效状态 (OC1REF=0),否则为有效状态 (OC1REF=1)。
111:PWM 模式 2––在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为无 效状态,否则为有效状态。在递减计数模式下,只要 TIMx_CNT>TIMx_CCR1,通道 1 便为 有效状态,否则为无效状态
通道有效,则输出你设定的有效电平(极性电平)
通道无效,则输出你设定与有效电平相反电平(极性电平)
总结就是。
PWM模式1一只要TIMx_ CNT< TIMx_ CCR1,通道1便为有效状态,否则为无效状态。
PWM模式2-一只要 TIMx_ CNT < TIMx _CCR1,通道1便为无效状态,否则为有效状态。

TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2是的预装载寄存器

TIM_OC2Init、TIM_OC2PreloadConfig这两个函数,其实就是指定是哪个通道的,之前都是配置定时器2,但是我们用到的是通道2,但是之前并没有配置通道2,这里配置,在这里我还专门为大家找了函数解释
在这里插入图片描述
看英文的第一句,就是Channel2,不用我多说,懂得都懂。
在这里插入图片描述
对比一下TIM_OC1Init的解释就是Channel1。
OK,最后再来看一下main函数,在main初始化中写

TIM2_PWM_Init(199,8399);
大家可以算一下,我这个PWM的周期,很简单为20ms。讲了半天PWM,终于要到舵机了。

舵机原理

舵机和PWM之间有啥关系呢?
对于一般的舵机来说,所对应的PWM波的周期为20ms,即舵机接收的PWM信号频率为50HZ。
其空占比与转动角度的关系。普通舵机的舵量是0~180°。脉冲宽度范围 0.5ms ~ 2.5ms,我又为大家找了张图,说明一下,这图是我引用的请添加图片描述
但是,我们使用的舵机为270度,并不是180度,所以我们还要重新映射一下,我去网上看了一下卖家给的信息,他是这么说的
在这里插入图片描述
就是0.5ms对应0度,2.5ms对应270度,1.5ms对应135度,我列了张表格,这个如果看懂了上面的计算方法,自己很容易就可以计算出来对应的数值

输入信号脉冲宽度0.50.831.161.51.832.162.5
舵机输出角度04590135180225270
Compare2581215182225

其中Compare2我解释一下来自void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2)这个函数
在这里插入图片描述
这个函数,可以改变指定定时器的CCRX值,这里所对应的时间大家可以自己计算。

在while(1)中就可以写

		Delay_ms(1000);	 TIM_SetCompare2(TIM2,5);	//修改比较值,修改占空比对应0度Delay_ms(1000);	 TIM_SetCompare2(TIM2,8);	//修改比较值,修改占空比对应45度Delay_ms(1000);	 TIM_SetCompare2(TIM2,12);	//修改比较值,修改占空比对应90度Delay_ms(1000);	 TIM_SetCompare2(TIM2,15);	//修改比较值,修改占空比对应135度Delay_ms(1000);	 TIM_SetCompare2(TIM2,18);	//修改比较值,修改占空比对应180度Delay_ms(1000);	 TIM_SetCompare2(TIM2,22);	//修改比较值,修改占空比对应225度Delay_ms(1000);	 TIM_SetCompare2(TIM2,25);	//修改比较值,修改占空比对应270度

来观察舵机的运动情况

请添加图片描述


http://www.ppmy.cn/news/339662.html

相关文章

解决z-index不生效

<div class"loginContent"><div class"loginLogo flexCenter left"><img src"../i/loginLogo.png"/></div><!--登录输入区域--><div class"loginRight flexCenter right"><div class"log…

python格式化字符串 时间戳 转 UTC(2023-01-11T16:00:00Z)格式时间

前言&#xff1a;公司前端的时间参数分为两类 一种是时间戳传参&#xff0c;另一种是 2023-01-11T16:00:00Z &#xff08;UTC&#xff09;时间传参,有些脚本需要用到datatime.datatime因此要整理一下相关方法获取时间戳 my_timestamptime.time() print(my_timestamp) # 167349…

记一次黑苹果(Hackintosh)HighSierra10.13.3安装过程

记一次黑苹果&#xff08;Hackintosh&#xff09;HighSierra10.13.3安装过程 部件&#xff1a; 主板&#xff1a;华硕&#xff08;Asus&#xff09;Z270-ACPU&#xff1a;ntel Core i7-7700K Kaby Lake Quad-Core 4.2 GHz LGA 1151内存条&#xff1a;芝奇&#xff08;2 x 8G&…

微星主板在有RAID的情况下在NVME的SSD上安装Win10

硬件环境&#xff1a; 微星主板B550&#xff0c;SATA模式为RAID&#xff0c;Windows配置为UEFI 1*NVME SSD&#xff08;西数500G&#xff09;&#xff08;新购&#xff09; 1*NVME SSD&#xff08;海康1T&#xff09;&#xff08;原启动盘&#xff09; 5*SATA&#xff08;希…

台式机组RAID(SSD 256G*2 + RAID0)

一、最终的成果。 注&#xff1a;由于两个硬盘是三星的SSD 且是PCIe M.2接口。单个硬盘的读取速度本来就很快&#xff0c;所以组RAID0后&#xff0c;提升幅度不大。 二、电脑配置信息 处理器 英特尔Core i7-7700 3.60GHz 四核 主板 华硕PRIME Z270-P 内存 威刚 8GB ( …

条码生成 SDK - Zint 教程及示例

Zint 教程及示例 Introduction Zint 是一款优秀的开源的条码生成工具&#xff0c;它跨平台&#xff0c;它支持超过50种条码&#xff0c;囊括目前市场上主流的条码类型&#xff0c;包括 QR、PDF417 等等。Zint 的源码你可以在其 官网首页 找到下载链接。除了源码&#xff0c;你…

有关于搭建私有云的那些事。z270-ubuntu14

一百块钱入了一个Z270&#xff0c;改造了一下。 首先安装了ubuntu 14的server版本。 出现了无法安装的现象。这个时候进入shell&#xff0c;挂载U盘的sdv1分区&#xff0c;然后把iso文件挂载为cdrom即可。 进入后安装lamp环境&#xff0c;但是由于环境为php5.59&#xff0c;…

z270 1080ti ubuntu1610 cuda8 cudnn6下深度学习实验环境搭建 ubuntu1710和1704也适用

z270 1080ti ubuntu1610 cuda8 cudnn6下深度学习实验环境搭建 astron最近一直很忙&#xff0c;搭建实验环境的事情从11月一拖再拖&#xff0c;每次只能搞几个小时就得等几周才能回归&#xff0c;终于有两天时间来搞自己的深度学习环境了。之前安装各个版本的软件&#xff0c;都…