多商城入住网站建设php网站建设
news/
2025/10/8 6:41:45/
文章来源:
多商城入住网站建设,php网站建设,百度识图查图片,网站的空间是什么意思STM32CubeMX学习笔记-USART_DMA 一、DMA的概念二、数据传输方式普通模式循环模式 三、以串口方式讲解串口DMA方式发送函数#xff1a;HAL_UART_Transmit_DMA串口DMA方式接收函数#xff1a;HAL_UART_Receive_DMA获取未传输数据个数函数#xff1a;__HAL_DMA_GET_COUNTER关闭… STM32CubeMX学习笔记-USART_DMA 一、DMA的概念二、数据传输方式普通模式循环模式 三、以串口方式讲解串口DMA方式发送函数HAL_UART_Transmit_DMA串口DMA方式接收函数HAL_UART_Receive_DMA获取未传输数据个数函数__HAL_DMA_GET_COUNTER关闭DMA数据流__HAL_DMA_DISABLE 四、DMA24.1 配置串口24.2 配置DMA4.3 生成代码4.4 USARTDMA数据发送4.5 USARTDMA数据接收4.6 串口IDLE空闲中断DMA数据接收 一、DMA的概念
直接存储器访问DMA)用于在外设与存储器之间以及存储器与存储器之间进行高速数据传输。DMA传输过程的初始化和启动由CPU完成传输过程由DMA控制器来执行无需CPU参与从而节省CPU资源提高利用率。
DMA数据传输的四个要素 ①传输源DMA数据传输的来源 ②传输目标DMA数据传输的目的 ③传输数量DMA传输数据的数量 ④触发信号启动一次DMA数据传输的动作
STM32的DMA控制器特点 1.STM32F411微控制器具备两个DMA控制器DMA1和DMA2,每个控制器有8个数据流每个数据流可以映射到8个通道(或请求) 2.每一个DMA控制器用于管理一个或多个外设的存储器访问请求并通过总线仲裁器来协调各个DMA请求的优先级 3.数据流stream)是用于连接传输源和传输目标的数据通路每个数据流可以配置为不同的传输源和传输目标这些传输源和传输目标称为通道Channel) 4.具备16字节的FIFO。使能FIFO功能后源数据先送入FIFO达到FIFO的触发阈值后再传送到目标地址。
二、数据传输方式
普通模式
传输结束后即要传输数据的数量达到零将不再产生DMA操作。若开始新的DMA传输需在关闭DMA通道情况下重新启动DMA传输。
循环模式
可用于处理环形缓冲区和连续数据流例如ADC扫描模式。当激活循环模式后每轮传输结束时要传输的数据数量将自动用设置的初始值进行加载并继续响应DMA请求。
三、以串口方式讲解
串口DMA方式发送函数HAL_UART_Transmit_DMA
函 数 原 型 | HAL_StatusTypeDef HAL_UART_Transmit_DMA (UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size) ------------------ | ---------------DMA 功能描述 | 在DMA方式下发送一定数量的数据 入口参数1 | huart:串口句柄的地址 入口参数2 | pData:待发送数据的首地址 入口参数3 | Size:待发送数据的个数 返回值 | HAL状态值HAL_OK表示发送成功HAL_ERROR表示参数错误HAL_BUSY表示串口被占用 注意事项 | 1.该函数将启动DMA方式的串口数据发送2.完成指定数量的数据发送后可以触发DMA中断在中断中将调用发送中断回调函数HAL_UART_TxCpltCallback进行后续处理3.该函数由用户调用
串口DMA方式接收函数HAL_UART_Receive_DMA
函 数 原 型HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size)功能描述在DMA方式下接收一定数量的数据入口参数1huart:串口句柄的地址入口参数2pData:待收数数据的首地址入口参数3Size:待收数数据的个数返回值HAL状态值HAL_OK表示发送成功HAL_ERROR表示参数错误HAL_BUSY表示串口被占用注意事项1.该函数将启动DMA方式的串口数据接收2.完成指定数量的数据接收后可以触发DMA中断在中断中将调用接收中断回调函数HAL_UART_RxCpltCallback进行后续处理3.该函数由用户调用
获取未传输数据个数函数__HAL_DMA_GET_COUNTER
函 数 原 型HAL_DMA_GET_COUNTER(HANDLE)功能描述获取DMA数据流中未传输数据的个数参数HANDLE_串口句柄的地址返回值NDTR寄存器的内容即DMA数据流中无传输数据的个数注意事项1.该函数是宏函数进行宏替换不发生函数调用2.该函数需要由用户调用用于获取未传输数据的个数
关闭DMA数据流__HAL_DMA_DISABLE
函数原型HAL_DMA_DISABLE(HANDLE_)功能描述关闭指定的DMA数据流参数HANDLE_串口句柄的地址返回值无注意事项1.该函数是宏函数进行宏替换不发生函数调用2.该函数需要由用户调用用于关闭指定的DMA数据流3.关闭DMA数据流后触发DMA中断最终调用串口收发的回调函数
四、DMA2
4.1 配置串口2
在 Connectivity 中选择 USART2 设置并选择 Asynchronous 异步通信 基础参数波特率为115200 Bits/s。传输数据长度为8 Bit。奇偶检验无停止位1 接收和发送都使能 NVIC Settings 一栏使能接收中断
4.2 配置DMA 根据DMA通道预览可以知道点击 DMA Settings 添加 USART2 TX 和 USART2 RX 分别对应DMA1 的通道5和通道6。
●Direction 传输方向 外设到内存 Peripheral To Memory 内存到外设 Memory To Peripheral 内存到内存 Memory To Memory 外设到外设 Peripheral To Peripheral ●Priority 传输速度 最高优先级 Very Hight 高优先级 Hight 中等优先级 Medium 低优先级Low 当发生多个 DMA 通道请求时就意味着有先后响应处理的顺序问题这个就由仲裁器也管理。仲裁器管理 DMA 通道请求分为两个阶段。第一阶段属于软件阶段可以在 DMA_CCRx 寄存器中设置有 4 个等级非常高、高、中和低四个优先级。第二阶段属于硬件阶段如果两个或以上的 DMA 通道请求设置的优先级一样则他们优先级取决于通 道编号编号越低优先权越高比如通道 0 高于通道 1。在大容量产品和互联型产品中DMA1 控制器拥有高于 DMA2 控制器的优先级。
■DMA Request Setting DMA传输的对应外设
●Mode传输模式 Normal 正常模式。表示当一次DMA数据传输完后停止DMA传送 也就是只传输一次。 Circular 循环模式。表示传输完成后又重新开始继续传输不断循环永不停止。 ●Increment Address Peripheral 表示外设地址自增。 Memory 表示内存地址自增。 串口发送数据是将数据不断存进串口的发送数据寄存器(USARTx_TDR)。所以外接的地址是不递增。而内存储器存储的是要发送的数据所以地址指针要递增才能将所以的数据发送出去。
●Data Width Byte 一个字节。 Half Word 半个字等于两字节。 Word 一个字等于四字节。 串口数据发送寄存器只能存储8bit,每次发送一个字节所以数据长度选择Byte。
4.3 生成代码
输入项目名和项目路径
选择应用的 IDE 开发环境 MDK-ARM V5
每个外设生成独立的 ’.c/.h’ 文件 不勾所有初始化代码都生成在 main.c 勾选初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。
点击 GENERATE CODE 生成代码
4.4 USARTDMA数据发送
新建一个变量
uint8_t sendBuff[] USART test by DMA\r\n;在 man.c 中的主循环添加以下代码 /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */HAL_UART_Transmit_DMA(huart2, (uint8_t *)sendBuff, sizeof(sendBuff));HAL_Delay(1000);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}通过串口助手可以看到在接收区有数据不断的打印输出
注意如果不开启串口中断则程序只能发送一次数据,程序不能判断DMA传输是否完成USART一直处于busy状态。
4.5 USARTDMA数据接收
/*** brief The application entry point.* retval int*/
int main(void)
{/* USER CODE BEGIN 1 */uint8_t rxSize 1;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_UART_Receive_DMA(huart2, (uint8_t *)Buffer, rxSize);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}在 stm32f1xx_it.c 这个文件的最下面添加 HAL_UART_RxCpltCallback()
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if (huart-Instance USART2){// 在这里处理接收到的数据例如将数据存储到缓冲区或者显示在UI上memcpy(Buffer, (uint8_t *)huart2-Instance-DR, rxSize);HAL_UART_Receive_DMA(huart2, (uint8_t *)Buffer, rxSize);}
}通过串口助手发送 OK可以看到接收到 O这是因为设置的接收数据是一个字符如果要接收更多字符请加大 Buffer。
4.6 串口IDLE空闲中断DMA数据接收
特点
●可以实现任意字符串接收并输出。 ●在串口无数据接收的情况下不会产生当清除IDLE标志位后必须有接收到第一个数据后才开始触发一但接收的数据断流没有接收到数据即产生IDLE中断。 在 main.c 中添加以下变量
uint8_t recvBuff[BUFFER_SIZE]; //接收数据缓存数组
volatile uint8_t recvLength 0; //接收一帧数据的长度
volatile uint8_t recvDndFlag 0; //一帧数据接收完成标志在 main.h 中添加以下宏定义与变量
#define BUFFER_SIZE 256
extern uint8_t recvBuff[BUFFER_SIZE]; //接收数据缓存
extern volatile uint8_t recvLength; //接收一帧数据的长度
extern volatile uint8_t recvDndFlag; //一帧数据接收完成标志在 main.c 中while 循环前串口初始化后添加空闲中断和DMA接收开启函数这样在第一次接收到数据的时候才会触发中断。
/*** brief The application entry point.* retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_DMA_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */__HAL_UART_ENABLE_IT(huart1, UART_IT_IDLE); //使能IDLE中断HAL_UART_Receive_DMA(huart1, recvBuff, BUFFER_SIZE);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}在 stm32f1xx_it.c 这个文件的最下面修改 USART1_IRQHandler()
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 */uint32_t tmpFlag 0;uint32_t temp;tmpFlag __HAL_UART_GET_FLAG(huart1,UART_FLAG_IDLE); //获取IDLE标志位if((tmpFlag ! RESET))//idle标志被置位{ __HAL_UART_CLEAR_IDLEFLAG(huart1);//清除标志位HAL_UART_DMAStop(huart1); //temp __HAL_DMA_GET_COUNTER(hdma_usart1_rx);// 获取DMA中未传输的数据个数 recvLength BUFFER_SIZE - temp; //总计数减去未传输的数据个数得到已经接收的数据个数recvDndFlag 1; // 接受完成标志位置1 HAL_UART_Transmit_DMA(huart1, recvBuff, recvLength);recvLength 0;//清除计数recvDndFlag 0;//清除接收结束标志位memset(recvBuff,0,recvLength);HAL_UART_Receive_DMA(huart1, recvBuff, BUFFER_SIZE);//重新打开DMA接收不然只能接收一次数据}/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}通过串口助手发送不定长数据
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/931157.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!