看了该芯片的例程,串口的DMA如何使用??
在AT32F403A的例程中,找到了USART文件下,关于DMA的有两个,在DMA_interrupt这个例程中,只有初始化的时候有一些DMA的操作,然后中断都是收到数据中断也没见有接着操作DMA的相关操作,在DMA_Polling例程中,我理解的意思是在/* Wait until USART3 RX DMA1 Channel Transfer Complete */while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET)
{
}
/* Check the received data with the send ones */
TransferStatus1 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2);初始化后就收到数据,然后放到RxBuffer1中,然后再判断收到的数据和TxBuffer2中的数据是否一样,我仿照例程使用串口1来收数据,但是我调试的时候,while是通过去了,加断点,查看RxBuffer1,这里根本就没有数据,希望大佬指点指点! 谢谢!
while能过,感觉串口是通了的,buffer没数据,你看一下dma配置的源地址和目的地址是否正确。 mark一江水 发表于 2021-5-6 10:02
while能过,感觉串口是通了的,buffer没数据,你看一下dma配置的源地址和目的地址是否正确。 ...
地址如图片,基本是仿照DMA_polling例程,就改了串口1,我用CH340和上位机连,通过了那个接收的while,但是rxbuff里面是没有数据的....
chenyuanjiyi 发表于 2021-5-6 10:43
地址如图片,基本是仿照DMA_polling例程,就改了串口1,我用CH340和上位机连,通过了那个接收的while,但 ...
串口1的基地址不对哦 本帖最后由 chenyuanjiyi 于 2021-5-6 17:17 编辑
mark一江水 发表于 2021-5-6 11:13
串口1的基地址不对哦
现在将基地址改成这个了(uint32_t)&USART1->DT,他这个基地址的在文档上也没看到具体对应什么地址啊?
另外我这样写的时候
TxBuffer1[] = "USART DMA Polling: USART2 -> USART3 using DMA\r\n";//这是我定义的数组
然后我想实现串口收到什么数据,发送什么数据,结果收到的 a123456789
串口发送的数据为 USART DMA Polling: Ua123456789if(done_flag)//收到数据
{
USART_SendBuff_DMA(USART1,DMA1_Channel4,RxBuffer1,RX_len);
memset(RxBuffer1,0,sizeof(RxBuffer1));
done_flag=0;
}这是刚开始出现 USART DMA Polling: Ua123456789 这个现象的代码,然后修改后
if(done_flag)//收到数据
{
<b><font color="#ff0000"> memset(TxBuffer1,0,sizeof(TxBuffer1));//清空TXbuff</font></b>
USART_SendBuff_DMA(USART1,DMA1_Channel4,RxBuffer1,RX_len);
memset(RxBuffer1,0,sizeof(RxBuffer1));
done_flag=0;
}清空下就可以实现收到什么数据,发送什么数据 a123456789
chenyuanjiyi 发表于 2021-5-6 17:02
现在将基地址改成这个了(uint32_t)&USART1->DT,他这个基地址的在文档上也没看到具体对应什么地址啊?
另 ...
基地址在文档第一章就有。你后面是说接收前有丢数据吗,要先使能接收dma再使能发送才行。 本帖最后由 chenyuanjiyi 于 2021-5-6 18:05 编辑
mark一江水 发表于 2021-5-6 17:24
基地址在文档第一章就有。你后面是说接收前有丢数据吗,要先使能接收dma再使能发送才行。 ...
发现那个问题根本原因了,我封装的那个USART_SendBuff_DMA函数中,将收到的数据给了USART->DT,然后又开启DMA的通道发送了。
现在改成这样了
void USART_SendBuff_DMA(USART_Type* USARTx,DMA_Channel_Type* DMA_CHx, uint8_t *buff, uint32_t size)
{
<font color="#ff0000"><b>memcpy(TxBuffer1,buff,size);</b></font>
DMA_ChannelEnable(DMA_CHx,DISABLE);//关闭USARTx TX DMA1 所指示的通道
DMA_SetCurrDataCounter(DMA_CHx,size);//DMA通道的DMA缓存的大小
DMA_ChannelEnable(DMA_CHx, ENABLE);//使能USARTx TX DMA1 所指示的通道
USART_DMACmd(USARTx,USART_DMAReq_Tx,ENABLE);//使能串口的DMA发送
while(1)
{
if( DMA_GetFlagStatus(DMA1_FLAG_TC4) != RESET)//传输完成
{
DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4传输完成标志
DMA_ChannelEnable(DMA1_Channel4, DISABLE);//传输完,要关闭DMA的通道
break;
}
}
} 感觉使用DMA还在死等传输完成,就失去了DMA的意义了。还是放在DMA完成中断里处理比较好。 admvip 发表于 2021-5-7 06:11
感觉使用DMA还在死等传输完成,就失去了DMA的意义了。还是放在DMA完成中断里处理比较好。 ...
那个等待是参考正点原子DMA标准库的实验例程写的,找到一个你说的关于DMA发送完成中断的介绍,到时去试试:https://blog.csdn.net/u010001130/article/details/77816020 感谢楼主的分享,不错的东东。 二楼正解,不错的帖子。 提供一个已经实际使用的DMA串口空闲驱动代码
串口及DMA初始化代码就不提供了,自行调通。
接收DMA设置为单次,不要用循环模式。
这个是串口空闲中断接收的回调函数
/*************************************
*函数名称:UART_DMARx_IDLECallback
*函数说明:串口DMA空闲中断数据处理函数
*入口参数:无
*
*返回参数:无
*************************************/
void UART_DMARx_IDLECallback(void)
{
#if RX_Enable
//串口DMA空闲中断数据处理
uint32_t temp;
DMA_ChannelEnable(DMA1_Channel4, DISABLE); //DMA通道禁止
temp = DMA_GetCurrDataCounter(DMA1_Channel4); //获取DMA剩余字节数
Rxbuffer_index = RX_Buffer_Size - temp; //计算接收到的数据数量
USART_Rx_OK = 1; //接收完成标志置位
#endif
}
在串口中断里的调用
void USART1_IRQHandler(void)
{
uint8_t clearTag;
if(USART_GetITStatus(USART1, USART_INT_IDLEF) != RESET)
{
// USART_ClearITPendingBit(USART1, USART_INT_IDLEF); //清除中断标志位
clearTag += USART1->DT; //读一次数据寄存器,作用是清除中断标志位
UART_DMARx_IDLECallback(); //串口DMA空闲中断回调函数
}
}
接收到的数据在用户程序里进行处理,处理完毕记得调用串口DMA接收恢复函数,恢复DMA接收
代码如下:
/*************************************
*函数名称:UART_DMARx_IDLEResume
*函数说明:串口DMA空闲中断数据处理完成
*后的DMA状态恢复函数
*入口参数:无
*
*返回参数:无
*************************************/
void UART_DMARx_IDLEResume(void)
{
memset(Rxbuffer, 0, RX_Buffer_Size); //清空接收缓冲区
Rxbuffer_index = 0; //接收缓冲区索引清零
USART_Rx_OK = 0; //接收完成标志清零
DMA_ChannelEnable(DMA1_Channel4, DISABLE); //DMA通道禁止
DMA_SetCurrDataCounter(DMA1_Channel4, RX_Buffer_Size); //重新设置DMA数据计数器参数
DMA_ChannelEnable(DMA1_Channel4, ENABLE); //DMA通道使能,开始空闲中断DMA传输
}
就这么多代码,就可以实现串口DMA空闲中断的数据接收,比较适合一帧一帧的数据传输。
chenyuanjiyi 发表于 2021-5-6 17:59
发现那个问题根本原因了,我封装的那个USART_SendBuff_DMA函数中,将收到的数据给了USART->DT,然后又开启 ...
您好,可以请教您一下关于雅特力MCU的问题吗
页:
[1]