**串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负**
来源:互联网 发布:apache ab post json 编辑:程序博客网 时间:2024/06/17 01:51
串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负
在使用串口接受数据时,如果用while在主函数等待,或者用if在主函数判断,传输少量的标志位可以,程序效率很低,如果用DMA+单字节串口接受中断,这样效率高了,但是当我们需要不间断传输大量数据时,单片机频繁进入中断,有时会影响main()函数的运行,如果采用串口总线空闲触发中断+DMA传输,可以完美的解决这两个问题。
USART_SR寄存器的IDLE位
代码如下:
/******************************************************************************** * @file LSYY_Usart_Api.c * @author 绿水颖颖 * @version V1.0 * @date 2017.7.26 * @brief 传输大量数据时 空闲中断+DMA传输 为CPU减负 ****************************************************************************** * @attention * * ********************************************************************************/#include "LSYY_Usart_Api.h"#include "LSYY_usart.h"#include "LSYY_led.h"/*内存池*/uint8_t DMA_Rece_Buf[USART_RX_BUFF_SIZE];/* *函数名` : void USURT1_Config(void) *描述 :配置USART1 *输入 :无 *输出 :无 */void USART_Config(void){ GPIO_InitTypeDef GPIO_InitStructure ; USART_InitTypeDef USART_InitStructure ; //开启串口的时钟 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK ,ENABLE); //开启GPIO的时钟 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK,ENABLE); //配置串口1的寄存器 //配置串口1所对应的GPIO口 //配置模式 复用推挽输出模式 GPIO_InitStructure.GPIO_Pin=DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP ; //配置输出速率 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //初始化GPIO口 GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure); //配置串口1GPIO口的模式 //GPIOA10 //GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PORT_PIN; GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PIN; //配置串口模式 GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING ; //初始化GPIOA GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure); //配置串口 //设置波特率 USART_InitStructure.USART_BaudRate =DEBUG_USART_BAUDRATE ; //设置传输字节 USART_InitStructure.USART_WordLength=USART_WordLength_8b; //设置停止标志位 USART_InitStructure.USART_StopBits=USART_StopBits_1; //配置奇偶校检位,不设置 USART_InitStructure.USART_Parity=USART_Parity_No; //配置硬件控制流,不配置 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None ; //配置串口模式 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx ; //初始化串口1 USART_Init(DEBUG_USARTx ,&USART_InitStructure); /****************************************************注意**************************************************/ /*开启空闲中断*/ USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); /*开启DMA传输数据*/ USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能串口 USART_Cmd(DEBUG_USARTx ,ENABLE); USART_ClearFlag(USART1, USART_FLAG_TC); }/** * @brief 串口空闲中断(IDLE)无 * @param 无 * @retval 无 **/void USART_IDLE_NVIC_Configuration(void){ NVIC_InitTypeDef NVIC_InitStructure; /* 配置中断源:IDLE */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; /* 配置抢占优先级 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 配置子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; /* 使能中断通道 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //初始化 NVIC_Init(&NVIC_InitStructure);}/** * @brief USART1 DMA配置 * @param 无 * @retval 无 **/void USART_DMA_Config(void){ DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输 //相应的DMA配置 DMA_DeInit(DMA1_Channel5); //将DMA的通道5寄存器重设为缺省值 串口1对应的是DMA通道5 //DMA外设ADC基地址 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //DMA内存基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf; //数据传输方向,从外设读取发送到内存 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_BufferSize = USART_RX_BUFF_SIZE; //外设地址寄存器不变 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //内存地址寄存器递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //数据宽度为8位 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //工作在正常缓存模式 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道x没有设置为内存到内存传输 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 DMA_Init(DMA1_Channel5, &DMA_InitStructure); //正式驱动DMA传输 DMA_Cmd(DMA1_Channel5, ENABLE); }/** * @brief 串口DMA配置复位函数 恢复DMA指针 * @param 无 * @retval 无 **/void DeInit_USART_DMA(DMA_Channel_TypeDef*DMA_CHx){ //串口DMA失能 DMA_Cmd(DMA_CHx,DISABLE); /*DMA传输数值重装*/ DMA_SetCurrDataCounter(DMA_CHx,USART_RX_BUFF_SIZE); //串口DMA使能 DMA_Cmd(DMA_CHx,ENABLE);}/** * @brief 串口发送一个数组、字符串 * @param buf 字符串数组地址 len 数组字符串长度 * @retval 无 **/void Usart1_Send(u8 *buf,u8 len){ u8 t; //循环发送数据 for(t=0;t<len;t++) { while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); USART_SendData(USART1,buf[t]); } while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); }/** * @brief 串口中断 * @param 无 * @retval 无 **//*用于计算不同长度数据的长度*/uint32_t DMA_Buf_Cnt;void USART1_IRQHandler(void){ /*串口空闲标志位置1*/ if(USART_GetITStatus(USART1,USART_IT_IDLE)==SET) { /* 必须得写,不然IDLE位清除不了 */ USART_ReceiveData(USART1); /*计算出本帧数据长度*/ DMA_Buf_Cnt=USART_RX_BUFF_SIZE-DMA_GetCurrDataCounter(DMA1_Channel5); /*测试程序*/ printf("Length:%d\r\n",DMA_Buf_Cnt); printf("Data:\r\n"); Usart1_Send((uint8_t *)DMA_Rece_Buf,DMA_Buf_Cnt); printf("\r\n \r\n"); //清除中断标志位 USART_ClearITPendingBit(USART1,USART_IT_IDLE); /*DMA使能*/ DeInit_USART_DMA(DMA1_Channel5); }}/** * @brief 测试函数 * @param 无 * @retval 无 **/void USART_DMA_Test(void){ USART_IDLE_NVIC_Configuration(); USART_DMA_Config();}/** * @brief 主函数 * @param 无 * @retval 无 **/int main(){ All_Init(); USART_DMA_Test(); while(1) { /*所有要处理任务*/// TaskProcess(); }}
串口上位机截图
注意内容:
!IDLE位清零必须进行一个读USART_SR寄存器操作,接着进行一个读取USART_DR寄存器操作
本人菜鸟,正在学习中,有问题还请多多交流指正1558194318@qq.com,如有侵权立即删除。
阅读全文
1 0
- **串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负**
- STM32F207运用串口空闲中断+DMA接收不定长数据
- STM32使用DMA加串口空闲中断接收数据
- STM32F207运用串口空闲中断+DMA接收不定长数据
- STM32F207运用串口空闲中断+DMA接收不定长数据
- stm32-9DMA为CPU减负
- DMA+LeUart传输数据
- dma传输原理,及其linux总线驱动之DMA传输,
- STM32利用串口空闲中断在串口DMA配置下接收变长数据
- Stm32——串口空闲中断+DMA接收不定长数据
- STM32CubeMX 串口空闲中断加DMA 实现不定长度收发数据
- DMA传输小程序,解决“总线错误”
- linux总线驱动之DMA传输
- linux总线驱动之DMA传输
- DMA传输数据过程简介
- STM32 HAL 库, 配置串口DMA接收及空闲中断
- 大数据串口传输
- stm32的串口空闲中断接收数据
- HTTP缓存机制及原理
- eclipse怎么创建library目录
- 源码反码补码
- 精通使用K米短信教程
- GCC 中的编译器堆栈保护技术
- **串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负**
- redis集群和spring结合
- 一段痛苦的电子从业之路(一)
- ajax常用知识点
- 线程安全和可重入函数
- tomcat相关
- 商品浏览记录实现
- java quartz配置
- 崩溃日志分析