STM32空闲中断+DMA解决接收不定长数据问题

发布者:cloudsousou6最新更新时间:2018-06-08 来源: eefocus关键字:STM32  空闲中断  DMA  不定长数据 手机看文章 扫描二维码
随时随地手机看文章

串口的中断类型:


#define USART_IT_PE                          ((uint16_t)0x0028)  

#define USART_IT_TXE                         ((uint16_t)0x0727)  

#define USART_IT_TC                          ((uint16_t)0x0626)  

#define USART_IT_RXNE                        ((uint16_t)0x0525)  

#define USART_IT_IDLE                        ((uint16_t)0x0424)  

#define USART_IT_LBD                         ((uint16_t)0x0846)  

#define USART_IT_CTS                         ((uint16_t)0x096A)  

#define USART_IT_ERR                         ((uint16_t)0x0060)  

#define USART_IT_ORE                         ((uint16_t)0x0360)  

#define USART_IT_NE                          ((uint16_t)0x0260)  

#define USART_IT_FE                          ((uint16_t)0x0160)  

USART_IT_PE 奇偶错误中断


USART_IT_TXE发送中断


USART_IT_TC 传输完成中断


USART_IT_RXNE 接收中断


USART_IT_IDLE 空闲总线中断


USART_IT_LBD LIN中断检测中断


USART_IT_CTS CTS中断


USART_IT_ERR 错误中断




该程序中用到的就是串口的空闲中断:当总线是一个字节周期内没有收到数据时触发


串口的配置如下:


void uart_init(u32 bound){  

        GPIO_InitTypeDef GPIO_InitStructure;  

    USART_InitTypeDef USART_InitStructure;  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);   

    NVIC_InitTypeDef NVIC_InitStructure;  

     //IO口相关配置  

    USART_DeInit(USART1);    

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速率  

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;   

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

        GPIO_Init(GPIOA, &GPIO_InitStructure);   

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  

        GPIO_Init(GPIOA, &GPIO_InitStructure);    

        //串口中断配置  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        

        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           

    NVIC_Init(&NVIC_InitStructure);   

    USART_InitStructure.USART_Parity = USART_Parity_No;//没有奇偶校验位  

    USART_InitStructure.USART_BaudRate = bound;       //波特率设置  

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据位  

    USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位  

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流配置  

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//串口收发模式  

        USART_Init(USART1, &USART_InitStructure);   

        USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);  

        USART_Cmd(USART1, ENABLE);    

}    


串口中断配置:


void USART1_IRQHandler(void)                   

{  

      if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)   

{  

       DMA_Cmd(DMA1_Channel5,DISABLE);  

       recok=1;  

       lenth=USART1->DR;//软件清空空闲中断标志位  

       lenth=USART1->SR;  

       lenth=32-DMA_GetCurrDataCounter(DMA1_Channel5);//获取当前接收的数据量   

       USART_RX_BUF[lenth]=0;//在buff最后加入空字符  

       DMA1_Channel5->CNDTR=32;//重新设置传输量为32   

       DMA_Cmd(DMA1_Channel5,ENABLE);  

    }   

}   




DMA配置:


void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)  

{  

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟  

  

      DMA_DeInit(DMA_CHx);  

      DMA1_MEM_LEN=cndtr;  

      DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;//外设地址  

      DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //内存地址  

      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //传输方向外设到内存  

      DMA_InitStructure.DMA_BufferSize = cndtr;  //传输量  

      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不自增    

      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增  

      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;   

      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;   

      DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //普通模式  

      DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级  

      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  

      DMA_Init(DMA_CHx, &DMA_InitStructure);    

}   




主函数中需要进行的配置:


MYDMA_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)USART_RX_BUF,32);//传输方向设置为USART1->DR到USART_RX_BUF 传输大小为32字节  

USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);//允许DMA请求  

DMA_Cmd(DMA1_Channel5,ENABLE);  


当标志为recok位1时表示接受完成  在主函数中等待recok位1就可以了


关键字:STM32  空闲中断  DMA  不定长数据 引用地址:STM32空闲中断+DMA解决接收不定长数据问题

上一篇:STM32 总线空闲 + DMA 方式接收
下一篇:STM32CubeMX:UART(DMA空闲方式)

推荐阅读最新更新时间:2024-03-16 16:05

STM32 DMA模块的配置与使用
DMA有什么用? 直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。 有多少个DMA资源? 有两个DMA控制器,DMA1有7个通道,DMA2有5个通道。 数据从什么地方送到什么地方? 外设到SRAM(I2C/UART等获取数据并送入SRAM); SRAM的两个区域之间; 外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比); SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形); ……还有一些目前还搞不清楚的。 DMA可以传递多少数据?
[单片机]
<font color='red'>STM32</font> <font color='red'>DMA</font>模块的配置与使用
基于STM32的多功能数字钟
/************************************************************************************** 程序功能:基于STM32的多功能数字钟 ************************************************************************************** 1、时钟的基准用STM32F103RCT6自带的RTC实现。 2、这三个按键的功能分别为: 设置 、 + 、 - 。(WAKEUP KEY0 KEY1) 三个按键作为这三个功能: 键盘上的WAKEUP用作 设置 ,KEY0用作
[单片机]
STM32 USB Virtual COM USB转串口的功能实现
这次讲的是如何实现USB转串口功能的实现。首先看看工程的布局吧: 我们主要要介绍的文件的在USB_User这个组文件。从上面的截图可以看到USB_User这个文件由hw_config.c、usb_desc.c、usb_endp.c、usb_istr.c、usb_prop.c、usb_pwr.c几个文件组成。其中usb_istr.c和usb_pwr.c整两个文件不用修改,其他的文件都需要修改。下面接慢慢将来。 首先讲讲hw_config.c这个文件。由于我们用到串口,所以这个文件需要添加串口相关代码。在这个文件的开始就需要定义一下串口的相关变量: uint8_t USART_Rx_Buffer ; //串口接收缓冲 ui
[单片机]
<font color='red'>STM32</font> USB Virtual COM USB转串口的功能实现
关于STM32堆栈方面知识点
最近弄json,发现经常的堆溢出,然后找问题。因为对STM32堆栈问题没有深刻认识,就花时间好好研究下了堆栈并且做了验证 1.栈地址区间确定 首先找到启动文件,我的启动文件在startup_stm32f40xx.s,一般的启动文件也都在startup_stm32fxxxx.s文件里 __initial_sp 这个参数是栈顶地址,因为栈的增长是向下增长,所以这个参数我们可以理解为栈的起始地址,我设置的栈尺寸是0x400,所以栈的地址范围是 __initial_sp ~ (__initial_sp - 0x400),__initial_sp 这个参数是keil编译代码之后计算出来的,有多种方法确定。 2.确定__i
[单片机]
关于<font color='red'>STM32</font>堆栈方面知识点
stm32的几种读保护措施讲解
综合网上讲解的几种读保护措施,这里简单总结下: 采用stm32唯一ID作为加密的字符,使用固定密码,采用16位字节AES加密的方式生成密文,然后写进flash,,app程序执行的时候需要判断读取的stm32唯一ID号和AES解密出来是否一致,是执行程序,否则不执行,测试过,但这个方案针对生产比较麻烦,这里不采用 ChipUniqueID = *(__IO u32 *)(0X1FFFF7F0); // 高字节 ChipUniqueID = *(__IO u32 *)(0X1FFFF7EC); // ChipUniqueID = *(__IO u32 *)(0X1FFFF7E8); // 低字节 ChipUniqueID =
[单片机]
【note】stm32 keilMDK出现warning: function XX declared implicitly
warning: #223-D: function CLR_TX_DATA declared implicitly 解决方法。 以上面错误提示为例: 1 找到定义函数 CLR_TX_DATA() 的源文件 ,这里假设在 a.c 中; 2 在 a.h 中最后声明一下 CLR_TX_DATA(),即添加(假设此函数无返回值无参数) void CLR_TX_DATA(void); 3 再次编译 刚才的 warning 即可消失。 参考自 KEIl编译STM32的时候,出现了一点问题!! 程序编译的时候通过了!!但是显示警告: test.c(45): warning: #22
[单片机]
嵌入式系统学习——STM32之外部中断
STM32与51相比,多了很多资源,其中外部中断就是被扩展了很多。51的外部中断只有2个,但是STM32不是,STM32的每个IO都可以作为外部中断输入。 STM32的中断控制器支持19个外部中断/事件请求: 线0~15:对应外部IO口的输入中断。 线16:连接到PVD输出。 线17:连接到RTC闹钟事件。 线18:连接到USB唤醒事件。 每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。 IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数: 从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数,外部中断线10~15分配一个中
[单片机]
嵌入式系统学习——<font color='red'>STM32</font>之外部<font color='red'>中断</font>
STM32中采用DMA实现方波的产生和捕获
1 STM32微控制器介绍 STM32系列微控制器是ST公司基于Cortex-M3内核的高集成度的微控制器。它在性能、价格、功耗和实时性方面树立了一个新的标杆,集成了Cortex-M3内核,以及双ADC、多用途的通用时钟TIMx、RTC、I2C、SPI、UART、CAN、DMA、USB等丰富的外设。其功耗在全速72MHz所有模块都打开时也仅仅为36 mA,在低功耗模式下其功耗仅为2μA。 2 DMA和TIMx简介 STM32系列微控制器均含有DMA和通用时钟TIMx模块。其低端型号中仅包含DMA1,支持7个通道;高端型号还包括DMA2,支持5个通道。它的每个通道可任意指定工作模式,如内存到内存、内存到外设或外设到内存等。当
[单片机]
<font color='red'>STM32</font>中采用<font color='red'>DMA</font>实现方波的产生和捕获
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved