STM32-PWM驱动舵机——HAL库

news2024/9/21 2:48:13

什么是舵机?

舵机,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。

舵机型号介绍:

市面上常见的舵机型号有 SG90、MG90S、MG995、MG996R 等等,主要是扭矩大小、工作电压大小、齿轮材质塑料或金属的不同。

一般分为180度和360度:

  • 180度:可以控制旋转角度、有角度定位。上电后舵机自动复位到0度,通过一定参数的脉冲信号控制它的角度。
  • 360°舵机版本不可控制角度,只能控制顺时针旋转、逆时针旋转、停止和调节转速。

引脚接线参考如下:

SG90STM32
PWM 信号线(橙色线)任意GPIO
VCC(红线)3.3/5V
GND(棕色线)GND

SG90原理

        舵机的控制信号是通过脉冲宽度调制(PWM)来实现的。PWM 信号的周期通常为20ms,而脉冲宽度则在 0.5ms 至 2.5ms 之间变化。这个脉冲宽度与舵盘的位置呈线性关系,范围从0度到180度。

        当给舵机提供特定宽度的脉冲信号时,输出轴会保持在相应的角度上,不受外界转矩的影响,直到接收到不同宽度的脉冲信号才会改变输出角度,使舵盘移动到新的位置。舵机内部有一个基准电路,产生周期为 20ms、宽度为 1.5ms 的基准信号。同时,还有一个比较器,用于将外部输入信号与基准信号进行比较,以确定转动方向和幅度,并生成驱动电机转动的信号。

        为了控制舵机,需要使用单片机来生成周期为 20ms 的脉冲信号,并通过控制脉冲的高电平时间在 0.5ms 至 2.5ms 之间来控制舵机的角度。这样,我们可以通过调整 PWM 信号的脉冲宽度来精确控制舵机的位置和运动。

以 SG90,180度版为例,那么对应的控制关系是这样的:

脉冲高电平角度占空比
0.5ms2.5%
1.0ms45°5.0%
1.5ms90°7.5%
2.0ms135°10.0%
2.5ms180°12.5%

PWM驱动舵机:

 因为:PWM 信号的周期通常为20ms,高电平宽度为0.5ms~2.5ms

代码:

TIM_HandleTypeDef tim3_handle = {0};
// init函数
void tim3_init(void)
{
    TIM_OC_InitTypeDef pwm_config = {0};
    
    tim3_handle.Instance = TIM3;
    tim3_handle.Init.Prescaler = 7200 - 1;
    tim3_handle.Init.Period = 200 - 1;
    tim3_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    HAL_TIM_PWM_Init(&tim3_handle);
    
    pwm_config.OCMode = TIM_OCMODE_PWM1;
    pwm_config.Pulse = 100;
    pwm_config.OCPolarity = TIM_OCPOLARITY_HIGH;
    HAL_TIM_PWM_ConfigChannel(&tim3_handle, &pwm_config, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&tim3_handle, TIM_CHANNEL_1);
}
//msp函数
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM3)
    {
        GPIO_InitTypeDef gpio_initstruct;
        //打开时钟
        __HAL_RCC_GPIOA_CLK_ENABLE();                           // 使能GPIOB时钟
        __HAL_RCC_TIM3_CLK_ENABLE();
        
        //调用GPIO初始化函数
        gpio_initstruct.Pin = GPIO_PIN_6;                    // 两个LED对应的引脚
        gpio_initstruct.Mode = GPIO_MODE_AF_PP;             // 推挽输出
        gpio_initstruct.Pull = GPIO_PULLUP;                     // 上拉
        gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;           // 高速
		HAL_GPIO_Init(GPIOA, &gpio_initstruct);
		
		gpio_initstruct.Pin = GPIO_PIN_1;
		gpio_initstruct.Mode = GPIO_MODE_INPUT;
		gpio_initstruct.Pull = GPIO_PULLUP;           // 上拉
        gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速(可选)
		HAL_GPIO_Init(GPIOA, &gpio_initstruct);       // 初始化 GPIOA 引脚 1
    }
}
//修改CCR值的函数
void tim3_compare_set(uint16_t val)
{
    __HAL_TIM_SET_COMPARE(&tim3_handle, TIM_CHANNEL_1, val);
}

void sg90_init(void)
{
    tim3_init();
}

void sg90_angle_set(uint16_t angle)
{
    uint16_t CCRx = (1.0 / 9.0) * angle + 5.0;
    tim3_compare_set(CCRx);
}

uint8_t key(void)
{
    uint8_t KeyNum = 0;
   

    if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET)
    {
        // 按键按下,等待去抖动
        delay_ms(20);
        if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET)  // 确认按键仍然按下
        {
            while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_SET);  // 等待按键释放
            delay_ms(20);  // 再次延时去抖动
            KeyNum = 1;  // 按键按下并释放,返回 1
        }
    }
	else
	{
		// PA1 是低电平
		delay_ms(20);
		if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET) 
		{
		while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1)==GPIO_PIN_RESET);
		delay_ms(20);
		KeyNum=2;
	}
}
	return KeyNum;
}

已知 PWM 信号的周期为20ms;高电平 0.5ms 指向 0° 位置,2.5ms 指向 180° 位置。如果我们要指向 angle°:

2.5-0.5=2ms,对应于180°

CCRx / (199 + 1) * 20 = 0.5 +(angle / 180)× 2

于是 CCRx =(1.0 / 9.0) * angle + 5.0

void SG_Control(uint16_t angle)
{
   float CCRx;
   CCRx =(1.0 / 9.0) * angle + 5.0;                             //占空比值 = 1/9 * 角度 + 5
   __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, (uint16_t )CCRx);
}

 

main.c

uint8_t KeyNum;			//定义用于接收键码的变量
float angle;
int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    led_init();                         /* 初始化LED灯 */
    sg90_init();

    while(1)
    { 
		KeyNum=key();
		if(KeyNum==1)
		{
			angle+=30;
			if(angle>180)
				angle=0;
		}
       sg90_angle_set(angle);
    }
}

 delay.c

/**
  * @brief  微秒级延时
  * @param  nus 延时时长,范围:0~233015
  * @retval 无
  */
void delay_us(uint32_t nus)
{
    uint32_t temp;
    SysTick->LOAD = 72 * nus;                           /* 设置定时器重装值 */
    SysTick->VAL = 0x00;                                /* 清空当前计数值 */
    SysTick->CTRL |= 1 << 2;                            /* 设置分频系数为1分频 */
    SysTick->CTRL |= 1 << 0;                            /* 启动定时器 */
    do
    {
        temp = SysTick->CTRL;
    } while ((temp & 0x01) && !(temp & (1 << 16)));     /* 等待计数到0 */
    SysTick->CTRL &= ~(1 << 0);                         /* 关闭定时器 */
}

/**
  * @brief  毫秒级延时
  * @param  nms 延时时长,范围:0~4294967295
  * @retval 无
  */
void delay_ms(uint32_t nms)
{
    while(nms--)
        delay_us(1000);
}
 
/**
  * @brief  秒级延时
  * @param  ns 延时时长,范围:0~4294967295
  * @retval 无
  */
void delay_s(uint32_t ns)
{
    while(ns--)
        delay_ms(1000);
}

/**
  * @brief  重写HAL_Delay函数
  * @param  nms 延时时长,范围:0~4294967295
  * @retval 无
  */
void HAL_Delay(uint32_t nms)
{
    delay_ms(nms);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2086681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux--IO多路复用(select,poll,epoll)

IO多路复用——select&#xff0c;poll&#xff0c;epoll IO多路复用是一种操作系统技术&#xff0c;旨在提高系统处理多个输入输出操作的性能和资源利用率。与传统的多线程或多进程模型相比&#xff0c;IO多路复用避免了因阻塞IO而导致的资源浪费和低效率问题。它通过将多个IO…

使用matplotlib可视化dataframe:让你的数据更生动有趣

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 1. 简介 在数据分析和可视化领域&#xff0c;matplotlib是一个非常强大的工具。它可以帮助将数据以图形的形式展示出来&#xff0c;使得数据更加直观、易于理解。本文将介绍如何使用matplotlib来可视化pandas中的Da…

小q的数列(c语言)

1./描述 //小q最近迷上了各种好玩的数列&#xff0c;这天&#xff0c;他发现了一个有趣的数列&#xff0c;其递推公式如下&#xff1a; // //f[0] 0 f[1] 1; //f[i] f[i / 2] f[i % 2]; (i > 2) // //现在&#xff0c;他想考考你&#xff0c;问&#xff1a;给你一个n&am…

趣映 v2.3.8 — 高级版,专注动画制作,自媒体变现

趣映是一款专注于为动画垂直账号提供全面视频编辑和制作功能的软件&#xff0c;支持从灵感创作到成片输出的全流程。海量模板助您一键制作爆款动画视频和动漫视频&#xff0c;适配各种场景。此版本已解锁高级功能&#xff0c;提供更丰富的编辑工具和模板。 链接&#xff1a;ht…

MySQL数据库60道面试题 ( 附答案 )

2024的4月招聘季如此卷&#xff0c;没点真本事真技术&#xff0c;没点面试经验&#xff0c;不了解点职场套路&#xff0c;如何过五关斩六将&#xff1f; 找工作最重要的一步自然是面试&#xff0c;马上跳槽季&#xff0c;网上出现了各种面试题&#xff0c;一时会让人眼花缭乱&…

外排序之⽂件归并排序实现

外排序之⽂件归并排序实现 外排序介绍 外排序&#xff08;External sorting&#xff09;是指能够处理极⼤量数据的排序算法。通常来说&#xff0c;外排序处理的数据不能 ⼀次装⼊内存&#xff0c;只能放在读写较慢的外存储器(通常是硬盘)上。外排序通常采⽤的是⼀种“排序-归 …

Spring+SpringWeb+MyBatis三大框架整合教程 实现先前后端交互搭建

目录 1. 创建项目 2. 导入所依赖的 jar 包 3. 配置MyBatis 4. 配置spring事务管理 5. 配置Spring * Spring配置代码解读 6. dao层 7. mappers映射文件 8. common层 9. service层 10. web层 11. 测试 ssm大合体&#xff01; 1. 创建项目 &#x1f4cd;创建一个J…

【C++ Primer Plus习题】6.7

问题: 解答: #include <iostream> #include <cctype> using namespace std;int main() {string words;int vowel 0;int consonant 0;int other0;cout << "请输入一个单词(q结束):";cin >> words;while (words!"q"){if (!isalph…

编成笔记-atan2函数学习分析

分析atan2函数 1. 前言 2. atan2函数分析 tanθy/x : 当(x,y) 在第一象限&#xff0c;0 < θ < π/2当(x,y) 在第二象限&#xff0c;π/2 < θ ≤ π当(x,y) 在第三象限&#xff0c;− π < θ < − π/2当(x,y) 在第四象限&#xff0c;− π/2 < θ <…

动态读取nacos中修改的项目配置文件

本项目用的还是springboot项目&#xff0c;咱们直接上代码 一&#xff1a;首先看下nacos中需要动态获取的属性 二&#xff1a;把需要动态读取的配置类中的属性整理一个实体类 mport lombok.Data; import org.springframework.boot.context.properties.ConfigurationPropert…

微信公众号等工具 3 — 使用 Markdown Nice 写文章

文章目录 操作步骤STEP 1. 进入微信公众号文章编辑界面STEP 2. Markdown Nice 将 3 个重要的功能嵌入到了微信公众号编辑器中STEP 3. 在 Markdown Nice 界面编辑内容STEP 4. 导入/粘贴/直接在编辑器中编辑 Markdown → 点击左下角的预览效果 操作步骤 STEP 1. 进入微信公众号文…

BUUCTF二维码1

九张撕碎二维码碎片。不会让人拼起来吧&#xff01;看了大神们得博客竟然是真的&#xff0c;这是ctf的题吗&#xff01;是考验人的耐性吧&#xff01; 我勉为其难讲一下PS怎么拼图&#xff0c;首先要把九张碎片抠图&#xff0c;背景变透明&#xff0c;ps可以但是太麻烦&#xf…

(亲测有效)spring cloud+Vue微服务项目云服务器部署(宝塔)

我的另一篇博客&#xff0c;有兴趣可以看看&#xff0c;部署思路都是一样的。 &#xff08;亲测有效&#xff09;SpringBootVue项目云服务器部署&#xff08;宝塔&#xff09;_springboot 宝塔部署-CSDN博客 目录 一、准备工作 购买云服务器 登录云服务器 安装宝塔 二、jdk…

项目技巧二

java中Date和mysql数据库datetime数据类型 数据库中的 datetime 类型&#xff1a; 大多数关系型数据库&#xff08;如 MySQL, SQL Server, PostgreSQL 等&#xff09;都提供了 datetime 类型&#xff0c;用于存储日期和时间信息。这些数据库中的 datetime 类型通常遵循 ISO 86…

金九银十跳槽季,最新自动化测试面试题合集

前言 Hello,大家好。金九银十也不远了&#xff0c;有的人盼望升职加薪&#xff0c;有的人立了新的Flag&#xff0c;有跳槽计划的该提上日程了。为解大伙的燃眉之急&#xff0c;今天分享自动化面试题预热一波&#xff0c;欢迎留言区补充评论&#xff01; 一、请描述一下自动化测…

sqli-labs靶场通关攻略(四十一到五十关)

sqli-labs-master靶场第四十一关 一&#xff0c;查看数据库 ?id-1 union select 1,2,database()-- 二&#xff0c;查看表名 ?id-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemadatabase()-- 三&#xff0c;查看users表中…

python学习之路 - python对mysql的数据操作

目录 一、python对mysql的数据操作1、前期准备2、连接mysql3、创建表5、插入表4、查询表 一、python对mysql的数据操作 1、前期准备 使用python对mysql进行相关操作前&#xff0c;需要安装pymysql。执行pip install pymysql命令即可如果具体不知道如何操作&#xff0c;可以查…

导入pyBigWig包

今天复现论文时&#xff0c;看到了一种叫做bigwig格式的数据&#xff0c;创建和访问该格式文件需要用到pybigwig包&#xff0c;在此过程中遇到了一些问题&#xff0c;记录一下。 介绍 pybigwig的使用依赖于两个C库&#xff0c;所谓C库就是C语言编写的python库。 正如在pypi官…

聚类算法-DBSCAN

文章目录 一、DBSCAN介绍1.含义2.DBSCAN 的核心概念3.DBSCAN算法参数 二、代码实现1.数据预处理2.DBSCAN聚类3.计算轮廓系数4.全部代码 三、总结 一、DBSCAN介绍 1.含义 DBSCAN&#xff08;Density-Based Spatial Clustering of Applications with Noise&#xff09;是一种基…

llama-cpp-python编译失败,解决方案安装wheel文件

https://abetlen.github.io/llama-cpp-python/whl/cu121/llama-cpp-python/编译失败&#xff1a; 解决方案&#xff1a;使用轮子镜像