STM32控制舵机讲解,从入门到放弃。

2023-11-12

STM32控制舵机


前言

我们这里拿STM32F103C8T6作为我们的芯片,通过PB9端口输出PWM,实现控制舵机。我们这里就拿180°的SG90舵机。


一、PWM


PWM是什么?

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%.

STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样, STM32 最多可以同时产生 30 路 PWM 输出!这里我们仅利用 TIM4的 CH4产生一路 PWM 输出。

在这里插入图片描述
PWM的频率: 是指1秒钟内信号从高电平到低电平再回到高电平的次数(一个周期);
也就是说一秒钟PWM有多少个周期

单位: Hz

表示方式: 50Hz 100Hz

PWM的周期:

T=1/f

周期=1/频率

50Hz = 20ms 一个周期

如果频率为50Hz ,也就是说一个周期是20ms 那么一秒钟就有 50次PWM周期
PWM占空比: 是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,由于PWM周期为20ms,所以(以舵机会转动 45°为例),占空比就应该为1ms/20ms = 5%,所以TIM_SetCompare1的 TIMx 捕获比较 1 寄存器值就为200-200*5% = 190

单位: % (0%-100%)

表示方式:20%

如何实现PWM信号输出?

<1> 可以直接通过芯片内部模块输出PWM信号,前提是这个I/O口要有集成模块,只需要简单几步操作即可,这种自带有PWM输出的功能模块在程序设计更简便,同时数据更精确。如下图,一般的IC口都会标明这个是否是PWM口;

在这里插入图片描述

<2> 但是如果IC内部没有PWM功能模块,或者要求不是很高的话可以利用I/O口设置一些参数来输出PWM信号,因为PWM 信号其实就是一高一低的一系列电平组合在一起。具体方法是给I/O加一个定时器,对于你要求输出的PWM信号频率与你的定时器一致,用定时器中断来计数,但是这种方法一般不采用,除非对于精度、频率等要求不是很高可以这样实现。

二、舵机


什么是舵机?

舵机也叫也叫 RC 伺服器,通常用于机器人项目,也可以在遥控汽车,飞机等航模中找到它们。
类似舵机这样的伺服系统通常由小型电动机,电位计,嵌入式控制系统和变速箱组成。
电机输出轴的位置由内部电位计不断采样测量,并与微控制器(例如STM32,Arduino)设置的目标位置进行比较;
根据相应的偏差,控制设备会调整电机输出轴的实际位置,使其与目标位置匹配。这样就形成了闭环控制系统。

在这里插入图片描述

控制原理

通过向舵机的信号信号线发送PWM信号来控制舵机的输出量;

一般来说,PWM的周期以及占空比,我们是可控的,所以PWM脉冲的占空比直接决定了输出轴的位置。

下面举个例子;

当我们向舵机发送脉冲宽度为1.5毫秒(ms)的信号时,舵机的输出轴将移至中间位置(90度);

脉冲宽度为1ms时,舵机的输出轴将移至最小的位置(0度);

脉冲宽度为2ms时,舵机的输出轴将移至最小的位置(180度);

注意:不同类型和品牌的伺服电机之间最大位置和最小位置的角度可能会不同。许多伺服器仅旋转约170度(或者只有90度),但宽度为1.5 ms的伺服脉冲通常会将伺服设置为中间位置(通常是指定全范围的一半);

具体可以参考下图;
在这里插入图片描述

占空比 = t / T 相关参数如下:

t = 0.5ms——————-舵机会转到 0 °
t = 1.0ms——————-舵机会转到 45°
t = 1.5ms——————-舵机会转到 90°
t = 2.0ms——————-舵机会转到 135°
t = 2.5ms——————-舵机会转到 180°

因为:PWM周期为20ms = (7200*200)/72000000=0.02
所以:TIM_Period = 199,TIM_Prescaler = 7199,就是我的程序入口参数


参考代码

编写步骤:

<1>开启 TIM4 ,GPIOB时钟,配置 PB9 为复用输出。

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能定时器 4 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE); //复用时钟使能

<2>初始化 TIM4,设置 TIM4 的 ARR 和 PSC。

TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化 TIMx 的

<3>设置 TIM4_CH4的 PWM 模式,使能 TIM4 的 CH4 输出。

void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)

看看结构体 TIM_OCInitTypeDef
的定义:

typedef struct
{
	uint16_t TIM_OCMode;
	uint16_t TIM_OutputState;
	uint16_t TIM_OutputNState; 
	uint16_t TIM_Pulse;
	uint16_t TIM_OCPolarity;
	uint16_t TIM_OCNPolarity;
	uint16_t TIM_OCIdleState;
	uint16_t TIM_OCNIdleState;
} TIM_OCInitTypeDef;

我们来看看里面的参数:

参数 TIM_OCMode 设置模式是 PWM 还是输出比较,这里我们是 PWM 模式。
参数 TIM_OutputState 用来设置比较输出使能,也就是使能 PWM 输出到端口。
参数 TIM_OCPolarity 用来设置极性是高还是低。
其他的参数 TIM_OutputNState, TIM_OCNPolarity, TIM_OCIdleState 和 TIM_OCNIdleState 是
高级定时器 TIM1 和 TIM8 才用到的。

配置如下:

TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式 2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高
TIM_OC4Init(TIM4, &TIM_OCInitStructure); //初始化 TIM4 OC4

<4>使能 TIM4。

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

<5>修改 TIM4_CCR4 来控制占空比。

void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4)

最终代码段:

//time.c
#include "time.h"
#include "stm32f10x.h"
#include "sys.h"

void TIM4_PWM_Init(u16 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStrue;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStrue);
	
	TIM_TimeBaseStructure.TIM_Period = arr; 
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; 
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); 
	
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; 
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC4Init(TIM4,&TIM_OCInitStructure);
	
	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
	TIM_Cmd(TIM4,ENABLE);
}



下面就是主函数的代码:

//main.c
#include "stm32f10x.h"
#include "time.h"
#include "sys.h"
#include "usart.h"
#include "delay.h"

int main(void)
{
	delay_init();
	TIM4_PWM_Init(199,7199);
  while (1)
 {
	 
		delay_ms(10);
	 
		TIM_SetCompare4(TIM4,190);
	
 }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32控制舵机讲解,从入门到放弃。 的相关文章

  • 具有可绑定属性的自定义视图未在 Xamarin.Forms SAP 上正确绑定

    我有一个复选框 应该触发按钮的 IsEnabled 事件 但不知何故 应该执行的命令永远不会正确绑定并因此执行 这是 CheckBox xaml cs 控件 中的可绑定属性 public static readonly BindablePr
  • 在动态事件处理程序中引用“this”

    在我的 myClass 类中 我使用 Reflection Emit 为 myClass 类成员之一动态编写事件处理程序 我已经成功地做到了这一点 现在 我想修改事件处理程序以调用 myClass 类中的实例方法之一 但是 我无法弄清楚如何
  • 为什么 VB.NET 和 C# 中针对值检查 null 存在差异?

    In VB NET http en wikipedia org wiki Visual Basic NET有时候是这样的 Dim x As System Nullable Of Decimal Nothing Dim y As System
  • 如何使用 MVVM 更新 WPF 中编辑的数据? [复制]

    这个问题在这里已经有答案了 我正在为聊天应用程序构建 UI 设计 在尝试更新所选联系人的消息时遇到问题 选择现有联系人 选择编辑选项 然后编辑其属性 例如用户名和图像 后 唯一进行的更改是联系人的用户名和图像 我仍然想更改 MessageM
  • 在Application_AquireRequestState事件中用POST数据重写Url

    我有一个在其中注册路线的代码Application AcquireRequestState应用程序的事件 注册路由后 我会在 Http 运行时缓存中设置一个标志 这样我就不会再次执行路由注册代码 在此事件中注册路线有特定原因Applicat
  • 是否有像 gccxml 这样的用于生成包装器的 C 标头解析器工具?

    我需要为一种新的编程语言编写一些 C 标头包装器 并且想要类似 gccxml 的东西 但不完全依赖 gcc 以及它在 Windows 系统上带来的问题 只需要读C而不是C 只要有完整的文档记录 任何格式的输出都可以 Linux Solari
  • 如何使用 wpf webbrowser 将数据发布到 Web 服务器

    我想从数据库获取数据并使用它来让用户登录到网站 我有一个包含 Web 浏览器控件的 wpf 页面 我有这样的代码 用于将用户登录到用 php 编写的网站
  • 手动将 ClientBase 集合类型从 Array[] 更改为 List<>

    我将自己的 WCF 代理与 Client Base 一起使用 我想做一些类似于 svc util 中的 ct 属性的操作 并告诉代理返回 List 集合类型 我不能使用 List 因为实体由 nhibernate 管理 所以我必须使用 IL
  • 您可以在一个 Windows Azure 实例上部署多个 Web 应用程序吗?

    是否可以在一个 windows azure 小型计算实例中运行一堆 Web 应用程序 我正在考虑使用 Azure 作为放置一堆处于开发和非生产状态的项目 Web 应用程序 的地方 有些实际上已经被封存了 但我想在某个地方有一个活跃的实例 我
  • 系统错误 124 - SHFileOperation 的 ERROR_INVALID_LEVEL

    我在使用时遇到问题SHFileOperation SHFileOperation SHFILEOPSTRUCT https stackoverflow com questions 9191415 shfileoperation shfile
  • 允许使用什么类型的内容作为 C 预处理器宏的参数?

    老实说 我很了解 C 编程语言的语法 但对 C 预处理器的语法几乎一无所知 尽管我有时在编程实践中使用它 所以问题来了 假设我们有一个简单的宏 它扩展为空 define macro param 可以放入宏调用构造中的语法有哪些限制 调用宏时
  • .NET JIT 编译的代码缓存在哪里?

    NET 程序首先被编译为 MSIL 代码 当它被执行时 JIT编译器会将其编译为本机机器代码 我想知道 这些JIT编译的机器代码存储在哪里 它只存储在进程的地址空间中吗 但由于程序的第二次启动比第一次快得多 我认为即使在执行完成后 该本机代
  • 使用(linq to sql)更新错误

    我有两个表 通过外键 CarrierID 绑定 Carrier CarrierID CarrierName CarrierID 1 CarrierName DHL CarrierID 2 CarrierName Fedex Vendor V
  • 如何使用收益返回和递归获得字母的每个组合?

    我有几个像这样的字符串列表 可能有几十个列表 1 A B C 2 1 2 3 3 D E F 这三个仅作为示例 用户可以从几十个具有不同数量元素的类似列表中进行选择 再举个例子 这对于用户来说也是一个完全有效的选择 25 empty 4 1
  • 纯虚函数可能没有内联定义。为什么?

    纯虚函数是那些虚函数并且具有纯说明符 0 第 10 4 条第 2 款C 03 的内容告诉我们什么是抽象类 顺便说一句 如下 注意 函数声明不能 同时提供纯说明符和定义 尾注 示例 struct C virtual void f 0 ill
  • C++ [Windows] 可执行文件所在文件夹的路径[重复]

    这个问题在这里已经有答案了 我需要访问一些文件fstream在我的 Windows 上的 C 应用程序中 这些文件都位于我的exe文件所在文件夹的子文件夹中 获取当前可执行文件的文件夹路径的最简单且更重要的 最安全的方法是什么 Use 获取
  • 使用 Chrome 和 Selenium 设置 LocalStorage

    我正在尝试使用 OpenQA Selenium 和 Chrome 设置本地存储键和值 我认为这相当微不足道 但我似乎无法让它发挥作用 我对 C 很陌生 所以我可能错过了一些东西 无论如何 我有这个功能 public static void
  • C# 粘贴到文本框时检查剪贴板中的字符

    有没有一些方法可以在粘贴到文本框 C 之前仅检查剪贴板中的字符 Ctrl V 和右键单击 gt 粘贴 但不使用 MaskedTextbox 在文本框文本更改中添加规则以仅接受数字 例如 private string value privat
  • 无法使 Polly 超时策略覆盖 HttpClient 默认超时

    我正在使用 Polly 重试策略 并且正如预期的那样 在重试过程中HttpClient达到 100 秒超时 我尝试了几种不同的方法来合并 Polly 超时策略 将超时移至每次重试而不是总计 但 100 秒超时仍然会触发 我读过大约 5 个
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec

随机推荐

  • 计算机视觉2021年3月28最新论文

    编辑 AI速递 计算机视觉 3月28日 1 USB Universal Scale Object Detection Benchmark 标题 USB 万能物体检测基准 链接 https arxiv org abs 2103 14027 2
  • Connected to the target VM, address:XXXX, transport: socket

    问题 1 Connected to the target VM address 127 0 0 1 65604 transport socket 排查方案 我是最近半年多次遇到这个问题 这个就是用debug模式启动程序 方便调试 运行一半直
  • Ablation Study消融研究

    作者 飘哥 链接 https www zhihu com question 291655038 answer 683038545 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 术语 消融研究 通常用于神经网
  • Python解释器验证器工具类

    需求背景 现需要实现一个工具类 功能为验证给定路径是否为有效的 Python 解释器可执行文件 不一定是主程序所使用的解释器 并获取该解释器版本信息 是否安装某模块 包等信息 该工具类将赋予主程序类似 PyCharm 中选取 Python
  • C#的架构、框架、设计模式

    建立层务必使用类库选项 不要使用文件夹 没错 说的就是我自己 一 两层架构 1 架构概述 两层架构适合小型 中小型项目 名称 标识 用途 数据访问对象 DAL 模型服务 需要添加Models引用 实体对象 Models 模型 用户界面 UI
  • SpringMVC @RequestBody 自动转json Http415错误

    项目中想用 RequestBody直接接收json串转成对象 网上查了使用方法 看着非常简单 不过经过测试很快发现页面直接报415错误 h1 HTTP Status 415 h1 hr size 1 p b type b Status re
  • React的几种路由配置方法

    1 标签 常用 import IndexRoute from react router const Dashboard React createClass render return div Welcome to the app div R
  • python内置array模块,与numpy中的array和list之间的转换

    numpy中matrix类型与array类型的转换 如何让 M matrix 1 2 3 4 如何转变为 array 1 2 3 4 比较优雅的办法 x matrix arange 12 reshape 3 4 gt gt gt x mat
  • 全国计算机等级考试题库二级C操作题100套(第76套)

    第76套 给定程序中 函数fun的功能是 计算下式前n项的和作为函数值返回 例如 当形参n的值为10时 函数返回 0 204491 请在程序的下划线处填入正确的内容并把下划线删除 使程序得出正确的结 果 注意 源程序存放在考生文件夹下的BL
  • 使用Fiddler修改请求参数

    1 下载比较新版的Fiddler 2 进入到调试的页面 并填写好参数 以获取短信验证码接口为例 3 先清空Fiddler列表中已经存在的请求 以便观察 4 打开断点调试 下面两种方式都可以 F11是快捷键 按F11 键盘快捷键 或者如下图勾
  • Qt在嵌入式系统QNX的HMI应用方案

    author 锋影 扣扣 174176320 e mail 174176320 qq com 黑莓推出了其全新的黑莓10平台QT的智能手机和平板电脑 它产生了大量的兴趣在QT上移动 黑莓10是基于QNX1操作系统的黑莓 也许不是很出名 是Q
  • lightGBM 调参

    文章目录 1 概述 1 lgb cv函数使用方法 1 参数 2 param需要填写的参数 2 GridSearchCV调参 第一步 学习率和迭代次数 第二步 确定max depth和num leave 第三步 确定min data in l
  • Mac配置与下载安卓SDK,配置adb命令

    所以如果想要单独下载SDK 参考如下步骤 文章目录 配置步骤 1 首先需要安装java的JDK 2 解压上面下载好的文件 3 补充SDK内容 4 配置环境变量 5 测试adb命令 其他信息 配置步骤 1 首先需要安装java的JDK 首先登
  • Linux查看磁盘空间

    如何查看磁盘空间 1 查看内存空间 dever iZ2zeewvm4yos65shrzg3wZ free total used free shared buff cache available Mem 7724300 1528996 300
  • vue项目的webpack打包优化

    前言 我第一次从搭建项目环境 到打包准备上线测试 vue对开发者来说学习成本不高 带来了很多的便利 没有经过如何优化 直接打包出来 打开页面时就看到无尽的加载中 啥 是网络不好了 等了半分钟时间页面终于出现了 我第一次打包 所以百度做功课
  • Xilinx IP核手册阅读——FIFO

    目录 Introduction Ch 1 Overview Feature Summary Native FIFO Interface Signals Applications Native FIFO Applications Ch 2 P
  • 笔记本电脑销量排名_2020最佳笔记本电脑品牌公布!华硕第一,戴尔惠普分列二三名_搜狐汽车...

    本文车型速览 除了文章作者的主观观点外 我们正尝试基于全网可查的客观数据 为您提供中立 客观的参考依据 本文部分车型速览 展开 微信扫码 直接一次看完附近所有城市低价 附近城市均有经销商可售卖至本市 2020最佳笔记本电脑品牌公布 华硕第一
  • Java实现http请求访问的实现和处理DefaultHttpClient过期和URL连接格式问题

    Java实现http请求代码 String strUrl http 172 0 0 1 80 api Notifiction sendForbidden userId dhdhsh data shshh try 增加代码下面两行代码解决UR
  • 计算机网络默认网关怎么看,默认网关怎么查看 查看电脑默认网关的方法介绍...

    本机默认网关是什么 默认网关怎么查看 有时我们需要对电脑进行相关设置 此时就要知道默认网关 那么 怎么查看电脑默认网关呢 下面我们就一起去了解一下 默认网关是什么 一个用于 TCP IP 协议的配置项 是一个可直接到达的 IP 路由器的 I
  • STM32控制舵机讲解,从入门到放弃。

    STM32控制舵机 文章目录 STM32控制舵机 前言 一 PWM PWM是什么 如何实现PWM信号输出 二 舵机 什么是舵机 控制原理 参考代码 前言 我们这里拿STM32F103C8T6作为我们的芯片 通过PB9端口输出PWM 实现控制