chore: 导入 Simba-OmniInfantry 基线(云台/底盘双工程)
- 云台(ROBOT_TYPE_GIMBAL)与底盘(ROBOT_TYPE_CHASSIS)完整固件源码 - 新增根级 .gitignore,排除 Keil MDK-ARM 构建产物(.o/.d/.crf/.axf/.lnp/.map/.htm/.sct/.dep/.iex/.lst 等) 与 *.uvguix.* / DebugConfig/(与机器绑定的 UI 布局) - core.autocrlf=false,避免固件源码在检出时被改动换行符
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
#ifndef BSP_CAN_H
|
||||
#define BSP_CAN_H
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
// clang-format off
|
||||
#define BOARD_DATA_ANY ((uint16_t)0x500)
|
||||
#define BOARD_DATA_UINT16 ((uint16_t)0x600)
|
||||
// clang-format on
|
||||
|
||||
typedef CAN_HandleTypeDef hcan_t;
|
||||
|
||||
typedef struct __CanCtrlData
|
||||
{
|
||||
hcan_t * hcan;
|
||||
CAN_TxHeaderTypeDef tx_header;
|
||||
uint8_t tx_data[8];
|
||||
} CanCtrlData_s;
|
||||
|
||||
/* CAN 接收回调:在 CAN RX0 中断上下文中执行,必须尽量短 */
|
||||
typedef void (*can_rx_callback_f)(uint32_t std_id, const uint8_t rx_data[8], uint32_t dlc);
|
||||
|
||||
extern hcan_t hcan1;
|
||||
extern hcan_t hcan2;
|
||||
|
||||
/* 初始化过滤器并启动两路 CAN,同时使能 CAN1_RX0/CAN2_RX0 NVIC(ioc 未开 CAN2 中断,由代码补齐)
|
||||
* 必须在 osKernelStart 之后的任务上下文中调用一次 */
|
||||
extern void can_start(void);
|
||||
|
||||
/* 注册按 (hcan, 标准ID) 分发的接收回调,返回 0-成功,-1-表满 */
|
||||
extern int can_rx_register(hcan_t * hcan, uint32_t std_id, can_rx_callback_f callback);
|
||||
|
||||
extern void CAN_SendTxMessage(CanCtrlData_s * can_ctrl_data);
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef BSP_UART_H
|
||||
#define BSP_UART_H
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "usart.h"
|
||||
|
||||
typedef UART_HandleTypeDef huart_t;
|
||||
#define UART1 huart6 //(3pin)与板上的标识相对应
|
||||
#define UART2 huart1 //(4pin)与板上的标识相对应
|
||||
|
||||
typedef enum __UartSendState {
|
||||
UART_SEND_FAIL = 0,
|
||||
UART_SEND_OK,
|
||||
} UartSendState_e;
|
||||
|
||||
extern UartSendState_e UartSendTxMessage(
|
||||
UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout);
|
||||
|
||||
#endif // BSP_UART_H
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef BSP_USART_H
|
||||
#define BSP_USART_H
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
/* 串口接收按"整帧"递交给注册回调(CAN 的按 ID 分发见 bsp_can.h) */
|
||||
typedef void (*usart_rx_callback_f)(const uint8_t * frame, uint16_t len);
|
||||
|
||||
/* ---- 接收 ----
|
||||
* 初始化在任务上下文调用一次;回调在中断上下文递交整帧,须尽量短 */
|
||||
extern void usart1_init(uint8_t * rx_buf, uint16_t dma_buf_num, usart_rx_callback_f callback);
|
||||
extern void usart3_init(uint8_t * rx_buf, uint16_t dma_buf_num, usart_rx_callback_f callback);
|
||||
extern void usart6_init(uint8_t * rx_buf, uint16_t dma_buf_num, usart_rx_callback_f callback);
|
||||
|
||||
extern int usart_rx_register(UART_HandleTypeDef * huart, usart_rx_callback_f callback);
|
||||
|
||||
/* 各 USARTx_IRQHandler 的 USER CODE 区调用(需在 HAL_UART_IRQHandler 之前) */
|
||||
extern void usart1_idle_isr(void);
|
||||
extern void usart3_idle_isr(void);
|
||||
extern void usart6_idle_isr(void);
|
||||
|
||||
/* ---- 发送 ----
|
||||
* TX DMA 启动后 data 缓冲须保持有效直至传输完成 */
|
||||
extern void usart1_tx_dma_init(void);
|
||||
extern void usart1_tx_dma_enable(uint8_t * data, uint16_t len);
|
||||
extern void usart6_tx_dma_enable(uint8_t * data, uint16_t len);
|
||||
|
||||
/* ---- 诊断(debug_task 打印) ---- */
|
||||
extern volatile uint32_t dbg_usart1_idle;
|
||||
extern volatile uint32_t dbg_usart3_idle;
|
||||
extern volatile uint32_t dbg_usart6_idle;
|
||||
extern volatile uint16_t dbg_usart3_last_len;
|
||||
extern volatile uint16_t dbg_usart6_last_len;
|
||||
#endif
|
||||
@@ -0,0 +1,129 @@
|
||||
/* =============================================================================
|
||||
* bsp_can.c - CAN 总线板级支持包(收发中枢)
|
||||
* 职责:
|
||||
* 1. can_start() 启动两路 CAN(过滤器全开掩码 0,接收所有 ID),
|
||||
* 并使能 CAN1_RX0/CAN2_RX0 NVIC(CAN2 中断 ioc 未开,
|
||||
* 在此代码补齐,优先级 5 = FreeRTOS 管理下限)
|
||||
* 2. can_rx_register() 按 (hcan, 标准ID) 注册接收回调,查表容量 32
|
||||
* 3. HAL_CAN_RxFifo0MsgPendingCallback
|
||||
* RX0 中断里取帧并按 ID 分发到注册回调
|
||||
* (中断上下文,回调必须尽量短)
|
||||
* 4. CAN_SendTxMessage() 发送帧(等待 3 个发送邮箱空闲,最多重试 20 次)
|
||||
* 数据流: 电机反馈/板间通讯/裁判数据 --ISR--> 回调表 --> 各模块解析
|
||||
* 依赖: CubeMX 生成的 hcan1/hcan2(Core/Src/can.c)
|
||||
* 对比 legacy: 替代了"单滤波器轮询切换 ID"的脆弱接收机制
|
||||
* ========================================================================== */
|
||||
#include "bsp_can.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#define CAN_RX_CALLBACK_MAX 32
|
||||
|
||||
typedef struct
|
||||
{
|
||||
hcan_t * hcan;
|
||||
uint32_t std_id;
|
||||
can_rx_callback_f callback;
|
||||
} can_rx_callback_item_t;
|
||||
|
||||
static can_rx_callback_item_t can_rx_callback_table[CAN_RX_CALLBACK_MAX];
|
||||
static uint8_t can_started = 0;
|
||||
|
||||
/* 初始化过滤器并启动两路 CAN
|
||||
* 过滤器掩码全 0,接收所有 ID,由 can_rx_register 注册的回调按 ID 分发 */
|
||||
void can_filter_init(void)
|
||||
{
|
||||
CAN_FilterTypeDef can_filter_st;
|
||||
can_filter_st.FilterActivation = ENABLE;
|
||||
can_filter_st.FilterMode = CAN_FILTERMODE_IDMASK;
|
||||
can_filter_st.FilterScale = CAN_FILTERSCALE_32BIT;
|
||||
can_filter_st.FilterIdHigh = 0x0000;
|
||||
can_filter_st.FilterIdLow = 0x0000;
|
||||
can_filter_st.FilterMaskIdHigh = 0x0000;
|
||||
can_filter_st.FilterMaskIdLow = 0x0000;
|
||||
can_filter_st.FilterBank = 0;
|
||||
can_filter_st.FilterFIFOAssignment = CAN_RX_FIFO0;
|
||||
HAL_CAN_ConfigFilter(&hcan1, &can_filter_st);
|
||||
HAL_CAN_Start(&hcan1);
|
||||
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||||
|
||||
can_filter_st.SlaveStartFilterBank = 14;
|
||||
can_filter_st.FilterBank = 14;
|
||||
HAL_CAN_ConfigFilter(&hcan2, &can_filter_st);
|
||||
HAL_CAN_Start(&hcan2);
|
||||
HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING);
|
||||
}
|
||||
|
||||
/* 应用层统一入口:启动 CAN(含 CAN2 接收中断使能,ioc 未开启,此处代码补齐)
|
||||
* FreeRTOS 管理的中断优先级不得高于 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY(5) */
|
||||
void can_start(void)
|
||||
{
|
||||
if (can_started)
|
||||
return;
|
||||
can_started = 1;
|
||||
|
||||
can_filter_init();
|
||||
|
||||
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
|
||||
|
||||
/* CAN2 的 RX0 中断未在 CubeMX 中开启,在此手动补齐 */
|
||||
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
|
||||
}
|
||||
|
||||
int can_rx_register(hcan_t * hcan, uint32_t std_id, can_rx_callback_f callback)
|
||||
{
|
||||
for (uint32_t i = 0; i < CAN_RX_CALLBACK_MAX; i++)
|
||||
{
|
||||
if (can_rx_callback_table[i].callback == NULL)
|
||||
{
|
||||
can_rx_callback_table[i].hcan = hcan;
|
||||
can_rx_callback_table[i].std_id = std_id;
|
||||
can_rx_callback_table[i].callback = callback;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* HAL CAN 接收回调:在 RX0 中断上下文中按 (hcan, StdId) 查表分发 */
|
||||
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef * hcan)
|
||||
{
|
||||
CAN_RxHeaderTypeDef rx_header;
|
||||
uint8_t rx_data[8];
|
||||
|
||||
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rx_header, rx_data) != HAL_OK)
|
||||
return;
|
||||
if (rx_header.IDE != CAN_ID_STD)
|
||||
return;
|
||||
|
||||
for (uint32_t i = 0; i < CAN_RX_CALLBACK_MAX; i++)
|
||||
{
|
||||
if (can_rx_callback_table[i].callback != NULL && can_rx_callback_table[i].hcan == hcan &&
|
||||
can_rx_callback_table[i].std_id == rx_header.StdId)
|
||||
{
|
||||
can_rx_callback_table[i].callback(rx_header.StdId, rx_data, rx_header.DLC);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 发送控制数据
|
||||
* @param[in] can_ctrl_data 打包好的发送结构体
|
||||
* @return none
|
||||
*/
|
||||
void CAN_SendTxMessage(CanCtrlData_s * can_ctrl_data)
|
||||
{
|
||||
uint32_t send_mail_box;
|
||||
uint8_t cnt = 20; // 重复检测次数
|
||||
|
||||
uint32_t free_TxMailbox =
|
||||
HAL_CAN_GetTxMailboxesFreeLevel(can_ctrl_data->hcan); // 检测是否有空闲邮箱
|
||||
while (free_TxMailbox < 3 && cnt--) { // 等待空闲邮箱数达到3
|
||||
free_TxMailbox = HAL_CAN_GetTxMailboxesFreeLevel(can_ctrl_data->hcan);
|
||||
}
|
||||
HAL_CAN_AddTxMessage(
|
||||
can_ctrl_data->hcan, &can_ctrl_data->tx_header, can_ctrl_data->tx_data, &send_mail_box);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @brief uart板级支持包
|
||||
* @author Penguin
|
||||
*/
|
||||
#include "bsp_uart.h"
|
||||
|
||||
/**
|
||||
* @brief 使用uart发送数据
|
||||
* @param huart
|
||||
* @param pData
|
||||
* @param Size
|
||||
* @param Timeout
|
||||
* @return
|
||||
*/
|
||||
UartSendState_e UartSendTxMessage(
|
||||
UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint8_t cnt = 5; //最大重发次数
|
||||
HAL_StatusTypeDef status = HAL_UART_Transmit(huart, pData, Size, Timeout);
|
||||
while (cnt-- && status != HAL_OK) {
|
||||
status = HAL_UART_Transmit(huart, pData, Size, Timeout);
|
||||
}
|
||||
|
||||
if (status == HAL_OK) {
|
||||
return UART_SEND_OK;
|
||||
}
|
||||
return UART_SEND_FAIL;
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/* =============================================================================
|
||||
* bsp_usart.c - 串口 DMA 接收板级支持包(USART1/3/6)
|
||||
* 职责:
|
||||
* 1. usartX_init() 任务上下文调用:配置 RX 循环 DMA + 空闲中断,
|
||||
* 注册"整帧"回调(帧 = 两次空闲之间的字节)
|
||||
* 2. usartX_idle_isr() 由 stm32f4xx_it.c 的 USER CODE 区调用(需在
|
||||
* HAL_UART_IRQHandler 之前):读 NDTR 算帧长,
|
||||
* 清 F4 DMA 流事件标志后重启 DMA,递交回调
|
||||
* 3. usartX_tx_dma_*() TX DMA 发送(缓冲须保持有效直到发送完成)
|
||||
* 数据流: DR16(USART3)/裁判(USART6)/视觉(USART1) --IDLE ISR--> 回调
|
||||
* 关键细节:
|
||||
* - 采用单缓冲循环 DMA + IDLE 重启(DJI 官方风格),不使用双缓冲
|
||||
* - F4 手册要求重启 DMA 流前必须清除该流全部事件标志,否则只收到第一帧
|
||||
* - usart3_init 会把字长改为 9B(CubeMX 生成的 8B+偶校验只有 7 个数据位,
|
||||
* DR16 帧需要 8 数据位+偶校验)
|
||||
* ========================================================================== */
|
||||
#include "bsp_usart.h"
|
||||
#include "main.h"
|
||||
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||||
extern DMA_HandleTypeDef hdma_usart1_rx;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
extern DMA_HandleTypeDef hdma_usart3_rx;
|
||||
extern UART_HandleTypeDef huart6;
|
||||
extern DMA_HandleTypeDef hdma_usart6_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart6_tx;
|
||||
|
||||
/* ==========================================================================
|
||||
* 单缓冲循环 DMA + 空闲中断重启接收(DJI 官方风格)
|
||||
* 每路串口接收配置:RX 走循环 DMA,空闲中断里读 NDTR 计算本帧长度,
|
||||
* 复位 NDTR 后继续接收,并通过注册的回调把整帧递交给使用者。
|
||||
* 回调在中断上下文执行,应尽量短(可拷贝数据/通知任务)。
|
||||
* ========================================================================== */
|
||||
|
||||
#define USART_RX_SLOT_MAX 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UART_HandleTypeDef * huart;
|
||||
uint8_t * rx_buf;
|
||||
uint16_t buf_num;
|
||||
usart_rx_callback_f callback;
|
||||
} usart_rx_slot_t;
|
||||
|
||||
static usart_rx_slot_t usart_rx_slots[USART_RX_SLOT_MAX];
|
||||
|
||||
/* 诊断计数(空串口事件次数/最近帧长),debug_task 打印 */
|
||||
volatile uint32_t dbg_usart1_idle = 0;
|
||||
volatile uint32_t dbg_usart3_idle = 0;
|
||||
volatile uint32_t dbg_usart6_idle = 0;
|
||||
volatile uint16_t dbg_usart3_last_len = 0;
|
||||
volatile uint16_t dbg_usart6_last_len = 0;
|
||||
|
||||
static usart_rx_slot_t * usart_rx_slot_find(UART_HandleTypeDef * huart)
|
||||
{
|
||||
for (uint8_t i = 0; i < USART_RX_SLOT_MAX; i++)
|
||||
if (usart_rx_slots[i].huart == huart)
|
||||
return &usart_rx_slots[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usart_rx_dma_start(usart_rx_slot_t * slot, DMA_HandleTypeDef * hdma_rx)
|
||||
{
|
||||
__HAL_DMA_DISABLE(hdma_rx);
|
||||
while (hdma_rx->Instance->CR & DMA_SxCR_EN)
|
||||
;
|
||||
|
||||
/* F4 手册要求:重新使能流之前必须清除该流全部事件标志,
|
||||
* 否则残留标志会导致流重启后不工作(表现为只收到第一帧) */
|
||||
{
|
||||
DMA_TypeDef * ctl = (DMA_TypeDef *)((uint32_t)hdma_rx->Instance & ~(0x3FFU));
|
||||
uint32_t stream_no = ((uint32_t)hdma_rx->Instance - (uint32_t)DMA1_Stream0) / 24U;
|
||||
if (stream_no < 4U)
|
||||
ctl->LIFCR = 0x3FUL << (6U * stream_no);
|
||||
else
|
||||
ctl->HIFCR = 0x3FUL << (6U * (stream_no - 4U));
|
||||
}
|
||||
|
||||
hdma_rx->Instance->PAR = (uint32_t) & (slot->huart->Instance->DR);
|
||||
/* 不使用 DMA 半满/全满中断,只靠空闲中断取帧 */
|
||||
hdma_rx->Instance->CR &= ~(DMA_SxCR_HTIE | DMA_SxCR_TCIE);
|
||||
hdma_rx->Instance->NDTR = slot->buf_num;
|
||||
hdma_rx->Instance->M0AR = (uint32_t)slot->rx_buf;
|
||||
__HAL_DMA_ENABLE(hdma_rx);
|
||||
}
|
||||
|
||||
static void usart_common_rx_init(
|
||||
UART_HandleTypeDef * huart, DMA_HandleTypeDef * hdma_rx, uint8_t * rx_buf, uint16_t dma_buf_num,
|
||||
usart_rx_callback_f callback)
|
||||
{
|
||||
usart_rx_slot_t * slot = usart_rx_slot_find(huart);
|
||||
if (slot == NULL)
|
||||
{
|
||||
for (uint8_t i = 0; i < USART_RX_SLOT_MAX; i++)
|
||||
if (usart_rx_slots[i].huart == NULL)
|
||||
{
|
||||
slot = &usart_rx_slots[i];
|
||||
break;
|
||||
}
|
||||
if (slot == NULL)
|
||||
return;
|
||||
}
|
||||
slot->huart = huart;
|
||||
slot->rx_buf = rx_buf;
|
||||
slot->buf_num = dma_buf_num;
|
||||
slot->callback = callback;
|
||||
|
||||
/* 使能 DMA 接收请求与空闲中断 */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);
|
||||
|
||||
usart_rx_dma_start(slot, hdma_rx);
|
||||
}
|
||||
|
||||
/* 空闲中断处理:取帧长,复位 DMA,回调递交(在各 USARTx_IRQHandler 的 USER CODE 区调用) */
|
||||
static void usart_idle_process(usart_rx_slot_t * slot, DMA_HandleTypeDef * hdma_rx)
|
||||
{
|
||||
if (slot == NULL || slot->callback == NULL)
|
||||
return;
|
||||
|
||||
__HAL_UART_CLEAR_IDLEFLAG(slot->huart);
|
||||
|
||||
uint16_t recv_len = slot->buf_num - hdma_rx->Instance->NDTR;
|
||||
usart_rx_dma_start(slot, hdma_rx);
|
||||
if (hdma_rx == &hdma_usart3_rx)
|
||||
dbg_usart3_last_len = recv_len;
|
||||
else if (hdma_rx == &hdma_usart6_rx)
|
||||
dbg_usart6_last_len = recv_len;
|
||||
if (recv_len > 0)
|
||||
slot->callback(slot->rx_buf, recv_len);
|
||||
}
|
||||
|
||||
/* --- 三路串口的 IDLE 中断入口,由 stm32f4xx_it.c 调用 --- */
|
||||
void usart1_idle_isr(void)
|
||||
{
|
||||
dbg_usart1_idle++;
|
||||
usart_idle_process(usart_rx_slot_find(&huart1), &hdma_usart1_rx);
|
||||
}
|
||||
void usart3_idle_isr(void)
|
||||
{
|
||||
dbg_usart3_idle++;
|
||||
usart_idle_process(usart_rx_slot_find(&huart3), &hdma_usart3_rx);
|
||||
}
|
||||
void usart6_idle_isr(void)
|
||||
{
|
||||
dbg_usart6_idle++;
|
||||
usart_idle_process(usart_rx_slot_find(&huart6), &hdma_usart6_rx);
|
||||
}
|
||||
|
||||
int usart_rx_register(UART_HandleTypeDef * huart, usart_rx_callback_f callback)
|
||||
{
|
||||
usart_rx_slot_t * slot = usart_rx_slot_find(huart);
|
||||
if (slot == NULL)
|
||||
return -1;
|
||||
slot->callback = callback;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
* 各串口接收初始化(在任务上下文调用;DMA/NVIC 已由 CubeMX 初始化)
|
||||
* ========================================================================== */
|
||||
|
||||
/* 视觉上位机串口(4pin 口 UART2),本工程暂未使用,保留接口 */
|
||||
void usart1_init(uint8_t * rx_buf, uint16_t dma_buf_num, usart_rx_callback_f callback)
|
||||
{
|
||||
usart_common_rx_init(&huart1, &hdma_usart1_rx, rx_buf, dma_buf_num, callback);
|
||||
}
|
||||
|
||||
/* DR16 遥控器接收机专用(100000-8E1)
|
||||
* CubeMX 生成的 WordLength=8B 在奇偶校验下只有 7 个数据位,
|
||||
* DR16 帧需要 8 数据位+偶校验,必须改为 9 位字长后重新初始化 */
|
||||
void usart3_init(uint8_t * rx_buf, uint16_t dma_buf_num, usart_rx_callback_f callback)
|
||||
{
|
||||
CLEAR_BIT(huart3.Instance->CR1, USART_CR1_UE); /* 先关串口再改字长 */
|
||||
huart3.Init.WordLength = UART_WORDLENGTH_9B;
|
||||
if (HAL_UART_Init(&huart3) != HAL_OK)
|
||||
return;
|
||||
|
||||
usart_common_rx_init(&huart3, &hdma_usart3_rx, rx_buf, dma_buf_num, callback);
|
||||
}
|
||||
|
||||
/* 图传链路/裁判系统串口(3pin 口 UART1) */
|
||||
void usart6_init(uint8_t * rx_buf, uint16_t dma_buf_num, usart_rx_callback_f callback)
|
||||
{
|
||||
usart_common_rx_init(&huart6, &hdma_usart6_rx, rx_buf, dma_buf_num, callback);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
* 发送(TX DMA,发送缓冲须保持有效直至传输完成)
|
||||
* ========================================================================== */
|
||||
|
||||
void usart1_tx_dma_init(void)
|
||||
{
|
||||
SET_BIT(huart1.Instance->CR3, USART_CR3_DMAT);
|
||||
}
|
||||
|
||||
void usart1_tx_dma_enable(uint8_t * data, uint16_t len)
|
||||
{
|
||||
__HAL_DMA_DISABLE(&hdma_usart1_tx);
|
||||
while (hdma_usart1_tx.Instance->CR & DMA_SxCR_EN)
|
||||
;
|
||||
hdma_usart1_tx.Instance->M0AR = (uint32_t)data;
|
||||
hdma_usart1_tx.Instance->NDTR = len;
|
||||
__HAL_DMA_ENABLE(&hdma_usart1_tx);
|
||||
}
|
||||
|
||||
void usart6_tx_dma_enable(uint8_t * data, uint16_t len)
|
||||
{
|
||||
SET_BIT(huart6.Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
__HAL_DMA_DISABLE(&hdma_usart6_tx);
|
||||
while (hdma_usart6_tx.Instance->CR & DMA_SxCR_EN)
|
||||
;
|
||||
hdma_usart6_tx.Instance->M0AR = (uint32_t)data;
|
||||
hdma_usart6_tx.Instance->NDTR = len;
|
||||
__HAL_DMA_ENABLE(&hdma_usart6_tx);
|
||||
}
|
||||
Reference in New Issue
Block a user