STM32L4-RS485+DMA中断通信实验+字节丢失处理[寄存器版]

文章介绍了STM32L4单片机通过DMA进行RS485通信的过程,遇到数据丢失问题的原因在于DMA传输完成中断导致串口未发送完数据就切换到接收状态。提供了两种解决方案:在DMA中断中加入串口TC标志检测,或改用串口中断处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本设置

MCU采用:STM32L431RCT6

485芯片采用:ADM3485

采用串口经由RS485,使用DMA向串口调试助手传送数据。

相关配置与前文基本相同:

STM32L4-双路RS485自收发通信实验[寄存器版]_staypt的博客-CSDN博客

DMA相关配置可参考:

STM32-DMA传输实验(寄存器版)_dma的cr寄存器_staypt的博客-CSDN博客

在485的串口配置函数中将DMA收发开启,由于DMA不经过处理器,将串口的中断关闭:

SET_BIT(USARTX->CR3,USART_CR3_DMAR);//开启DMA接收通道
SET_BIT(USARTX->CR3,USART_CR3_DMAT);//开启DMA发送通道

配置DMA函数

void DMA_init(void)
{
	//TX发送
	DMA1_CSELR->CSELR=0;//清除通道配置寄存器
	DMA1_CSELR->CSELR |= (0X2<<4);//配置DMA通道2为usart3_TX
	
	CLEAR_BIT(DMA1_Channel2->CCR,DMA_CCR_EN);//清除使能
	DMA1_Channel2->CCR = 0;//初始化
	
  DMA1_Channel2->CPAR = (uint32_t) & (USART3->TDR);//外设地址设置为数据寄存器TDR
	DMA1_Channel2->CMAR = (uint32_t) & (TX_buf[0]);//储存器地址设置为内部flash
	DMA1_Channel2->CNDTR= 7;//传输的字节数
	SET_BIT(DMA1_Channel2->CCR,DMA_CCR_PL);//通道优先级
	SET_BIT(DMA1_Channel2->CCR,DMA_CCR_DIR);//方向,储存器到外设
	SET_BIT(DMA1_Channel2->CCR,DMA_CCR_MINC);//内存地址增量模式
	SET_BIT(DMA1_Channel2->CCR,DMA_CCR_TCIE);//配置传输完成中断
	RE_DE_TX3;//485发送模式
	NVIC_SetPriority(DMA1_Channel2_IRQn,0);
	NVIC_EnableIRQ(DMA1_Channel2_IRQn);
  SET_BIT(DMA1_Channel2->CCR,DMA_CCR_EN);//开启DMA通道 
}

通道映射

根据L4芯片手册,L4的DMA通道有固定对应的外设请求映射:

外设的映射配置在DMA的CSELR寄存器中: 

因此,根据手册,应当在CSELR中配置USART3-TX对应的channel2通道映射:

	DMA1_CSELR->CSELR=0;//清除通道配置寄存器
	DMA1_CSELR->CSELR |= (0X2<<4);//配置DMA通道2为usart3_TX

配置DMA中断

由于本次DMA串口通信使用了RS485接口,因此为了切换RS485的收发状态,这里采用DMA中断的方式,配置DMA的发送完成中断,在中断里切换485收发状态:

SET_BIT(DMA1_Channel2->CCR,DMA_CCR_TCIE);//配置传输完成中断
NVIC_SetPriority(DMA1_Channel2_IRQn,0);
NVIC_EnableIRQ(DMA1_Channel2_IRQn);

中断函数配置

当DMA传输完成中断之后,将485切换回接收状态,同时清除中断标志位

//DMA传输完成中断函数
void 	DMA1_Channel2_IRQHandler(void)
{

	if(READ_BIT(DMA1->ISR,DMA_ISR_TCIF2))//检测TC完成中断标志位
	{
		RE_DE_RX3;//传输完成后配置为输入模式
		SET_BIT(DMA1->IFCR,DMA_IFCR_CTCIF2);//清除标志位
//		CLEAR_BIT(DMA1_Channel2->CCR, DMA_CCR_EN);//关闭dma通道
	}
}

主函数配置

在主函数中开启485串口,DMA,设置预先需要DMA传输的数组字节,分别传输两次,一次为五字节,一次为7字节数据:

uint8_t TX_buf[7]={0X05,0x02,0x03,0x01,0x04,0x07,0x08};//发送缓冲储存

实验结果:

可以发现通过串口调试助手接收到的两次数据均丢失了2个字节,然而DMA和串口传输的数据是正常的。

字节丢失原因及分析

查询L4芯片手册的USART中DMA相关章节可以发现:

 当DMA已经将frame3传输完成的时候,在TX line上才出现frame2的时序,而配置DMA的传输完成中断,在DMA传输完成的时候,485就将收发配制成接收状态,因此就丢失了后续TX线未发送完成的数据。

解决方法

1.依旧使用DMA传输完成中断,在检测到DMA传输完成标志位后,判断串口的传输完成标志位TC,当串口传输完成之后,再进行485的收发态切换,同时清除相应标志位。

2.不使用DMA的中断,使用串口中断,在串口中断函数中检测串口传输完成位TC,同时清除DMA传输完成中断,并切换485收发态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值