STM32_串口接收

实验平台:STM32F407ZGT6

1 RXNE中断

  • RXNE介绍如下图(来自STM32F4xx中文参考手册)
    RXNE

  • 由图可知,每接收到一位数据,便会生成一次中断,并通过读入操作清除中断标志。

  • 该方式一般用于数据量小且接收频率低的场合,通过检测帧尾或对RXNE中断次数计数来判断一帧数据是否接收完毕。

2 IDLE中断(空闲中断)

  • 针对没有帧尾且长度不固定的情况,可以通过IDLE中断来判断一帧数据是否接收完毕。
  • IDLE介绍如下图
    IDLE
  • 由图可知,当一帧数据接收完毕,线路将处于空闲状态,产生空闲中断,通过依次读取USART_SR和USART_DR清除中断标志。
void USART3_IRQHandler(void)
{	
	u8 clear;
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)	//RXNE中断,读取数据			
	{
		USART3_RX_BUF[USART3_RX_CNT] = USART_ReceiveData(USART3);
		USART3_RX_CNT++;
	}	
	if(USART_GetITStatus(USART3,USART_IT_IDLE) != RESET)	//IDLE中断,一帧数据接收完毕
    {
		clear = USART3->SR;
        clear = USART3->DR; //先读SR再读DR清除IDLE中断标志
        USART3_RX_STA = 1;	//数据接收完成标志
		USART3_RX_CNT = 0;
	}
}

3 DMA + 空闲中断

  • 针对数据量大或接收频率高的情况,采用DMA接收可以避免频繁进入中断影响系统性能。
  • DMA介绍如下图
    在这里插入图片描述
  • 由图可知,当发生RXNE中断,即接收到数据时,数据将直接加载到预先指定的存储地址,而不经过CPU处理。
  • 当产生空闲中断时,说明一帧数据接收完毕,此时只需对预先指定的存储地址内的数据进行处理或取出即可,此过程需要关闭DMA,避免数据被覆盖。
  • DMA请求映射参考STM32F4xx中文参考手册。
u8 USART3_RX_BUF[USART3_REC_LEN];	//接收缓冲

void uart3_init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); 	//使能GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);	//使能USART3时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);		//使能DMA1时钟
	
	//DMA配置,USART3_RX对应DMA1通道4数据流1
	DMA_DeInit(DMA1_Stream1);
	DMA_InitStructure.DMA_Channel = DMA_Channel_4;  						//通道选择
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART3->DR);			//DMA外设地址
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)USART3_RX_BUF;				//DMA存储器地址
	DMA_InitStructure.DMA_DIR =DMA_DIR_PeripheralToMemory ;					//外设到存储器模式
	DMA_InitStructure.DMA_BufferSize = USART3_REC_LEN;						//数据传输量 
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;		//外设非增量模式
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;					//存储器增量模式
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	//外设数据长度:8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;			//存储器数据长度:8位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;							//使用循环模式 
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;					//中优先级
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;				//存储器突发单次传输
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;		//外设突发单次传输
	DMA_Init(DMA1_Stream1, &DMA_InitStructure);								//初始化DMA Stream

	//USART3引脚复用映射
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3); 	//GPIOB10复用为USART3TX
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3); 	//GPIOB11复用为USART3RX

	//USART3端口配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;				//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;			//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 				//推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 				//上拉
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//USART3初始化设置
	USART_InitStructure.USART_BaudRate = bound;										//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;						//字长为8位数据格式
	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;					//收发模式
	USART_Init(USART3, &USART_InitStructure);

	//USART3 NVIC配置
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;			//串口3中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;		//抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;			//子优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);								//根据指定的参数初始化VIC寄存器
	
	USART_Cmd(USART3, ENABLE);  								//使能串口3
	USART_ClearFlag(USART3, USART_FLAG_TC);						//清除标志位
	USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);				//开启空闲中断
	DMA_Cmd(DMA1_Stream1,ENABLE);   							//驱动DMA传输
	USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);   				//使能串口3 DMA接收	
}

void USART3_IRQHandler(void)
{
	unsigned char num;
	if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)	//IDLE中断,一帧数据接收完毕
	{
		DMA_Cmd(DMA1_Stream1,DISABLE);	//关闭DMA
		num = USART3->SR;
		num = USART3->DR; 				//先读SR再读DR,清USART_IT_IDLE标志
		num = USART3_REC_LEN - DMA_GetCurrDataCounter(DMA1_Stream1);	//获得数据长度
		
		//******此处添加数据处理函数或添加接收数据接收完成标志******//
		
		DMA_SetCurrDataCounter(DMA1_Stream1,USART3_REC_LEN);			//重置数据接收个数		
		DMA_Cmd(DMA1_Stream1,ENABLE);	//开启DMA				
	} 
}
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: DMX512是一种常用于舞台灯光控制的数字通信协议。而STM32是意法半导体(STMicroelectronics)推出的一系列微控制器,具有高性能和低功耗的特点。STM32的DMA(Direct Memory Access)是一种直接内存访问技术,可以实现高效的数据传输。 "dmx512通过stm32_dma方式接收解码.rar" 这个压缩文件中应该包含有关如何在STM32微控制器上使用DMA接收和解码DMX512信号的代码和工程文件。 在实际项目中,通过STM32的DMA方式接收和解码DMX512信号有以下几个步骤: 1. 硬件连接:将DMX512信号接收器与STM32微控制器连接,通常通过串行通信接口(USART)实现。确保连接正确无误。 2. 配置DMA:使用STM32提供的DMA控制器和相关寄存器,配置DMA通道,设置数据传输方向和传输长度,为DMX512信号接收准备DMA。 3. 配置串行通信接口(USART):配置串行通信接口的参数,如波特率和数据帧格式。确定USART与DMA之间的传输关系。 4. 编写中断服务程序:通过编写中断服务程序,处理DMA传输完成的中断事件。在中断服务程序中,可以读取接收到的DMX512数据,完成解码操作。 5. 调试和测试:在完成代码编写后,进行调试和测试。可以通过连接外部DMX512信号源,查看接收到的数据是否正确解码,并进行灯光控制测试。 通过以上步骤,我们可以利用STM32的DMA功能来实现对DMX512信号的接收和解码,从而实现对舞台灯光等设备的控制。这种方式可以提高数据传输的效率和可靠性,使得控制系统更加稳定和可靠。 ### 回答2: DMX512是一种常用于舞台灯光控制的数字通信协议,而STM32是一款常用的微控制器。STM32_DMA作为STM32的外设之一,可以实现高效的数据传输和处理。 在使用STM32_DMA方式接收和解码DMX512的过程中,我们可以通过以下步骤进行操作: 1. 首先,我们需要配置STM32的串口外设和DMA。通过设置串口的波特率、数据位数等参数,并配置DMA通道的传输方向和内存地址。 2. 接下来,我们可以使用STM32中的中断机制来触发DMA传输和接收DMX512数据。当DMX512信号的帧头出现时,我们可以设置DMA传输的触发方式,使得DMA能够将数据流传输到指定的存储器位置。 3. 一旦DMX512数据传输完成,我们可以使用STM32中的中断机制或轮询的方式来读取并解码数据。通过解码DMX512数据包,我们可以获取到各个通道上的亮度值或其他控制参数。 通过使用STM32_DMA方式接收解码DMX512信号,我们可以实现高效、快速的数据传输和处理,同时保证了舞台灯光控制的稳定性和准确性。 需要注意的是,DMX512协议的传输速率为250kbps,因此在实际应用中,我们需要根据数据包的长度和传输速率来设计和调整DMA的设置,以确保数据的准确传输和解码。同时,为了提高系统的稳定性和适应性,我们还可以结合其他外设或算法进行数据校验和容错处理。 ### 回答3: dmx512是一种数字控制协议,常用于舞台灯光设备的控制中。而STM32是一系列由STMicroelectronics生产的32位单片机微控制器,它具有强大的性能和丰富的外设资源,非常适合用于开发各种嵌入式系统。 在dmx512协议中,数据是以均衡的差分信号的形式传输的。因此,我们需要在STM32上设置一种能够接收并解码差分信号的方式。而DMA(直接存储器访问)是一种数据传输方式,它可以通过硬件方式在外设和内存之间直接进行数据传输,大大降低了CPU的负担。 即通过将dmx512数据接收到的差分信号传递给STM32的DMA控制器,再通过STM32的DMA方式将数据传输到内存中,最后通过解码操作将数据还原成可以识别的格式。 在文件“dmx512通过stm32_dma方式接收解码.rar”中,我们可以找到一种使用STM32的DMA方式接收并解码dmx512的代码实现。该文件中可能包含有关如何配置STM32的DMA控制器以及如何运行程序的文档,以帮助开发者理解并使用该方法。 通过使用该文件中的代码实现,我们可以在STM32上轻松地接收和解码dmx512信号,并且无需过多的CPU资源就能完成这项任务。这种方法可以提高系统的性能,并且更加稳定可靠,适用于各种需要dmx512控制的应用场景,如舞台灯光、演出控制等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

研溪南

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值