太虚四形二十一式,
启,化,守,开。
残月,断海,裂空。
飞鹘,玄隼,雨燕,藤雀,云鹰,月鹭。
垂柳,幽兰,劲竹,墨菊,净莲,青松。
岩破,乱雷,霹雳,山崩,瞬尘,震风。
新人写帖子,仅供内部人员参照,
使用DJI遥控协议,DBUS,初始配置如前文在下A板杀手,请赐教,uart配置可以看这篇文章,相关协议的介绍也在里头http://t.csdn.cn/rVp9A大疆A型板使用经验分享(五)—— DMA配置和遥控器使用
下面进入正题,由本人改编的代码奉上
LSS_UART.c
/**
***************************************(C) COPYRIGHT 2020 DJI***************************************
* @file LLS_USART.c
* @brief this file contains rc data receive and processing function
* @note
* @Version V1.0.0
* @Date June-30-2022
***************************************(C) COPYRIGHT 2020 DJI***************************************
*/
#include "LSS_USART.h"
/*
*****移植了DJI的中断逻辑处理函数
*****使用串口空闲中断来接收数据比较合理
*/
#define abs(x) ((x)>0? (x):(-(x)))
uint8_t dbus_buf[DBUS_BUFLEN];
rc_info_t rc;
/**
* @brief enable global uart it and do not use DMA transfer done it
* @param[in] huart: uart IRQHandler id
* @param[in] pData: receive buff
* @param[in] Size: buff size
* @retval set success or fail
*/
static int uart_receive_dma_no_it(UART_HandleTypeDef* huart, uint8_t* pData, uint32_t Size)
{
uint32_t tmp1 = 0;
tmp1 = huart->RxState;
if (tmp1 == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Enable the DMA Stream */
HAL_DMA_Start(huart->hdmarx, (uint32_t)&huart->Instance->DR, (uint32_t)pData, Size);
/*
* Enable the DMA transfer for the receiver request by setting the DMAR bit
* in the UART CR3 register
*/
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
/**
* @brief returns the number of remaining data units in the current DMAy Streamx transfer.
* @param[in] dma_stream: where y can be 1 or 2 to select the DMA and x can be 0
* to 7 to select the DMA Stream.
* @retval The number of remaining data units in the current DMAy Streamx transfer.
*/
uint16_t dma_current_data_counter(DMA_Stream_TypeDef *dma_stream)
{
/* Return the number of remaining data units for DMAy Streamx */
return ((uint16_t)(dma_stream->NDTR));
}
/************************************空闲中断回调函数功能函数区************************************/
void rc_callback_handler(rc_info_t *rc, uint8_t *buff)
{
rc->ch1 = (buff[0] | buff[1] << 8) & 0x07FF;
rc->ch1 -= 1024;
rc->ch2 = (buff[1] >> 3 | buff[2] << 5) & 0x07FF;
rc->ch2 -= 1024;
rc->ch3 = (buff[2] >> 6 | buff[3] << 2 | buff[4] << 10) & 0x07FF;
rc->ch3 -= 1024;
rc->ch4 = (buff[4] >> 1 | buff[5] << 7) & 0x07FF;
rc->ch4 -= 1024;
rc->sw1 = ((buff[5] >> 4) & 0x000C) >> 2;
rc->sw2 = (buff[5] >> 4) & 0x0003;
if ((abs(rc->ch1) > 660) || \
(abs(rc->ch2) > 660) || \
(abs(rc->ch3) > 660) || \
(abs(rc->ch4) > 660))
{
memset(rc, 0, sizeof(rc_info_t));
}
}
/************************************END************************************/
/**
* @brief clear idle it flag after uart receive a frame data
* @param[in] huart: uart IRQHandler id
* @retval
*/
static void uart_rx_idle_callback(UART_HandleTypeDef* huart)
{
/* clear idle it flag avoid idle interrupt all the time */
__HAL_UART_CLEAR_IDLEFLAG(huart);
if (huart == &DBUS_HUART)
{
__HAL_DMA_DISABLE(huart->hdmarx);
if ((DBUS_MAX_LEN - dma_current_data_counter(huart->hdmarx->Instance)) == DBUS_BUFLEN)
{
rc_callback_handler(&rc, dbus_buf);
}
__HAL_DMA_SET_COUNTER(huart->hdmarx, DBUS_MAX_LEN);
__HAL_DMA_ENABLE(huart->hdmarx);
}
}
/**
* @brief callback this function when uart interrupt
* @param[in] huart: uart IRQHandler id
* @retval
*/
void uart_receive_handler(UART_HandleTypeDef *huart)
{
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) &&
__HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE))
{
uart_rx_idle_callback(huart);
}
}
/**
**空闲中断初始化函数,main里面调用,选择串口即可初始化
**/
void uart_receive_init(UART_HandleTypeDef *huart)
{
if(huart == &DBUS_HUART)
{
__HAL_UART_CLEAR_IDLEFLAG(&DBUS_HUART);
__HAL_UART_ENABLE_IT(&DBUS_HUART, UART_IT_IDLE);
uart_receive_dma_no_it(&DBUS_HUART, dbus_buf, DBUS_MAX_LEN);
}
}
//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//中断回调函数
//{
// HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin,GPIO_PIN_SET);
//
// UNUSED(huart);
// if(huart->Instance == USART1)//判断串口号
// {
// LIDAR_USART(rx_buffer);
// HAL_UART_Transmit(&huart1,(uint8_t *)&rx_buffer,1,100); // 将接收到的数据再通过串口发送出去
// HAL_UART_Receive_IT(&huart1, (uint8_t *)&rx_buffer, 1); //重新使能接收中断
// }
//}
LSS_UART.h
#ifndef __LSS_USART__H
#define __LSS_USART__H
#include "stm32f4xx_hal.h"
#include "LSS_USART.h"
#include "usart.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "stdint.h"
#include "math.h"
#define BYTE0(dwTemp) ( *( (char *)(&dwTemp) ) )
#define BYTE1(dwTemp) ( *( (char *)(&dwTemp) + 1) )
#define BYTE2(dwTemp) ( *( (char *)(&dwTemp) + 2) )
#define BYTE3(dwTemp) ( *( (char *)(&dwTemp) + 3) )
#define posit_clear "ACT0" //数据清零 重新开始计算
#define UART_RX_DMA_SIZE (1024)
#define DBUS_MAX_LEN (50)
#define DBUS_BUFLEN (18)
#define DBUS_HUART huart1
#define USART4_MAX_LEN (50)
#define USART4_BUFLEN (27)
#define LeDar_HUART huart4
typedef struct lidar//激光雷达
{
float pos_x;
float pos_y;
float zangle;
float xangle;
float yangle;
float w_z;
}lidar;//全场地位结构体
typedef __packed struct
{
int16_t ch1;
int16_t ch2;
int16_t ch3;
int16_t ch4;
uint8_t sw1;
uint8_t sw2;
uint8_t last_sw;
} rc_info_t;
extern uint8_t usart4_buf[USART4_BUFLEN];
extern rc_info_t rc;
void LIDAR_USART(uint8_t ch);
void usart_printf(const char *fmt,...);
void uart_receive_handler(UART_HandleTypeDef *huart);
void imu_uart_init(void);
void openmv_uart_init(void);
void uart_receive_init(UART_HandleTypeDef *huart);
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
void Send_dat_HMI(uint8_t *date);
#endif
main.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "LSS_USART.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
/* USER CODE BEGIN 2 */
uart_receive_init(&huart1);//接收初始化
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 6;
RCC_OscInitStruct.PLL.PLLN = 180;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
编写完后在debug里调试
查看rc
使用大疆的DR16接收机和RoboMaster 遥控器,会有数值的变化,之后可以在里面编写一些程序。
以上便是DBUS快速代码入门。下一篇更新山外上位机的使用