stm32 linux 串口,关于STM32 串口收发数据的常用方法和讨论。

博主分享了在实际项目中使用串口和DMA进行数据收发的经验,强调了基础理解的重要性。文中详细介绍了中断接收和发送的实现,并提出用DMA优化串口数据传输的思路。在中断处理和DMA应用中遇到关于串口空闲中断的触发时机以及DMA通道并发使用的困惑,期待讨论和解答。
摘要由CSDN通过智能技术生成

之所以想发这么个帖子,发现要想实际项目应用和学习玩玩有很大的区别,学习也是为了以后的实际项目应用。

所以越是基础的东西越需要透彻的理解,需要考虑到方方面面细节。在此,想和大家分享并讨论有关串口在实际项目应用时的做法和思路。欢迎拍砖~

ps:本人目前还没学习和接触过操作系统。全都是裸跑。

中断接收:接收完成中断里一个字节中断一次的收数据,每次接收中断里只把收到的一个字节放入一个环形队列里,主函数里再提取分析数据。遵循中断里尽量少做函数调用的原则。

[mw_shl_code=c,true]if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断

{

USART_ClearFlag(USART1, USART_FLAG_RXNE);

USART_ClearITPendingBit(USART1, USART_IT_RXNE);

Res =USART_ReceiveData(USART1);                //(USART3->DR);           //读取接收到的数据

if (((usart1Rx.rear+1)%RX_BUFFER_SIZE) != usart1Rx.front)//接收缓冲未满

{

usart1Rx.buf[usart1Rx.rear] = Res;

usart1Rx.rear              = (usart1Rx.rear+1)%RX_BUFFER_SIZE;

}

}[/mw_shl_code]

中断发送:发送空中断(TC),每发送一个字节,则中断一次传入下一个字节。

[mw_shl_code=c,true]if(USART_GetITStatus(USART1, USART_IT_TC) != RESET) //  发送空中断

{

if(usart1Tx.front != usart1Tx.rear)

{

USART_SendData(USART1,usart1Tx.buf[usart1Tx.front]);

usart1Tx.front=(usart1Tx.front+1)%TX_BUFFER_SIZE;

}

else

{

USART_ITConfig(USART1, USART_IT_TC, DISABLE);  //关闭发送空中断使能

}

}[/mw_shl_code]

以上是我平时写串口数据收发主要用的方法,暂时也没有出现过什么问题。

/

最近想到用DMA尝试串口数据的收发,毕竟DMA收发一帧数据才触发一次中断(当然你也可以不触发DMA接收通道中断,通过查询接收数组中是否有数据的方法)。

下面是我用DMA方式收发串口数据的程序思路:

[mw_shl_code=c,true]void USART1_IRQHandler(void)                        //串口1中断服务程序

{

u8 Res;

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

{

Res=USART1->SR;//先读SR,然后读DR才能清除

Res=USART1->DR;// 清除DR

Res=Res; // 防止编译器警告

receive.dmaRxCount =DMA_USART1_RxLEN - DMA1_Channel5->CNDTR;// 总的buf长度减去剩余buf长度,得到接收到数据的长度

receive.dmaRxCompleteFlag=true;   //主循环 receive函数里根据这个接收完成的标志来提取处理一帧数据

DMAUsartRxSetAddr();

USART_ClearITPendingBit(USART1, USART_IT_IDLE); // 清除空闲中断

}

if(USART_GetITStatus(USART1,USART_IT_TC)!= RESET) // 全部数据发送完成,产生该标记

{

USART_ClearITPendingBit(USART1, USART_IT_TC);   // 清除完成标记

DMA_Cmd(DMA1_Channel4, DISABLE); // 关闭DMA

DMA1_Channel4->CNDTR=0;          // 清除数据长度

}

}

[/mw_shl_code]

测下来基本能用,没发现什么异常。但是我有几点困惑的地方,也查了一些资料,没有找到具体说法。

困惑1:这个串口空闲中断,到底是多久没有字节进来则触发空闲中断。比如上位机串口传送5个字节的数据给单片机,正常情况下5个字节连续传完了,这个“完了”具体指多长时间?

如果上位机卡顿,发送5个字节的时候发到第三个字节卡了一会儿,则是不是会产生两次空闲中断,如果是的话,我上面这种程序则会出现问题,当我在主循环receive函数里根据接收完成的标志来提取处理一帧数据的时候,后半段数据又来了,就会覆盖掉前面刚收到的数据。

困惑2:DMA1 4 5两个通道可以同时进行吗?接收数据的同时DMA发送数据。

以上则是我对串口传输数据的一些理解和做法,欢迎大家拍砖讨论,有什么更好更加适合实际项目应用的方法帮忙指点一下。个人认为只有把基础的东西琢磨透了,才能走的更远一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值