当前位置: 首页 > news >正文

STM32-PWM驱动舵机——HAL库

什么是舵机?

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

舵机型号介绍:

市面上常见的舵机型号有 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);
}

相关文章:

  • Kafka 到数据仓库:使用 bend-ingest-kafka 将消息加载到 Databend
  • vivado USED_IN
  • C#骑砍逻辑类Mod制作详细解说
  • C++系列-泛型编程之类模板
  • 51单片机——模块化编程
  • Unity编辑器扩展之Hierarchy面板扩展
  • 数美Android SDK
  • 【412】【统计近似相等数对 I】
  • docker python 3.11 容器报错
  • [M模拟] lc3153. 所有数对中数位不同之和(模拟+按位统计)
  • golang 多版本管理工具
  • IDEA没有SQL语句提示
  • 【Springboot服务实现类】用户登录逻辑梳理(未完待续)
  • 数据库与缓存一致性的解决方案
  • django(一):项目搭建
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • JavaScript新鲜事·第5期
  • js ES6 求数组的交集,并集,还有差集
  • Just for fun——迅速写完快速排序
  • underscore源码剖析之整体架构
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 程序员最讨厌的9句话,你可有补充?
  • 大快搜索数据爬虫技术实例安装教学篇
  • 关于使用markdown的方法(引自CSDN教程)
  • 基于web的全景—— Pannellum小试
  • 面试总结JavaScript篇
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 限制Java线程池运行线程以及等待线程数量的策略
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • ​Redis 实现计数器和限速器的
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • # include “ “ 和 # include < >两者的区别
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • (02)Unity使用在线AI大模型(调用Python)
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (2)Java 简介
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (Python第六天)文件处理
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (三)mysql_MYSQL(三)
  • (四)Controller接口控制器详解(三)
  • (原)Matlab的svmtrain和svmclassify
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)
  • (转)Linux下编译安装log4cxx
  • (转)mysql使用Navicat 导出和导入数据库
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .NET程序员迈向卓越的必由之路
  • /3GB和/USERVA开关
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • @media screen 针对不同移动设备
  • @SpringBootApplication 注解
  • [ C++ ] STL---string类的模拟实现
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器