CUBEMX配置
遥控器配置
cubemx配置
-
在 Connectivity 标签页下将 USART3 打开,将其 Mode 设置为 Asynchronous 异步通讯方式

-
将其波特率设置为 100000,数据帧设置为9位数据位(实测8位有错误),单校验位,1 位停止位
-
接着开启USART3 的 DMA 功能,在 USART3 下找到 DMA Settings 标签呀,在 USART3 中将 DMA Request 选 为 USART3_RX,数据从外设流向存储器,Priority 选为 low,Mode 选择Circular

keil配置
dbus.h
#ifndef __DBUS_H__
#define __DBUS_H__
#include "main.h"
#include "stdbool.h"
#define MISSING_TIMEOUT 100
#define KEY_V 16384
#define KEY_Q 64
#define KEY_W 1
#define KEY_A 4
#define KEY_S 2
#define KEY_D 8
#define KEY_E 128
#define KEY_R 256
#define KEY_B 32768
#define KEY_Z 2048
#define KEY_X 4096
#define KEY_SHIFT 16
/* ----------------------- RC Channel Definition---------------------------- */
#define RC_CH_VALUE_MIN ((int16_t)-660 )
#define RC_CH_VALUE_OFFSET ((int16_t)0)
#define RC_CH_VALUE_MAX ((int16_t)660)
/* ----------------------- RC Switch Definition----------------------------- */
#define RC_SW_UP ((uint16_t)1)
#define RC_SW_MID ((uint16_t)3)
#define RC_SW_DOWN ((uint16_t)2)
/* ----------------------- PC Key Definition-------------------------------- */
#define KEY_PRESSED_OFFSET_W ((uint16_t)0x01<<0)
#define KEY_PRESSED_OFFSET_S ((uint16_t)0x01<<1)
#define KEY_PRESSED_OFFSET_A ((uint16_t)0x01<<2)
#define KEY_PRESSED_OFFSET_D ((uint16_t)0x01<<3)
#define KEY_PRESSED_OFFSET_SHIFT ((uint16_t)0x01<<4)
#define KEY_PRESSED_OFFSET_CTRL ((uint16_t)0x01<<5)
#define KEY_PRESSED_OFFSET_Q ((uint16_t)0x01<<6)
#define KEY_PRESSED_OFFSET_E ((uint16_t)0x01<<7)
#define KEY_PRESSED_OFFSET_R ((uint16_t)0x01<<8)
#define KEY_PRESSED_OFFSET_F ((uint16_t)0x01<<9)
#define KEY_PRESSED_OFFSET_G ((uint16_t)0x01<<10)
#define KEY_PRESSED_OFFSET_Z ((uint16_t)0x01<<11)
#define KEY_PRESSED_OFFSET_X ((uint16_t)0x01<<12)
#define KEY_PRESSED_OFFSET_C ((uint16_t)0x01<<13)
#define KEY_PRESSED_OFFSET_V ((uint16_t)0x01<<14)
#define KEY_PRESSED_OFFSET_B ((uint16_t)0x01<<15)
typedef struct
{
struct
{
short ch0;
short ch1;
short ch2;
short ch3;
char s1;
char s2;
short wheel;
}rc;
struct
{
short x;
short y;
short z;
char press_l;
char press_r;
}mouse;
struct
{
uint16_t v;
}key;
uint32_t misstimeout;
struct
{
bool CTRL;
bool F;
bool X;
bool C;
bool Q;
bool E;
}flag;//标志位,用来切换模式,保证按键瞬间只进入函数一次
}RC_Ctl_t;
/* 获取遥控器摇杆偏移量
根据遥控器文档:
左摇杆: 右摇杆:
左右为ch2 左右为ch0
上下为ch3 上下为ch1
上 660
左 中 右
-660 0 660 中 0
下 -660 */
/* 获取遥控器摇杆偏移值
RLR:右摇杆左右移动 LUD:左摇杆上下移动 */
#define RC_CH0_RLR_OFFSET (RC_Ctl.rc.ch0 - RC_CH_VALUE_OFFSET)
#define RC_CH1_RUD_OFFSET (RC_Ctl.rc.ch1 - RC_CH_VALUE_OFFSET)
#define RC_CH2_LLR_OFFSET (RC_Ctl.rc.ch2 - RC_CH_VALUE_OFFSET)
#define RC_CH3_LUD_OFFSET (RC_Ctl.rc.ch3 - RC_CH_VALUE_OFFSET)
/* 检测遥控器开关状态 */
#define IF_RC_SW1_UP (RC_Ctl.rc.sw1 == RC_SW_UP)
#define IF_RC_SW1_MID (RC_Ctl.rc.sw1 == RC_SW_MID)
#define IF_RC_SW1_DOWN (RC_Ctl.rc.sw1 == RC_SW_DOWN)
#define IF_RC_SW2_UP (RC_Ctl.rc.sw2 == RC_SW_UP)
#define IF_RC_SW2_MID (RC_Ctl.rc.sw2 == RC_SW_MID)
#define IF_RC_SW2_DOWN (RC_Ctl.rc.sw2 == RC_SW_DOWN)
/* 获取鼠标三轴的移动速度 */
#define MOUSE_X_MOVE_SPEED (RC_Ctl.mouse.x)
#define MOUSE_Y_MOVE_SPEED (RC_Ctl.mouse.y)
#define MOUSE_Z_MOVE_SPEED (RC_Ctl.mouse.z)
/* 检测鼠标按键状态
按下为1,没按下为0*/
#define IF_MOUSE_PRESSED_LEFT (RC_Ctl.mouse.press_l == 1)
#define IF_MOUSE_PRESSED_RIGH (RC_Ctl.mouse.press_r == 1)
/* 检测键盘按键状态
若对应按键被按下,则逻辑表达式的值为1,否则为0 */
#define IF_KEY_PRESSED ( RC_Ctl.key.v )
#define IF_KEY_PRESSED_W ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_W) != 0 )
#define IF_KEY_PRESSED_S ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_S) != 0 )
#define IF_KEY_PRESSED_A ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_A) != 0 )
#define IF_KEY_PRESSED_D ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_D) != 0 )
#define IF_KEY_PRESSED_Q ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_Q) != 0 )
#define IF_KEY_PRESSED_E ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_E) != 0 )
#define IF_KEY_PRESSED_G ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_G) != 0 )
#define IF_KEY_PRESSED_X ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_X) != 0 )
#define IF_KEY_PRESSED_Z ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_Z) != 0 )
#define IF_KEY_PRESSED_C ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_C) != 0 )
#define IF_KEY_PRESSED_B ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_B) != 0 )
#define IF_KEY_PRESSED_V ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_V) != 0 )
#define IF_KEY_PRESSED_F ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_F) != 0 )
#define IF_KEY_PRESSED_R ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_R) != 0 )
#define IF_KEY_PRESSED_CTRL ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_CTRL) != 0 )
#define IF_KEY_PRESSED_SHIFT ( (RC_Ctl.key.v & KEY_PRESSED_OFFSET_SHIFT) != 0 )
#define IF_KEY_PRESSED_LAST ( RC_Ctl.key.v_last )
#define IF_KEY_PRESSED_W_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_W) != 0 )
#define IF_KEY_PRESSED_S_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_S) != 0 )
#define IF_KEY_PRESSED_A_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_A) != 0 )
#define IF_KEY_PRESSED_D_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_D) != 0 )
#define IF_KEY_PRESSED_Q_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_Q) != 0 )
#define IF_KEY_PRESSED_E_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_E) != 0 )
#define IF_KEY_PRESSED_G_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_G) != 0 )
#define IF_KEY_PRESSED_X_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_X) != 0 )
#define IF_KEY_PRESSED_Z_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_Z) != 0 )
#define IF_KEY_PRESSED_C_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_C) != 0 )
#define IF_KEY_PRESSED_B_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_B) != 0 )
#define IF_KEY_PRESSED_V_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_V) != 0 )
#define IF_KEY_PRESSED_F_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_F) != 0 )
#define IF_KEY_PRESSED_R_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_R) != 0 )
#define IF_KEY_PRESSED_CTRL_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_CTRL) != 0 )
#define IF_KEY_PRESSED_SHIFT_LAST ( (RC_Ctl.key.v_last & KEY_PRESSED_OFFSET_SHIFT) != 0 )
extern RC_Ctl_t RC_Ctl;
extern uint8_t dbus_connect;
void dbus_read(void);
void DBUS_Init(void);
#endif
dbus.c
#include "dbus.h"
#include "dma.h"
#include "usart.h"
// 声明接收DBUS数据的变量
uint16_t dbus_receive;
// 声明遥控器数据结构体
RC_Ctl_t RC_Ctl;
// 声明遥控器缓存数组
uint8_t sbus_rx_buffer[18];
//// 声明一个变量,用于表示DBUS连接状态
//uint8_t dbus_connect = 0;
/**
* @brief 初始化DBUS接收功能
* @details 使用DMA方式接收18字节的SBUS数据
*/
void DBUS_Init(void)
{
HAL_UART_Receive_DMA(&huart3, sbus_rx_buffer, 18);
}
// 定义DBUS使用的UART设备
#define DBUS_HUART huart3 /* for dji remote controler reciever */
// 定义DBUS最大接收长度
#define DBUS_MAX_LEN (50)
// 定义DBUS缓冲区长度
#define DBUS_BUFLEN (18)
/**
* @brief 解析接收到的DBUS数据
* @details 从sbus_rx_buffer中解析出各个通道和开关的状态
*/
void dbus_read(void)
{
RC_Ctl.rc.ch0 = (sbus_rx_buffer[0] | (sbus_rx_buffer[1] << 8)) & 0x07ff;
RC_Ctl.rc.ch0 -= 1024;
RC_Ctl.rc.ch1 = ((sbus_rx_buffer[1] >> 3) | (sbus_rx_buffer[2] << 5)) & 0x07ff;
RC_Ctl.rc.ch1 -= 1024;
RC_Ctl.rc.ch2 = ((sbus_rx_buffer[2] >> 6) | (sbus_rx_buffer[3] << 2) | (sbus_rx_buffer[4] << 10)) & 0x07ff;
RC_Ctl.rc.ch2 -= 1024;
RC_Ctl.rc.ch3 = ((sbus_rx_buffer[4] >> 1) | (sbus_rx_buffer[5] << 7)) & 0x07ff;
RC_Ctl.rc.ch3 -= 1024;
// 摇杆防抖处理
if (RC_Ctl.rc.ch0 <= 8 && RC_Ctl.rc.ch0 >= -8)
RC_Ctl.rc.ch0 = 0;
if (RC_Ctl.rc.ch1 <= 8 && RC_Ctl.rc.ch1 >= -8)
RC_Ctl.rc.ch1 = 0;
if (RC_Ctl.rc.ch2 <= 8 && RC_Ctl.rc.ch2 >= -8)
RC_Ctl.rc.ch2 = 0;
if (RC_Ctl.rc.ch3 <= 8 && RC_Ctl.rc.ch3 >= -8)
RC_Ctl.rc.ch3 = 0;
RC_Ctl.rc.s1 = ((sbus_rx_buffer[5] >> 4) & 0x000C) >> 2;
RC_Ctl.rc.s2 = ((sbus_rx_buffer[5] >> 4) & 0x0003);
RC_Ctl.rc.wheel = (sbus_rx_buffer[16] | sbus_rx_buffer[17] << 8) - 1024;
RC_Ctl.mouse.x = sbus_rx_buffer[6] | (sbus_rx_buffer[7] << 8); // 鼠标X轴
RC_Ctl.mouse.y = sbus_rx_buffer[8] | (sbus_rx_buffer[9] << 8); // 鼠标Y轴
RC_Ctl.mouse.z = sbus_rx_buffer[10] | (sbus_rx_buffer[11] << 8); // 鼠标Z轴
if (RC_Ctl.mouse.x <= 1 && RC_Ctl.mouse.x >= -1)
RC_Ctl.mouse.x = 0;
if (RC_Ctl.mouse.y <= 1 && RC_Ctl.mouse.y >= -1)
RC_Ctl.mouse.y = 0;
RC_Ctl.mouse.press_l = sbus_rx_buffer[12]; // 鼠标左键
RC_Ctl.mouse.press_r = sbus_rx_buffer[13]; // 鼠标右键
RC_Ctl.key.v = sbus_rx_buffer[14] | (sbus_rx_buffer[15] << 8); // 键盘值
RC_Ctl.misstimeout = 0; // 失联保护
}
void DMA1_Stream1_IRQHandler(void)
void DMA1_Stream1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
dbus_read();
/* USER CODE END DMA1_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart3_rx);
/* USER CODE BEGIN DMA1_Stream1_IRQn 1 */
/* USER CODE END DMA1_Stream1_IRQn 1 */
}
CAN
CUBEMX
使能can1
改GPIO


CAN的通信速率按照C620手册要求的1Mbps配置
71.42857142857143𝑛𝑠 ∗(10 +3+1) = 1000𝑛𝑠 = 1𝑢𝑠=1mbps

开启接收中断

添加arm_math.h库
选择Select Components

点击

返回,勾选,生成

keil添加宏定义
,ARM_MATH_CM4//H7是CM7,F4是CM4,F1是CM3


浙公网安备 33010602011771号