之所以想发这么个帖子,发现要想实际项目应用和学习玩玩有很大的区别,学习也是为了以后的实际项目应用。
所以越是基础的东西越需要透彻的理解,需要考虑到方方面面细节。在此,想和大家分享并讨论有关串口在实际项目应用时的做法和思路。欢迎拍砖~
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发送数据。
以上则是我对串口传输数据的一些理解和做法,欢迎大家拍砖讨论,有什么更好更加适合实际项目应用的方法帮忙指点一下。个人认为只有把基础的东西琢磨透了,才能走的更远一些。