CUBEMX配置

遥控器配置

cubemx配置

  1. 在 Connectivity 标签页下将 USART3 打开,将其 Mode 设置为 Asynchronous 异步通讯方式
    image

  2. 将其波特率设置为 100000,数据帧设置为9位数据位(实测8位有错误),单校验位,1 位停止位

  3. 接着开启USART3 的 DMA 功能,在 USART3 下找到 DMA Settings 标签呀,在 USART3 中将 DMA Request 选 为 USART3_RX,数据从外设流向存储器,Priority 选为 low,Mode 选择Circular
    image

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;  // 失联保护
}
stm32f4xx_it.c中的
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 */
}
main.c添加DBUS_Init();

CAN

CUBEMX

使能can1
改GPIO
image
image

CAN的通信速率按照C620手册要求的1Mbps配置

71.42857142857143𝑛𝑠 ∗(10 +3+1) = 1000𝑛𝑠 = 1𝑢𝑠=1mbps
image

开启接收中断

image

添加arm_math.h库

选择Select Components
image
点击
image
返回,勾选,生成
image
keil添加宏定义
,ARM_MATH_CM4//H7是CM7,F4是CM4,F1是CM3
image

posted @ 2024-11-18 21:13  挽天  阅读(220)  评论(0)    收藏  举报