stm32 串口2空闲中断死机_STM32的串口空闲中断及接受数据

本文详细介绍了STM32的串口空闲中断及其在数据接收中的应用。通过空闲中断,可以检测到数据帧间的空闲状态,实现数据的高效接收。文章还探讨了如何清除中断以及使用DMA进行串口数据传输,特别强调了在空闲中断触发后,如何通过DMA处理接收的数据并避免数据丢失或冲突。
摘要由CSDN通过智能技术生成

STM32的串口空闲中断及接受数据——STM32简介

STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核

STM32的串口空闲中断及接受数据——关于什么是空闲中断:

检测到接收数据后,在数据总线上的一个字节时间内,没有接收到数据触发空闲中断。RXNE置位一次,空闲总线就检测一次。

关于STM32串口空闲中断的问题

1.空闲中断是接受数据后出现一个byte的高电平(空闲)状态,就会触发空闲中断。并不是空闲就会一直中断,准确的说应该是上升沿(停止位)后一个byte,如果一直是低电平是不会触发空闲中断的(会触发break中断)。

2.关于第二点有要铺垫的三个情况,datasheet中

“当一空闲帧被检测到时,其处理步骤和接收到普通数据帧一样,但如果IDLEIE位被设置将产生一个中断”

“空闲符号被视为完全由‘1’组成的一个完整的数据帧,后面跟着包含了数据的下一帧的开始位‘1’的位数也包括了停止位的位数” 空闲符号的配图后面跟这一个低电平。

有人理解为只有收到下一个数据的起始位才会触发中断,这样理解是不对的,应该是数据后有空闲了一帧就会触发。

3.清中断的方式感觉奇怪,使用函数USART_ClearITPendingBit( USART1, USART_IT_IDLE )清除不了中断的。我用的是3.5的库,查看函数说明,里面的@param参数并没有IDLE,后面的@note中,这样说:

”PE(Parity error),FE(Framing error),NE(Noise error),ORE(OverRun error) and IDLE(Idle line detected) pending bits are cleared by software sequence: a read operation to USART_SR register (USART_GetITStatus()) followed by a read operation to USART_DR register (USART_ReceiveData())。“

我是通过语句”USART1-》DR;“来清除IDLE中断的。

关于STM32的串口空闲中断及接受数据——解析

整体的思路

一开始设置好DMA接收,可以把缓冲区长度设置为帧最大长度,我们可以把RX连接到定时器的管脚输入端,并且一开始设置输入并且使能引脚下降沿中断,当帧的第一个字节发送时,因为起始位为低电平,空闲时UART为高电平,满足条件,进入中断,禁止中断,并且在中断中开启定时器,该定时器工作在复位模式,上升沿复位,并且设置好定时器输出比较值为超时时间,比如20ms,这样,在传输后面字节时,肯定会有高低电平出现,即便是传输的是0x00,0xFF,虽然UART数据区不变,但是都为1,或都为0,但是因为起始位为低电平,停止位是高电平,所以肯定会有上升沿,定时器会一直复位,输出定时器的计数器一直到达不了输出比较值,当一帧传输结束后,定时在最后一个字节复位后,由于没有数据继续到达,无法复位,则计数器就能计到输出比较值,这时发出中断,在定时器中断中可以计算出接收数据的长度,并且通知外部数据已经接收完毕。)

另一种USART DMA接收未知数据长度的接收,使用的是USRAT空闲总线中断接收,这种方法也在网站上比较多见,使用DMA发送USART数据替代了以前的查询法发送,其速度快了很多,尤其是在大量数据传输与发送的时候其优势更加明显。

举个例子:

1、后台数据-》USART1-》 USART2-》其它设备,其它设备数据-》USART2-》 USART1-》后台,这两个数据过程也可能同时进行。

2、由于硬件的限制,USART1和USART2的传输波特率不一样,比如USART1使用GPRS通信,USART2使用短距离无线通信;或者USART1使用以太网通信,USART2使用485总线通信。

现在我把我实现的过程简单描述一下:

1、 初始化设置:USART1_RX DMA1_ Channel5,USART2_RX DMA1_ Channel6,USART1_TX DMA1_ Channel4,USART2_TX DMA1_ Channel7(具体设置请看程序包)

2、 当数据发送给USART1接收完毕时候会引起USART1的串口总线中断,计算DMA1_ Channel5内存数组剩余容量,得到接收的字符长度。将接收的字符给DMA1_ Channel4内存数组,启动DMA1_ Channel4通道传输数据,(传输完成需要关闭。)下一次数据接收可以在启动DMA1_ Channel4时候就开始,不需要等待DMA1_ Channel4数据传输完成。但是上一次DMA1_ Channel4完成之前,不可以将数据给DMA1_ Channel4内存数组,会冲掉以前数据。

3、 USART2类同USART1。

#p##e#

源程序:

IO口定义:

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* 第1步:打开GPIO和USART部件的时钟 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* 第2步:将USART Tx的GPIO配置为推挽复用模式 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 第3步:将USART Rx的GPIO配置为浮空输入模式

由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的

但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 第1步:打开GPIO和USART2部件的时钟 */

//RCC_APB2PeriphClockCmd(RCC_APB2Per

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值