遥控器配置
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
开启接收中断