STM32 PWM控制舵机——原理、接线、源程序

article/2025/10/7 15:02:03

STM32——PWM 控制舵机

  • 通用定时输出PWM
    • PWM的工作原理
    • PWM的模式
      • TIM_OCMode_PWM1 (边沿对齐模式)
      • TIM_OCMode_PWM2(中央对齐模式)
    • 占空比
  • 舵机
    • 实物图
    • 接线
    • 舵机工作原理
    • 周期T
    • PWM占空比
  • TIM3 PWM输出 驱动SG90电机 配置过程:
    • 1. 使能GPIO时钟,TIM定时器时钟,部分重映射时钟
    • 2. 重映射定时器
    • 3. 配置GPIO结构体
    • 4. 配置通用定时器TIM结构体
    • 5. 配置PWM
  • stm32 超声波感应开盖垃圾桶
    • motor.c
    • motor.h
    • HC_SR04.c
    • HC_SR04.h
    • usart.c
    • usart.h
    • main.c
    • stm32 超声波感应开盖垃圾桶 效果展示

通用定时输出PWM

以TIM3为例,STM32的通用定时器氛围TIM2,TIM3,TIM4,TIM5,每个定时器都有独立的四个通道可以用来作为: 输入捕获,输出比较,PWM输出,单脉冲模式输出等。

STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM波输出,高级定时器TIM1,TIM8可以同时产生7路PWM输出,而通用定时器可以同时产生4路PWM输出,这样STM32可以最多同时输出30路PWM输出!

PWM的工作原理

在这里插入图片描述

以向上计数为例,讲述PWM原理:

  1. 在PWM输出模式下除了CNT(计数器当前值),ARR(自动重装载值),CCRx(捕获/比较寄存器值)。

  2. 当CNT小于CCRx时,TIMx_CHx通道输出低电平

  3. 当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平

所谓脉宽调制信号(PWM波),就是一个TIMx_ARR自动重装载寄存器确定频率(由它决定PWM周期),TIM_CCRx寄存器确定占空比信号。

PWM的模式

TIM_OCMode_PWM1 (边沿对齐模式)

在这里插入图片描述

向上计数时: 当TIMx_CNT<TIMx_CCRx时通道1为有效电平,否则为无效电平;

向下计数时: 一旦TIMx_CNT>TIMx_CCRx,CCR1通道1为无效电平,否则为有效电平。

TIM_OCMode_PWM2(中央对齐模式)

向上计数时: 当TIMx_CNT<TIMx_CCRx时通道1为无效电平,否则为有效电平;

向下计数时: 一旦TIMx_CNT>TIMx_CCRx,CCR1通道1为有效电平,否则为无效电平。

占空比

在这里插入图片描述

是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比。

舵机

实物图

在这里插入图片描述

接线

SG9O电机

硬件接线:

红线 : 3.3v/ 5v
黑 / 棕线 : GND
黄线 : 信号线

舵机工作原理

舵机的主要组成部分为伺服电机,所谓伺服就是服从信号的要求而动作。在信号来之前,转子停止不动;信号来到之后,转子立即运动。因此我们就可以给舵机输入不同的信号,来控制其旋转到不同的角度。
舵机接收的是PWM信号,当信号进入内部电路产生一个偏置电压,触发电机通过减速齿轮带动电位器移动,使电压差为零时,电机停转,从而达到伺服的效果。简单来说就是给舵机一个特定的PWM信号,舵机就可以旋转到指定的位置。

在这里插入图片描述

舵机上有三根线,分别是GND、VCC和SIG,也就是地线、电源线和信号线,其中的PWM波就是从信号线输入给舵机的。
一般来说,舵机接收的PWM信号频率为50HZ,即周期为20ms。当高电平的脉宽在0.5ms~2.5ms之间时舵机就可以对应旋转到不同的角度。

在这里插入图片描述

t = 0.5ms——————-舵机会转到 0 °
t = 1.0ms——————-舵机会转到 45°
t = 1.5ms——————-舵机会转到 90°
t = 2.0ms——————-舵机会转到 135°
t = 2.5ms——————-舵机会转到 180°
  • 1
  • 2
  • 3
  • 4
  • 5

周期T

PWM周期为20ms = 0.02s = (7200*200)/72000000

PWM占空比

是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比.由于PWM周期为20ms,所以(以舵机会转动 45°为例),占空比就应该为1ms/20ms = 5%,所以TIM_SetCompare1的 TIMx 捕获比较 1 寄存器值就为200 * 5% = 10

单位: % (0%~100%)

TIM3 PWM输出 驱动SG90电机 配置过程:

1. 使能GPIO时钟,TIM定时器时钟,部分重映射时钟

//1.使能GPIO时钟、定时器时钟、复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  • 1
  • 2
  • 3
  • 4

2. 重映射定时器

在这里插入图片描述

//2.重映射定时器
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
  • 1
  • 2

3. 配置GPIO结构体

GPIO_InitTypeDef gpioInitStructure;

//3.配置GPIO
gpioInitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
gpioInitStructure.GPIO_Pin = GPIO_Pin_5; //引脚5
gpioInitStructure.GPIO_Speed = GPIO_Speed_10MHz; //10Hz

GPIO_Init(GPIOB, &gpioInitStructure); //初始化

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4. 配置通用定时器TIM结构体

TIM_TimeBaseInitTypeDef timInitStructure;

//4.配置定时器
timInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频
timInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
timInitStructure.TIM_Period = 200-1; //设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。
timInitStructure.TIM_Prescaler = 7200-1; //设置了用来作为 TIMx时钟频率除数的预分频值。

TIM_TimeBaseInit(TIM3, &timInitStructure); //初始化

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5. 配置PWM

在这里插入图片描述

//5.配置PWM
timOCInitStructure.TIM_OCMode      = TIM_OCMode_PWM1; //边沿对齐模式
timOCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能
timOCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_High; //设置为高电平有效

TIM_OC2Init(TIM3, &timOCInitStructure); //初始化
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //配置自动加载的预加载寄存器

TIM_Cmd(TIM3, ENABLE); //使能

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

stm32 超声波感应开盖垃圾桶

motor.c

#include "motor.h"
#include "stm32f10x.h"

void motor_Init(void)
{
GPIO_InitTypeDef gpioInitStructure;
TIM_TimeBaseInitTypeDef timInitStructure;
TIM_OCInitTypeDef timOCInitStructure;

	<span class="token comment">//1.使能GPIO时钟、定时器时钟、复用时钟</span><span class="token function">RCC_APB2PeriphClockCmd</span><span class="token punctuation">(</span>RCC_APB2Periph_GPIOB<span class="token punctuation">,</span> ENABLE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">RCC_APB1PeriphClockCmd</span><span class="token punctuation">(</span>RCC_APB1Periph_TIM3<span class="token punctuation">,</span> ENABLE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">RCC_APB2PeriphClockCmd</span><span class="token punctuation">(</span>RCC_APB2Periph_AFIO<span class="token punctuation">,</span> ENABLE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//2.重映射定时器</span><span class="token function">GPIO_PinRemapConfig</span><span class="token punctuation">(</span>GPIO_PartialRemap_TIM3<span class="token punctuation">,</span> ENABLE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//3.配置GPIO</span>gpioInitStructure<span class="token punctuation">.</span>GPIO_Mode  <span class="token operator">=</span> GPIO_Mode_AF_PP<span class="token punctuation">;</span>gpioInitStructure<span class="token punctuation">.</span>GPIO_Pin   <span class="token operator">=</span> GPIO_Pin_5<span class="token punctuation">;</span>gpioInitStructure<span class="token punctuation">.</span>GPIO_Speed <span class="token operator">=</span> GPIO_Speed_10MHz<span class="token punctuation">;</span><span class="token function">GPIO_Init</span><span class="token punctuation">(</span>GPIOB<span class="token punctuation">,</span> <span class="token operator">&amp;</span>gpioInitStructure<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//4.配置定时器</span>timInitStructure<span class="token punctuation">.</span>TIM_ClockDivision <span class="token operator">=</span> TIM_CKD_DIV1<span class="token punctuation">;</span>timInitStructure<span class="token punctuation">.</span>TIM_CounterMode   <span class="token operator">=</span> TIM_CounterMode_Up<span class="token punctuation">;</span>timInitStructure<span class="token punctuation">.</span>TIM_Period        <span class="token operator">=</span> <span class="token number">200</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>timInitStructure<span class="token punctuation">.</span>TIM_Prescaler     <span class="token operator">=</span> <span class="token number">7200</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token function">TIM_TimeBaseInit</span><span class="token punctuation">(</span>TIM3<span class="token punctuation">,</span> <span class="token operator">&amp;</span>timInitStructure<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//5.配置PWM</span>timOCInitStructure<span class="token punctuation">.</span>TIM_OCMode      <span class="token operator">=</span> TIM_OCMode_PWM1<span class="token punctuation">;</span>timOCInitStructure<span class="token punctuation">.</span>TIM_OutputState <span class="token operator">=</span> TIM_OutputState_Enable<span class="token punctuation">;</span>timOCInitStructure<span class="token punctuation">.</span>TIM_OCPolarity  <span class="token operator">=</span> TIM_OCPolarity_High<span class="token punctuation">;</span><span class="token function">TIM_OC2Init</span><span class="token punctuation">(</span>TIM3<span class="token punctuation">,</span> <span class="token operator">&amp;</span>timOCInitStructure<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">TIM_OC2PreloadConfig</span><span class="token punctuation">(</span>TIM3<span class="token punctuation">,</span> TIM_OCPreload_Enable<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">TIM_Cmd</span><span class="token punctuation">(</span>TIM3<span class="token punctuation">,</span> ENABLE<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

motor.h

#include "stm32f10x.h"

void motor_Init(void);

  • 1
  • 2
  • 3
  • 4

HC_SR04.c

在STM32第9篇中可以找到 9. STM32——HC_SR04超声波测距

HC_SR04.h

在STM32分栏第9篇中可以找到 9. STM32——HC_SR04超声波测距

usart.c

在STM32分栏第6篇中可以找到 6. STM32——用串口发送数据点亮LED(串口的中断接收)

usart.h

在STM32分栏第6篇中可以找到 6. STM32——用串口发送数据点亮LED(串口的中断接收)

main.c

#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "shake.h"
#include "relay.h"
#include "exti.h"
#include "usart.h"
#include "tim.h"
#include "motor.h"
#include "SysTick.h"
#include "HC_SR04.h"

int main()
{
float Length=0;
// int pwmval=155;

	<span class="token function">motor_Init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">HC_SR04Init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">usart_init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

// printf(“abc”);

	<span class="token keyword">while</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>Length<span class="token operator">=</span><span class="token function">Get_Length</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"%.3f\r\n"</span><span class="token punctuation">,</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">delay_ms</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span><span class="token punctuation">(</span>Length<span class="token operator">&lt;</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token function">TIM_SetCompare2</span><span class="token punctuation">(</span>TIM3<span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">delay_ms</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>Length<span class="token operator">&gt;</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span><span class="token function">TIM_SetCompare2</span><span class="token punctuation">(</span>TIM3<span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

stm32 超声波感应开盖垃圾桶 效果展示

在这里插入图片描述

如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈。


http://chatgpt.dhexx.cn/article/TBujvl3N.shtml

相关文章

pwm波控制舵机原理(转)

文章转自&#xff1a;http://www.geek-workshop.com/thread-70-1-1.html 一、关于舵机&#xff1a; 舵机&#xff08;英文叫Servo&#xff09;&#xff1a;它由直流电机、减速齿轮组、传感器和控制电路组成的一套自动控制系统。通过发送信号&#xff0c;指定输出轴旋转角度。…

pwm信号控制舵机的简单原理

pwm信号控制舵机的简单原理 控制信号由接收机的通道进入信号调制芯片&#xff0c;获得直流偏置电压。它内部有一个基准电路&#xff0c;产生周期为20ms&#xff0c;宽度为1.5ms的基准信号&#xff0c;将获得的直流偏置电压与电位器的电压比较&#xff0c;获得电压差输出。最后&…

SG90舵机的原理和控制方式

前言 做过机器人、智能车或者玩航模的朋友应该对舵机不会陌生&#xff0c;这种舵机也是很常用的。 舵机只是我们通俗的叫法&#xff0c;它的本质是一个伺服电机&#xff0c;也可以叫做位置(角度)伺服驱动器。一般被应用在那些需要控制角度变化的系统中&#xff0c;可以方便的…

舵机控制原理和结构

原文&#xff1a;https://blog.zeruns.tech/index.php/archives/358/ 什么是PWM信号 PWM&#xff0c;英文名Pulse Width Modulation&#xff0c;是脉冲宽度调制缩写&#xff0c;它是通过对一系列脉冲的宽度进行调制&#xff0c;等效出所需要的波形&#xff08;包含形状以及幅…

舵机控制原理/舵机内部电路原理

舵机结构 舵机是我们常用到的末端执行器&#xff0c;但是在应用时我们只知道利用一定频率和周期的PWM来控制其摆动一定角度。及控制器给舵机一个周期为20ms的PWM波&#xff0c;高电平时间为0.5ms时对应0&#xff0c;高电平时间为2.5ms时对应180。以上规律适用于大多数180摆角的…

矩阵谱半径与矩阵范数的关系

摘自 程云鹏. 矩阵论(第二版)[M]// 矩阵论&#xff08;第二版&#xff09;. 西北工业大学出版社, 2000. p135~p137

谱半径

矩阵的谱或叫矩阵的谱半径&#xff0c;在特征值估计、广义逆矩阵、数值分析以及数值代数等理论的建树中&#xff0c;都占有极其重要的地位&#xff1b; 矩阵的谱半径为矩阵的特征值的模的最大值。 关于矩阵的谱&#xff08;半径&#xff09;的一个重要性质即是&#xff1a;任意…

【矩阵论笔记】谱半径

定义 例子 谱半径比他的诱导范数都小。 证明 例子 hemite对称矩阵 谱半径什么时候跟诱导范数相等&#xff1f;答曰&#xff1a;Hermite矩阵。

python求矩阵的谱半径

在学习计算方法的时候&#xff0c;线性方程组的迭代法中的雅可比(Jacobi)迭代法和高斯-塞德尔(Gauss-Seidel)迭代法的收敛条件中需要求矩阵的谱半径&#xff0c;而经过查阅资料&#xff0c;python numpy库中没有直接求谱半径的函数。 谱半径的定义为&#xff1a; 设A是n n矩阵…

实对称阵的谱半径是连续函数

矩阵的诱导范数&#xff08;算子范数&#xff09;的定义&#xff1a; ∣ ∣ A ∣ ∣ sup ⁡ ∣ ∣ x ∣ ∣ 1 ∣ ∣ A x ∣ ∣ ||A|| \sup_{||x|| 1}||Ax|| ∣∣A∣∣∣∣x∣∣1sup​∣∣Ax∣∣其中&#xff0c;||||可以是任何向量范数&#xff0c;由于该矩阵范数是由向量范…

PTA 1063 计算谱半径(Python3)

在数学中&#xff0c;矩阵的“谱半径”是指其特征值的模集合的上确界。换言之&#xff0c;对于给定的 n 个复数空间的特征值 { a1​b1​i,⋯,an​bn​i }&#xff0c;它们的模为实部与虚部的平方和的开方&#xff0c;而“谱半径”就是最大模。 现在给定一些复数空间的特征值&a…

1063 计算谱半径

问题描述&#xff1a; 在数学中&#xff0c;矩阵的“谱半径”是指其特征值的模集合的上确界。换言之&#xff0c;对于给定的 n 个复数空间的特征值 { a​1​​b​1​​i,⋯,a​n​​b​n​​i }&#xff0c;它们的模为实部与虚部的平方和的开方&#xff0c;而“谱半径”就是最大…

如何判断矩阵的谱半径 C语言,矩阵谱半径

矩阵谱半径指的是矩阵的最大特征值(含绝对值)。 它可以判断收敛性,也可以判断方程解的稳定性。 一般情况下,当存在一个单位矩阵减去另外一个矩阵的形式时, 谱半径小于一就是为了确保它们之间的差值为正这样逆矩阵才会存在,可以用来验证一个方案是否可行。 The radius of t…

一、向量范数、矩阵范数、谱半径、条件数

一、范数、条件数与谱半径 1. 范数 1.1 向量范数 向量范数的具体形式可以有很多种(满足上述三个条件的)&#xff0c;但常用的有以下三种 设 向 量 x ( ξ 1 , ξ 2 , … , ξ n ) T ∈ C n , 设向量 x\left(\xi_{1}, \xi_{2}, \dots, \xi_{n}\right)^{T} \in C^{n} , 设向量…

【高等工程数学】南理工研究生课程 突击笔记2 谱半径,条件数

高等工程数学 突击笔记2 文章目录 高等工程数学 突击笔记2写在前面一、谱半径什么是正规矩阵矩阵级数敛散性判断 二、条件数举个栗子条件数求误差总结 写在前面 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 本文主要是为了应付考试&#xff0c;因此很多原…

线性代数(四十八) : 谱半径

本节介绍复欧几里得空间映射到其自身的矩阵.给出其范数的一个简单而有用的下界. 该矩阵范数的定义同实欧几里得空间. 0 说明&#xff1a; 本节以下的研究都是针对复欧几里得空间到自身的映射 1 范数 2 特征值 设A为任意的复方阵.h为A的一个长度为1的特征向量.a为对应的特征…

高等工程数学 —— 第一章 (2)矩阵的谱半径与条件数

第一章 &#xff08;2&#xff09;矩阵的谱半径与条件数 文章目录 第一章 &#xff08;2&#xff09;矩阵的谱半径与条件数谱半径收敛矩阵矩阵级数矩阵幂级数 矩阵的条件数及应用 谱半径 谱半径其实就是最大特征值 注意这里谱半径是小于等于矩阵的任意范数的。在求特征值比较麻…

oracle安装问题---测试连接时不成功

1. 以前安装oracle比较顺利&#xff0c;这次安装时出现了一点问题 安装 oracle服务端时没有改账户密码&#xff0c; 出现密码失效 连接不成功的事情 第一步&#xff1b; 运行SQLPlus命令行工具&#xff08;即在命令行 输入sqlplus /nolog&#xff09; connect as sysdba;…

oracle安装及常见问题解决

oracle 11g安装详解 一、Oracle安装包准备 二、安装oracle和plsql 1、解压上述压缩包后---》打开文件夹后看见如下图&#xff0c;一个是oracle安装资料&#xff0c;一个是oracle客户端安装资料plsql。 2、打开oracle文件夹&#xff0c;找到安装程序【setup.exe】并双击 3、安装…

Oracle安装过程及问题解决

Oracle安装过程及问题解决 下载安装出现问题[INS-13001] 此操作系统不支持 Oracle 数据库。安装程序将不在系统上执行先决条件检查。[INS-35180]无法检查可用内存 下载安装 Oracle11下载地址 下载这两个文件 下载完成后,选中两个压缩包,右击,点击解压到当前文件夹 会生成一个…