STM32 HAL库 总线舵机驱动库的编写
文章目录
1 理论基础
1.1 硬件
版本一:幻尔串行总线舵机、亚博智能 ROS机器人控制器STM32主控


版本二:串行总线舵机、任意型号的STM32开发板、SN74AHC1G04DBV(单路反相器)、74HC126D(缓冲器)、MF-MSMF300自恢复保险丝等
1.2 电路图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0gy0zoRW-1684223384004)(C:\Users\77454\AppData\Roaming\Typora\typora-user-images\image-20230515093301452.png)]](https://i-blog.csdnimg.cn/blog_migrate/777539e4ce050f106d1df9d1ea792945.png)
1.3 原理
本次所用的舵机为串行总线舵机,采用异步串行总线通讯方式,理论多至 253 个机器人舵机可以通过总线组 成链型,一条总线上允许挂载多个舵机,且每个舵机均有一个唯一ID(0~253),通过 UART 异步串行接口统一控制。
每个舵机可以设定不同的节点地址,多个舵机可以统一运动也可以单个独立控制。通过异步串行接口与用户的上位机(控制器或PC机)通讯,可对其进行参数设置、功能控制。通过异步串行接口发送指令,可以设置为电机控制模式或位置控制模式。
在电机控制模式下,可以作为直流减速电机使用,速度可调;在位置控制模式下,拥有 0-240° 的转动范围,外加±30°的偏差可调范围,在此范围内具备精确位置控制性能,速度可调。只要符合协议的半双工UART异步串行接口都可以和舵机进行通讯,对舵机进行各种控制。
原理图如上图所示,舵机用程序代码对UART(本次示例中使用USART3)异步串口进行时序控制,实现半双工异步串行总线通讯,即半双工的主从问答式通信,通信波特率为115200bps。
原理可以理解为:舵机控制器作为主机发送读写指令给舵机,舵机作为从机根据具体情况执行相应动作或应答。
1.4 通信协议
(1)指令包格式
| 帧头 | ID号 | 数据长度 | 指令 | 参数 | 校验和 |
|---|---|---|---|---|---|
| 0x55 0x55 | ID | Length | Cmd | Prm 1…Prm N | Checksum |
- 帧头:连续收到两个 0x55 ,表示有数据包到达。
- ID: 每个舵机都有一个 ID 号。ID 号范围 0~253,转换为十六进制 0x00~0xFD。 广播 ID: ID 号254(0xFE) 为广播 ID,若控制器发出的ID号为 254(0xFE),所有的舵机均接收指令,但都不返回应答信息,(读取舵机 ID 号除外,具体说明参见下面指令介绍)以防总线冲突。
- 数据长度:等于待发送的数据(包含本身一个字节)长度,即数据长度Length加3等于这一包指令的长度,从帧头到校验和。
- 指令:控制舵机的各种指令,如位置、速度控制等。
- 参数:除指令外需要补充的控制信息。
- 校验和:校验和 Checksum,计算方法如下:Checksum = ~ (ID + Length + Cmd+ Prm1 + … Prm N)若括号内的计算和超出 255, 则取最低的一个字节,“~”表示取反。
(2)指令类型
指令有两种,写指令和读指令。
- 写指令:后面一般带有参数,将相应功能的参数写进舵机,来完成某种动作。
- 读指令:后面一般不带参数,舵机接收到读指令后会立即返回相应数据,返回的指令值和发送给舵机的“读指令”值相同,并且带有参数。所以上位机发送读指令后要立马准备将自己变为读取状态。
2 程序编写
2.1 cube mx设置
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zorh0bb7-1684223384005)(assets/image-20230516151529723.png)]](https://i-blog.csdnimg.cn/blog_migrate/9f95730139b85e9696c2087c497b478e.png)
(1)USART1设置
-
串口1模式配置为同步通讯,波特率改为115200bps,数据宽度8位,检验None,停止位1位

-
增加DMA发送通道

-
打开串口1中断设置

(2)USART3设置
-
串口3模式配置为同步通讯,波特率改为115200bps,数据宽度8位,检验None,停止位1位

-
由于默认串口3引脚是PB10和PB11,而扩展版原理图钟串口3连接的是PC10和PC11,所以串口需要重映射。
先点击PC11引脚,然后选择USART3_RX,这样操作后,串口3的引脚就会被重映射为PC10和PC11了。

-
打开串口3中断设置

2.2 程序编写
(1)bsp_key.c
#include "bsp_key.h"
#include "bsp.h"
// 判断按键是否被按下,按下返回KEY_PRESS,松开返回KEY_RELEASE
// Determine if the key is pressed, press to return KEY_PRESS, release to return KEY_RELEASE
static uint8_t Key1_is_Press(void)
{
if (!HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin))
{
return KEY_PRESS; // 如果按键被按下,则返回KEY_PRESS
}
return KEY_RELEASE; // 如果按键是松开状态,则返回KEY_RELEASE
}
// 读取按键K1的状态,按下返回KEY_PRESS,松开返回KEY_RELEASE.
// mode:设置模式,0:按下一直返回KEY_PRESS;1:按下只返回一次KEY_PRESS
// Read the state of key K1, press down to return KEY_PRESS, release to return key_release.
// mode: setting mode, 0: press down to return KEY_PRESS; 1: KEY_PRESS is returned only once
uint8_t Key1_State(uint8_t mode)
{
static uint16_t key1_state = 0;
if (Key1_is_Press() == KEY_PRESS)
{
if (key1_state < (mode + 1) * 2)
{
key1_state++;
}
}
else
{
key1_state = 0;
}
if (key1_state == 2)
{
return KEY_PRESS;
}
return KEY_RELEASE;
}
/*********************************************END OF FILE**********************/
(2)bsp_key.h
#ifndef __BSP_KEY_H__
#define __BSP_KEY_H__
#include "gpio.h"
#define KEY_PRESS 1
#define KEY_RELEASE 0
#define KEY_MODE_ONE_TIME 1
#define KEY_MODE_ALWAYS 0
uint8_t Key1_State(uint8_t mode);
#endif /* __BSP_KEY_H__ */
(3)bsp_uart.c
/*
* bsp_uart.c
*
* Created on: Mar 4, 2022
* Author: Administrator
*/
#include "bsp_uart.h"
#include "bsp.h"
#define ENABLE_UART_DMA 1
uint8_t RxTemp = 0;
uint8_t RxTemp_3 = 0;
uint8_t UART_RX_BUF[16];
bool isUartRxCompleted= false;
// Initialize USART1 初始化串口1
void USART1_Init(void)
{
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxTemp, 1);
}
// The serial port sends one byte 串口发送一个字节
void USART1_Send_U8(uint8_t ch)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
}
// The serial port sends a string of data 串口发送一串数据
void USART1_Send_ArrayU8(uint8_t *BufferPtr, uint16_t Length)
{
#if ENABLE_UART_DMA
HAL_UART_Transmit_DMA(&huart1, BufferPtr, Length);
#else
while (Length--)
{
USART1_Send_U8(*BufferPtr);
BufferPtr++;
}
#endif
}
// Initialize USART3 初始化串口3
void USART3_Init(void)
{
HAL_UART_Receive_IT(&huart3, (uint8_t *)&RxTemp, 1);
}
// The serial port sends one byte 串口发送一个字节
void USART3_Send_U8(uint8_t ch)
{
HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);
}
// The serial port sends a string of data 串口发送一串数据
void USART3_Send_ArrayU8(uint8_t *BufferPtr, uint16_t Length)
{
while (Length--)
本文介绍了如何使用STM32 HAL库编写串行总线舵机驱动程序,包括硬件配置、电路原理、通信协议以及Cube MX和程序详细步骤。通过对USART1和USART3的配置,实现半双工UART异步串行总线通讯,支持多个舵机的精确控制。
最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



