TxRX选择正常Normal模式:
配置完毕
main.h
#include "stdio.h"
#include "string.h"
#include
#include "usart.h"
#include "dma.h"
//usart.h文件,变量外部声明
#define USART_DMA_TX_BUFFER_MAXIMUM 256 // DMA缓冲区大小
#define USART_DMA_RX_BUFFER_MAXIMUM 256 // DMA缓冲区大小
extern uint8_t usart1_rx_buffer[USART_DMA_RX_BUFFER_MAXIMUM]; //串口1的DMA接收缓冲区
extern uint8_t usart1_tx_buffer[USART_DMA_TX_BUFFER_MAXIMUM]; //串口1的DMA发送缓冲区
extern uint8_t usart1_rx_flag; //DMA接收成功标志 0,未接收到/1,接收到等待处理
extern uint16_t usart1_rx_len; //DMA一次空闲中断接收到的数据长度
extern uint8_t receive_u1_data[USART_DMA_RX_BUFFER_MAXIMUM]; //DMA接收数据缓存区
注意:要放到有注释begin和end的中间,不然下次重新配置生成会被擦除。
usart.c文件中:
//变量外部声明
uint8_t usart1_rx_buffer[USART_DMA_RX_BUFFER_MAXIMUM]; //串口1的DMA接收缓冲区
uint8_t usart1_tx_buffer[USART_DMA_TX_BUFFER_MAXIMUM]; //串口1的DMA发送缓冲区
uint8_t usart1_rx_flag = 0; //DMA接收成功标志 0,未接收到/1,,接收到等待处理
uint16_t usart1_rx_len = 0; //DMA一次空闲中断接收到的数据长度
uint8_t receive_u1_data[USART_DMA_RX_BUFFER_MAXIMUM]; //DMA接收数据缓存区
//串口1的DMA发送
void UART1_TX_DMA_Send(uint8_t *buffer, uint16_t length)
{
//等待上一次的数据发送完毕
while(HAL_DMA_GetState(&hdma_usart1_tx) != HAL_DMA_STATE_READY);
//while(__HAL_DMA_GET_COUNTER(&hdma_usart1_tx));
//关闭DMA
__HAL_DMA_DISABLE(&hdma_usart1_tx);
//开始发送数据
HAL_UART_Transmit_DMA(&huart1, buffer, length);
}
//串口1的DMA发送printf
void printf1(const char *format, ...)
{
uint32_t length = 0;
va_list args;
__va_start(args, format);
length = vsnprintf((char*)usart1_tx_buffer, sizeof(usart1_tx_buffer), (char*)format, args);
UART1_TX_DMA_Send(usart1_tx_buffer, length);
}
然后记得在usart.h文件中声明
发送测试:(main.c)
使能DMA接收,并于接收完后进入空闲中断函数
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
函数作用:在DMA模式下接收一定数量的数据,直到接收到预期数量的数据或发生空闲事件。
参数Size:接收数据的长度,一般大于不定长数据长度,避免遗漏数据空闲中断回调函数
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
使能DMA接收
主函数:
HAL_UARTEx_ReceiveToIdle_DMA(&huart1,usart1_rx_buffer,USART_DMA_RX_BUFFER_MAXIMUM);
中断:
中断回调函数,放usart.c
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1) //如果是串口1
{
memset(receive_u1_data, 0, usart1_rx_len);//清除上次缓存的数据
usart1_rx_len = USART_DMA_RX_BUFFER_MAXIMUM - (__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)); //接收个数等于接收缓冲区总大小减剩余计数
/* 搬移数据进行其他处理 */
memcpy(receive_u1_data, usart1_rx_buffer, usart1_rx_len);
usart1_rx_flag = 1; //标志已经成功接收到一包等待处理
}
}
测试(main.c)
if (usart1_rx_flag)
{
count++;
printf1("接收数据次数: %d\r\n接收数据长度: %d\r\n接收数据内容:%s",count,usart1_rx_len,receive_u1_data);
//delay_ms(10);
//Debug_printf("连续传送\r\n");
usart1_rx_flag = 0;
//usart1_rx_len = 0;
}
烧入进去要复位一下,可以在这里设置就不用复位了
结果: