第六篇 STM32CubeMX创建STM32工程之串口+DMA采集实验
一、串口+DMA配置
1.串口配置
参考第五篇
2.DMA配置
接收DMA配置,共分五步
1.选择串口配置
2.选择DMA settings
3.增加DMA通道选择接收通道
4.优先,最高
5.接受模式,循环
发送DMA配置,共分四个步骤,比接收收一个,区别在于发送模式使用默认
其他都可以默认,保存导出工程即可
二、串口+DMA收发程序设计
1.修改uart.c程序为
#include "uart.h"
#include "usart.h"
#include "string.h"
unsigned char rx_buf1[buf_size]="";
int recv_end_flag1=0;
int rx_len1=0;
void buff1_clear(void)
{
rx_len1 = 0;
recv_end_flag1 = 0;
memset(rx_buf1, 0x00, buf_size);
}
void uart_init(void)
{
buff1_clear();
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1, rx_buf1, buf_size);
}
修改uart.h程序为
#ifndef __uart_H__
#define __uart_H__
#include "stm32f1xx_hal.h" //引入hal库
void uart_init(void); //定义串口初始化函数
void buff1_clear(void); //定义数据清空函数
#define buf_size 1024
extern unsigned char rx_buf1[buf_size];
extern int recv_end_flag1;
extern int rx_len1;
#endif
在usart.h中定义一个函数void HAL_USER1_IRQHandler(UART_HandleTypeDef *huart);
void HAL_USER1_IRQHandler(UART_HandleTypeDef *huart);
在usart.c添加函数
void HAL_USER1_IRQHandler(UART_HandleTypeDef *huart)
{
uint32_t tmp_flag = 0;
uint32_t temp;
tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
if(tmp_flag != RESET)
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1);
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
rx_len1 = buf_size - temp;
recv_end_flag1 = 1;
}
}
在usart.c中包含#include "uart.h"头文件
#include "uart.h"
在stm32f1xx_it.c的void USART1_IRQHandler(void)函数中添加一行代码
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
HAL_USER1_IRQHandler(&huart1); //添加
/* USER CODE END USART1_IRQn 1 */
}
修改user.c程序如下
#include "user.h"
#include "gpio.h"
#include "usart.h"
#include "uart.h"
int x=0;
void DMA_Usart1_Read(uint8_t *Data,uint16_t len)
{
HAL_UART_Receive_DMA(&huart1,Data,len);
}
void DMA_Usart1_Send(uint8_t *buf,uint16_t len)
{
if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK)
{
Error_Handler();
}
}
void recv_judge_data(void)
{
if(recv_end_flag1 == 1 && rx_buf1[rx_len1-2] == 0x0D && rx_buf1[rx_len1-1] == 0x0A)
{
x=1;
}
}
void user_main(void)
{
uint8_t a[6]="abcd\r\n";
uart_init();
while(1)
{
recv_judge_data();
if(x == 1)
{
DMA_Usart1_Send(a, 6);
buff1_clear();
DMA_Usart1_Read(rx_buf1, buf_size);
x=0;
}
}
}
本程序的编写均看个人习惯,小编使用的是不定长接收,通过判断头尾来判断是否接收结束,欢迎留言探讨。