GD 32空闲中断DMA串口接收

前言


通过本次代码的学习,搞懂USART配置,DMA配置,数据校验,数据接收,进一步巩固串口发送和接收知识,了解指针和结构体的使用。


DMA 转运基础知识补充

串口接收中断的流程

配置串口接收使用DMA的方式


 初始化各个驱动

 声明结构体给结构体,创建结构体数字,初始化数据包格式

typedef struct
{
	uint32_t uartNo;
	rcu_periph_enum rcuUart;
	rcu_periph_enum rcuGpio;
	uint32_t gpio;
	uint32_t txPin;
	uint32_t rxPin;
	uint8_t irq;
	uint32_t dmaNo;
	rcu_periph_enum rcuDma;
	dma_channel_enum dmaCh;
} UartHwInfo_t;

static UartHwInfo_t g_uartHwInfo = 
{
	USART0,
	RCU_USART0, 
	RCU_GPIOA, 
	GPIOA,
	GPIO_PIN_9,
	GPIO_PIN_10,
	USART0_IRQn,
	DMA0,
	RCU_DMA0,
	DMA_CH4
};

#define USART0_DATA_ADDR      (USART0 + 0x04)   //串口0的数据寄存器十六进制地址值
						
/**
***********************************************************************
包格式:帧头0  帧头1  数据长度  功能字   LED编号  亮/灭  异或校验数据
        0x55   0xAA    0x03      0x06     0x00     0x01      0xFB
***********************************************************************
*/
#define FRAME_HEAD_0        0x55  
#define FRAME_HEAD_1        0xAA
#define CTRL_DATA_LEN       3     //数据域长度
#define PACKET_DATA_LEN     (CTRL_DATA_LEN + 4)  //包长度
#define FUNC_DATA_IDX       3     //功能字数组下标
#define LED_CTRL_CODE       0x06  //功能字

#define MAX_BUF_SIZE 20
static uint8_t g_rcvDataBuf[MAX_BUF_SIZE];
static bool g_pktRcvd = false;

typedef struct
{
	uint8_t ledNo;
	uint8_t ledState;
} LedCtrlInfo_t;				

gpio 初始化

 创建一个函数用于调用,gpio,usart,dma的初始化函数,第二个函数传递进去一个波特率为115200.

/**
***********************************************************
* @brief USB转串口硬件初始化
* @param
* @return 
***********************************************************
*/
void Usb2ComDrvInit(void)
{
	Usb2ComGpioInit();
	Usb2ComUartInit(115200);
	Usb2ComDmaInit();
}

gpio 初始化代码

 这是一个静态的函数只能在函数的内部进行调用对外部时隐藏的,


                
### GD32 UART Idle Line Interrupt and Receive Interrupt Implementation For the GD32 microcontroller series, implementing UART idle line interrupts (IDLE) along with receive interrupts allows efficient handling of serial data reception without continuous CPU polling. This method is particularly useful when receiving packets of varying lengths or detecting pauses between transmissions. #### Enabling IDLE Interrupts To enable an idle line detection interrupt on a UART interface: 1. Configure the UART peripheral to generate an interrupt upon detecting an idle line condition. 2. Ensure that NVIC settings are configured so that the corresponding IRQ can be serviced by the processor. The following code snippet demonstrates how to set up these configurations using HAL libraries[^2]: ```c // Enable UART RXNE and IDLE interrupts HAL_UART_Receive_IT(&huart1, rxBuffer, BUFFER_SIZE); ``` This function call prepares the UART hardware to trigger both buffer full (`RXNE`) as well as end-of-frame (`IDLE`) events which will invoke the associated ISR handler once any event occurs. #### Handling Received Data via DMA When utilizing Direct Memory Access (DMA), it becomes possible to offload much of the work from the main processing unit while still maintaining high throughput rates during bulk transfers over UART lines. By configuring DMA channels correctly alongside enabling appropriate flags within the UART configuration structure, one may achieve seamless background transfer operations even under heavy load conditions. Here’s an example setup for initializing DMA-based reception combined with IDLE interrupt support: ```c static void MX_DMA_Init(void) { /* Init DMAs */ __HAL_RCC_DMA1_CLK_ENABLE(); hdma_usart1_rx.Instance = DMA1_Channel5; hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode = DMA_NORMAL; // Normal mode instead of circular hal_dma_init(&hdma_usart1_rx); __HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx); } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance== USART1){ // Process received frame here... // Restart listening after each complete packet has been processed HAL_UARTEx_ReceiveToIdle_DMA(&huart1, rxBuffer, BUFFER_SIZE); } } ``` In this case, `HAL_UARTEx_ReceiveToIdle_DMA` starts monitoring incoming bytes until either all expected characters have arrived or there was no activity detected for some time—triggering the IDLE state—and thus invoking the callback where further actions like parsing messages could take place immediately afterward. #### Important Considerations - Always ensure proper synchronization mechanisms exist around shared resources accessed inside ISRs versus normal program flow paths. - Carefully choose buffer sizes based on application requirements considering worst-case scenarios regarding message length and timing constraints imposed by external devices communicating through the link layer protocol stack implemented atop physical transport mediums such as RS-232/485 etc. --related questions-- 1. How does setting up different types of UART interrupts impact system performance? 2. What precautions should developers consider when working with DMA in embedded systems? 3. Can you explain more about error handling strategies specifically tailored towards UART communication protocols used in GD32 platforms? 4. Is it feasible to implement multiple UART instances simultaneously supporting various features including IDLE interrupts efficiently?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值