使用CUBE_MX实现STM32 DMA功能 (储存器发送数据到外设串口)+(外设串口将数据写入到存储器)
目录
一、配置串口打印(参考串口打印的文章)
二、CUBE_MX配置
三、KEIL5配置
1.打开dma.c文件(默认初始化DMA中断函数)
2.打开usart.c文件
3.打开main.c文件(储存器发送数据到外设串口)
4.打开main.c文件(外设串口将数据写入储存器)
一、配置串口打印(参考串口打印的文章)
二、CUBE_MX配置
1.选择USART1串口,配置为异步发送
2.在DMA Setting中add
USART1_RX(串口到储存器)
USART1_TX(存储器到串口)
3.配置优先级、传输数据的大小
4.生成代码
三、KEIL5配置
1.打开dma.c文件(默认初始化DMA中断函数)
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
2.打开usart.c文件
定义了句柄结构体
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart1_rx;
串口参数配置
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
要手动增补初始化函数(不要忘记了)
HAL_UART_Init(&huart1);
上述代码配置了串口的传输速度和模式(可以通过软件配置),如图:
初始化 USART1_RX(串口到储存器)、 USART1_TX(存储器到串口)
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
/* USART1_RX Init */
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;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA1_Channel4;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
要手动增补初始化函数(不要忘记了)
HAL_DMA_Init(&hdma_usart1_tx);
HAL_DMA_Init(&hdma_usart1_rx);
3.打开main.c文件(储存器发送数据到外设串口)
1.定义存储器1
#define SENDBUFF_SIZE 13
uint8_t SendBuff[SENDBUFF_SIZE];//储存器(给外设串口发送数据)
2.在主结构体存储数据
HAL_UART_Transmit_DMA函数中,储存器中只能使用 ‘’ (单个字符)
int i;
for(i=0;i<SENDBUFF_SIZE;i=i+13)
{
SendBuff[i] = 'M';
SendBuff[i+1] = 'L';
SendBuff[i+2] = 'S';
SendBuff[i+3] = ' ';
SendBuff[i+4] = 'L';
SendBuff[i+5] = 'O';
SendBuff[i+6] = 'V';
SendBuff[i+7] = 'E';
SendBuff[i+8] = ' ';
SendBuff[i+9] = 'M';
SendBuff[i+10] = 'X';
SendBuff[i+11] = ' ';
}
3.配置串口打印(参考另一篇文章)
4.在main结构体中调用函数
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)SendBuff ,SENDBUFF_SIZE);
//三个参数 1.USART句柄结构体 2.要发送数据的存储器 3.数据大小
5.打开串口调试助手
4.打开main.c文件(外设串口将数据写入储存器)
1.定义储存器2
#define SENDBUFF_SIZE 13
uint8_t ReceiveBuff[SENDBUFF_SIZE];
2.配置串口打印
3.在main结构体中调用函数
HAL_UART_Receive_DMA(&huart1,(uint8_t *)ReceiveBuff,SENDBUFF_SIZE);
//三个参数 1.串口的句柄结构体 2.要接收串口数据的存储器 3.数据大小
4.再调用函数把存储的数据再发送到串口中
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)ReceiveBuff,SENDBUFF_SIZE);
5.打开串口助手,发送数据999,并回显
作者:明月清风mls