|
楼主 |
发表于 2018-11-23 10:04:19
|
显示全部楼层
首先,对你的问题我有个疑问USART2->SR和uart_base->SR到底是不是指向同一个地址?
第二,刚刚在f103上面测试,DMA中断中加入等待不影响DMA的后续发送,代码在下面:
/*usart1 TX DMA handle*/
void DMA1_Channel4_IRQHandler(void)
{
if(RESET != DMA_GetITStatus(DMA1_IT_TC4))
{
while(0==(USART1->SR&USART_FLAG_TC));//**********这里加入等待(注意:实际工程中绝对不允许这么做)
DMA_ClearITPendingBit(DMA1_IT_TC4);
/*disable TC IT*/
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,DISABLE);
/*stop translation*/
DMA_Cmd(DMA1_Channel4,DISABLE);
}
}
第三,实际工程中绝对不允许在中断中做耗时的操作,更不要说等待外设
最后,你说的“DMA 意义在哪里”---------启动DMA之前肯定要看之前的操作是否已经完成,就跟写flash操作一样,write之后要等待操作完成。DMA的意义在于,假如你发1000个字节,那么你只需启动DMA就可以了,不需要你去往USART1->DR里面写入1000次数据,可以把节约的时间用来做别的操作。如果启动之前不检查上次的发送是否完成,而此时直接停掉DMA修改参数再次启动,那么前面发出去的数据就是不完整的,而我们不希望发生这种情况。
*************************************************************************
如果不希望等待,那么建议你这么做:
1.创建一个环形队列,
2.需要往串口打印数据的时候先写入队列里面,
3.真正发送的流程从队列获取数据启动DMA从USART发出去,
4.软件流程是这样:我要往串口打印数据---》先写入环形队列---》检查DMA是否正在用USART往外发送---》如果是则return。
|
\/
如果不是,则启动一次发送---》发送完成后进入USART的TC中断,中断中从队列获取数据再次启动发送。
|
|