你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的PWM舵机控制经验分享

[复制链接]
攻城狮Melo 发布时间:2023-9-21 14:07
PWM舵机控制

硬件清单
  • 180°舵机
  • 270°舵机
  • 360°舵机
  • STM/GD32F103C8T6核心板
  • 杜邦线

硬件接线


(KJ87HQKEAR50GMANL~TDZV.png

一、标准/连续旋转舵机
PWM舵机的控制原理基于脉宽调制技术。
1、标准舵机(180°/270°)
  • 具有固定的角度范围
  • 精确控制角度位置

通过改变PWM信号来控制脉冲的高电平时间,从而来控制舵机旋转的角度2、连续旋转舵机(360°)

  • 控制旋转速度和方向
  • 实现无限制的连续旋转


通过改变PWM信号来控制脉冲的高电平时间,从而来控制舵机的速度和方向


二、舵机控制思路
控制信号以固定频率的方波形式发送给舵机;这个方波的周期通常为20ms,即50Hz的频率;
在控制信号中,脉冲的高电平时间决定舵机旋转的角度或旋转速度和方向。


@E`Y[AZ1G_FO2[ZDGV6E_A3.png

三、PWM实现思路
1、时钟使能
  1. //TIM3时钟使能
  2. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  3. //使能GPIOB端口时钟和AFIO时钟
  4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
复制代码

2、配置GPIO为复用功能及时钟使能
  1. // 配置GPIO为复用功能
  2. GPIO_InitTypeDef GPIO_InitStructure;
  3. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;  // 设置要配置的引脚
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  // 设置引脚模式为复用推挽模式
  5. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 设置引脚的速度
  6. GPIO_Init(GPIOB, &GPIO_InitStructure);  // 初始化GPIO配置

  7. // 禁用JTAG 启用SWD
  8. GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
  9. // 把TIM3_CH1功能部分映射到PB4引脚上
  10. GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
复制代码

由于使用的是PB4引脚,需要将TIM3_CH1功能部分映射到PB4引脚上

3、配置定时器3为PWM模式
  1. // 配置TIM3为PWM模式
  2. TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  3. TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // PWM周期,即计数周期20ms,PWM信号频率为50HZ
  4. TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; // 预分频系数,定时器时钟频率为72MHz/72=1MHz
  5. TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分频
  6. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数模式为向上计数
  7. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
复制代码

4、配置TIM3的通道1为PWM输出
  1. // 配置TIM3的通道1为PWM输出
  2. TIM_OCInitTypeDef  TIM_OCInitStructure;
  3. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1
  4. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 输出使能
  5. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性为高电平
  6. TIM_OCInitStructure.TIM_Pulse = 0; // 初始占空比
  7. TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  8. TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); // 开启OC1预加载寄存器
  9. TIM_ARRPreloadConfig(TIM3, ENABLE);// 使能自动重装载寄存器
  10. // 使能TIM3定时器
  11. TIM_Cmd(TIM3, ENABLE);
复制代码

四、主要函数
此处代码以180°舵机演示
1、main.c
  1. if(Data_Flag == 1)
  2. {
  3.    int Servo_Degree = strtol(Data_Buffer, NULL, 10);//将数组中的数据转换成整数
  4.    printf("%s\n",Data_Buffer);//打印数组中的字符串
  5.    printf("舵机目前角度 = %d°\n",Servo_Degree);//打印转化后的数据
  6.    Degree_Conv_PWM(Servo_Degree);//控制舵机旋转角度
  7.    Data_Flag = 0;//标志位重置
  8.    memset(Data_Buffer, 0, sizeof(Data_Buffer));//清除数组中的数据
  9. }
复制代码


使用轮询的方式判断是否接收到正确的数据,根据串口数据控制舵机运转

2、PWM.c
  1. void Degree_Conv_PWM(int Servo_Degree)// 将接收的数据转换成PWM高电平脉宽
  2. {
  3.     float PWM_Time;
  4.     PWM_Time = (2000.0 * (Servo_Degree / 180.0)) + 500;
  5.     TIM_SetCompare1(TIM3, (int)PWM_Time);//定时器设置比较值函数和通道有关 时间参数单位是us
  6. }
复制代码


使用强制类型转换是为了保证精度,最后传递给定时器一个整数比较值

3、Usart.c
  1. int fputc(int ch, FILE *f)// printf()函数重定向
  2. {
  3.     // 发送一个字符到USART1
  4.     USART_SendData(USART1, (uint16_t)ch);
  5.     // 等待发送完成
  6.     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  7.     return ch;
  8. }

  9. void USART1_IRQHandler(void)//串口中断函数
  10. {
  11.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  12.     {
  13.         Rx_Buffer[Rx_Index] = USART_ReceiveData(USART1);// 从串口接收数据到缓冲区
  14.     if(Rx_Buffer[Rx_Index] == '[/align][b][b][font=Tahoma][size=3][color=#000000][b][b][font=Tahoma][size=3][color=#000000]
  15. [/color][/size][/font][/b][/b]
  16. Usart1:串口中断接收以“$”开头,“#”结尾的数据[/color][/size][/font][/b][/b]
  17. [align=left][b][b][b][b][font=Tahoma][size=3][color=#ff8c00]4、SysTick.c[/color][/size][/font][/b][/b][/b][/b][/align][align=left][code]void Delay_us(uint16_t us)
  18. {
  19.     SysTick->CTRL =  0;// SysTick控制寄存器清零,停止SysTick定时器
  20.     SysTick->LOAD =  72*us - 1;// 设置SysTick加载寄存器的值,确定延时的时间
  21.     SysTick->VAL =  0;// 将SysTick当前值寄存器清零
  22.     SysTick->CTRL =  5;// 设置SysTick控制寄存器,使其开始倒数计数,并启用SysTick定时器
  23.     while((SysTick->CTRL & 0x00010000) == 0);// 等待SysTick定时器倒数完成
  24.     SysTick->CTRL =  0;// 再次将SysTick控制寄存器清零,停止SysTick定时器
  25. }
复制代码
使用系统滴答定时器来控制延时
五、实践
通过串口发送指令控制舵机(180°舵机演示)
1、UartAssist
微信图片_20230921140518.png
注意:串口、波特率、以及数据格式等
2、现象
180°/270°舵机可以通过串口发送的指令控制舵机旋转的角度;
360°舵机可以通过串口发送的指令控制舵机旋转的方向和速度。

转载自: W-ML
如有侵权请联系删除



)// 如果数据是以$开头则开始存储数据
    {
        memset(Rx_Buffer, 0, sizeof(Rx_Buffer));// 清空接收缓冲区
        Rx_Buffer[0] = '

Usart1:串口中断接收以“$”开头,“#”结尾的数据

4、SysTick.c
  1. void Delay_us(uint16_t us)
  2. {
  3.     SysTick->CTRL =  0;// SysTick控制寄存器清零,停止SysTick定时器
  4.     SysTick->LOAD =  72*us - 1;// 设置SysTick加载寄存器的值,确定延时的时间
  5.     SysTick->VAL =  0;// 将SysTick当前值寄存器清零
  6.     SysTick->CTRL =  5;// 设置SysTick控制寄存器,使其开始倒数计数,并启用SysTick定时器
  7.     while((SysTick->CTRL & 0x00010000) == 0);// 等待SysTick定时器倒数完成
  8.     SysTick->CTRL =  0;// 再次将SysTick控制寄存器清零,停止SysTick定时器
  9. }
复制代码
使用系统滴答定时器来控制延时
五、实践
通过串口发送指令控制舵机(180°舵机演示)
1、UartAssist
注意:串口、波特率、以及数据格式等
2、现象
180°/270°舵机可以通过串口发送的指令控制舵机旋转的角度;
360°舵机可以通过串口发送的指令控制舵机旋转的方向和速度。

转载自: W-ML
如有侵权请联系删除



;
        Rx_Index = 1;
    }
    else if(Rx_Buffer[Rx_Index] == '#' && Rx_Buffer[0] == '

Usart1:串口中断接收以“$”开头,“#”结尾的数据

4、SysTick.c
[        DISCUZ_CODE_7        ]
使用系统滴答定时器来控制延时
五、实践
通过串口发送指令控制舵机(180°舵机演示)
1、UartAssist
注意:串口、波特率、以及数据格式等
2、现象
180°/270°舵机可以通过串口发送的指令控制舵机旋转的角度;
360°舵机可以通过串口发送的指令控制舵机旋转的方向和速度。

转载自: W-ML
如有侵权请联系删除



)// 如果数据是以#结尾则结束数据存储并打印数据信息
    {
          printf("Received: %sundefined", Rx_Buffer);// 打印接收到的数据
          memcpy(Data_Buffer, Rx_Buffer + 1, 3);// 使用memcpy函数进行数组内容复制
          memset(Rx_Buffer, 0, sizeof(Rx_Buffer));// 清空接收缓冲区
          Rx_Index = 0;// 重置索引
          Data_Flag = 1;// 数据标志位
    }
    else
    {
          Rx_Index++;// 增加索引,准备接收下一个字符
    }
    }
}[/code]

Usart1:串口中断接收以“$”开头,“#”结尾的数据

4、SysTick.c
[        DISCUZ_CODE_7        ]
使用系统滴答定时器来控制延时
五、实践
通过串口发送指令控制舵机(180°舵机演示)
1、UartAssist
注意:串口、波特率、以及数据格式等
2、现象
180°/270°舵机可以通过串口发送的指令控制舵机旋转的角度;
360°舵机可以通过串口发送的指令控制舵机旋转的方向和速度。

转载自: W-ML
如有侵权请联系删除




收藏 评论0 发布时间:2023-9-21 14:07

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版