前言
本文章仅作为我学习的一次记录,本人的技术还不够成熟,可能无法对工程技术上做太多指导。
工程为基于HT32F52352的智能物联网宠物喂食机系统,通过HT32控制舵机工作,完成饲料的投喂。
一、舵机介绍
1、舵机的分类
按照舵机内部的控制电路不同,可以分为模拟舵机和数字舵机。
模拟舵机:模拟舵机内部为纯模拟电路,需要通过一直发送一定频率和占空比的PWM信号才能转动至规定的角度;
数字舵机:数字舵机内部集成有微控制器模块,在接收了一次PWM信号后即可转动至规定角度。
按照舵机内部的机械材质,可以分为塑料齿舵机和金属齿舵机。
塑料齿舵机:内部齿轮结构为塑料制成,重量轻,价格低,但舵机扭矩一般较小,例如SG90;
金属舵机:内部齿轮为金属制成,重量大,扭矩大,但价格也相对更高;
按照舵机的旋转角度范围,可以分为180°舵机和360°舵机。
180°舵机:可以控制旋转角度、有角度定位;上电后舵机自动复位到0°,通过一定参数的脉冲信号控制它的角度。
360°舵机:不可控制角度,只能顺/逆时针旋转、停止、调节转速。无角度定位,因为这是为360°任意旋转的,所以无0°,上电不会复位到0°;通过一定参数的脉冲信号控制它的旋转。
此外,舵机在不同的应用场景和使用途径上还有很多种分类,目前我还没有更多的使用需求,因此了解不多,感兴趣的朋友可以自行查阅。
2、舵机的工作原理
在很多教程中都讲过,想要控制舵机转动,就需要发送一定周期 (频率) 和脉冲宽度 (占空比) 的PWM波,周期一般为20ms(即频率为50Hz),脉冲宽度为0.5ms~2.5ms(即占空比为2.5%~12.5%),但我对为什么需要这两个参数的PWM波产生了疑问;
舵机内部存在一个基准电路,能够产生一个周期为20ms,脉冲宽度为1.5ms的基准信号;舵机内部还有一个比较器,能够将我们的输入信号和基准信号做对比,对比产生了信号差,信号差的正负决定了舵机的转动方向,信号差的大小决定了转动的角度大小; 这是我在别的博主的文章中找到的答案(34条消息) 单片机——SG90舵机工作原理_掏一淘哆啦A梦的奇妙口袋的博客-CSDN博客https://blog.csdn.net/qq_41873236/article/details/116353829?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167858272216800226577641%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167858272216800226577641&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~hot_rank-1-116353829-null-null.142%5Ev73%5Epc_search_v2,201%5Ev4%5Eadd_ask,239%5Ev2%5Einsert_chatgpt&utm_term=%E8%88%B5%E6%9C%BA%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86&spm=1018.2226.3001.4187
对于通过输出多少占空比的PWM脉冲信号,用下面这张图就能够很明了的解释了;0.5ms~2.5ms之间对应的都是连续的角度值,此处只是表现了特定角度的典型值。
二、代码编写
了解完舵机的工作原理之后,就可以选择好需要的舵机,进行代码的编写了。
1、舵机选择
本项目中,我对舵机的需求是重量轻,体积小,力矩不需要太大,因此我使用的是常用的Sg90。
2、硬件连接
舵机连接
红线---------VCC
棕线---------GND
橙线---------信号线
在本程序中,我使用的是通用定时器GPTM1,通道CH0,对应复用引脚为PC10,因此信号线与PC10相连。
3、代码编写
HT32与STM32的程序思路相类似,可以在一定程度上参考STM32的程序。
1、定时器初始化
pwm.h
#ifndef _STEERING_H #define _STEERING_H#include "ht32f5xxxx_usart.h" #include "ht32_board_config.h" #include "delay.h"void PWM_Init(void);#endif
pwm.c
/************************************************************************** * @brief 定时器初始化函数 * @param void * @retval None *************************************************************************/ void PWM_Init(void) {{ /* Enable peripheral clock */CKCU_PeripClockConfig_TypeDef CKCUClock = {{ 0 }};CKCUClock.Bit.PC = 1; //PC端口时钟开启CKCUClock.Bit.GPTM1 = 1; //通用定时器GPTM1时钟开启CKCUClock.Bit.AFIO = 1; //复用功能时钟开启CKCU_PeripClockConfig(CKCUClock, ENABLE);}{ /* Configure AFIO mode as TM function */AFIO_GPxConfig(GPIO_PC, AFIO_PIN_10, AFIO_MODE_4); //将GPTM1_CH0映射到PC10}{ /* Time base configuration */TM_TimeBaseInitTypeDef TimeBaseInit;TimeBaseInit.Prescaler = 4800 - 1; //Timer Clock = CK_AHB/HTCFG_PWM_TM_PRESCALERTimeBaseInit.CounterReload = 200 - 1;TimeBaseInit.RepetitionCounter = 0;TimeBaseInit.CounterMode = TM_CNT_MODE_UP; //设置为向上计数TimeBaseInit.PSCReloadTime = TM_PSC_RLD_IMMEDIATE; //立即重装载TM_TimeBaseInit(HT_GPTM1, &TimeBaseInit);TM_CRRPreloadCmd(HT_GPTM1, ENABLE); //使能CRR寄存器预装载值/* Clear Update Event Interrupt flag since the "TM_TimeBaseInit()" writes the UEV1G bit */TM_ClearFlag(HT_GPTM1, TM_FLAG_UEV);}{ /* Channel n output configuration */TM_OutputInitTypeDef OutInit;OutInit.Channel = TM_CH_0;OutInit.OutputMode = TM_OM_PWM1; //模式设置为PWM1,不同的模式可以查看数据手册OutInit.Control = TM_CHCTL_ENABLE; //GPTM通道使能OutInit.ControlN = TM_CHCTL_DISABLE; //与上一行功能相同,可以不写OutInit.Polarity = TM_CHP_INVERTED; //GPTM通道极性为高电平有效OutInit.PolarityN = TM_CHP_NONINVERTED; //与上一行功能相同,可以不写 OutInit.Compare = 195; //初始角度为0°/* Compare值的设置PWM基本原理可以简单理解为,计数器CNT的值与重装载CRR的值相比较,在向上计数模式下,CNT的值=CRR的值时,通道电平为有效电平,即为高电平,其余时间为低电平;若想要舵机转动,就要控制占空比,此处我的CRR值为200,0°对应占空比为2.5%,故compare的值为200-200*2.5% = 195;若想转动90°,则compare的值为200-200*7.5% = 185 */TM_OutputModeConfig(HT_GPTM1, TM_CH_0, TM_OM_PWM1);TM_OutputInit(HT_GPTM1,&OutInit);}//PWM ENABLETM_Cmd(HT_GPTM1, ENABLE); //最后一定要记得使能GPTM }
2、主函数调用
main.c
#include "ht32.h" #include "ht32_board.h" #include "delay.h" #include "time.h" #include "steering.h"int main() { // MY_USART_Init(); //USART1 Initial // USART0_Init(); //USART0 Initial // ESP8266_Start_Trans(); //ESP8266 InitialPWM_Init(); //PWM Initial while(1){TM_SetCaptureCompare(HT_GPTM1,TM_CH_0,195);//对应0度delay_ms(1000);TM_SetCaptureCompare(HT_GPTM1,TM_CH_0,185); //对应90度delay_ms(1000);} }
在主函数中通过函数不断改变PWM的占空比即可实现舵机的转动。
效果演示