希望有人能对我的无能有所了解。我已经为使用DMA中断的DMA传输设置了USART。
void DMA1_Channel7_IRQHandler(void)
{
// USART2 TX handler
/* Test on DMA Stream Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_IT_TC7))
{
/* Clear DMA Stream Transfer Complete interrupt pending bit */
DMA_ClearITPendingBit(DMA1_IT_GL7 | DMA1_IT_TC7);
}
DMA_Cmd(DMA1_Channel7, DISABLE);
}我正在尝试使用如下命令将数据发送到TX缓冲区:
SCICommsStringIntoTxQ("\n\rTEST_CODE V0.01: \r\n");命令的位置
void SCICommsStringIntoTxQ(int8_t * str_out_string)
{
memset(TxBuffer, '\0', sizeof(TxBuffer));
strcpy(TxBuffer, str_out_string);
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
DMA_Cmd ( DMA1_Channel7, ENABLE );
}我的DMA初始化是:-
/* Configures the DMA1 Channel7 for UART2_CHAN Transmission. */
DMA_DeInit(DMA_Channel_USART2_TX);
DMA7_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(USART2->DR);
DMA7_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA7_InitStructure.DMA_BufferSize = (uint16_t)sizeof(TxBuffer) -1;
DMA7_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer;
DMA7_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA7_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA7_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA7_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA7_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA7_InitStructure.DMA_Priority = DMA_Priority_High;
DMA7_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA_Channel_USART2_TX, &DMA7_InitStructure);
USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); // Enable USART2 DMA TX
DMA_ITConfig(DMA_Channel_USART2_TX, DMA_IT_TC, ENABLE);第一次发送可以正常工作,但是只要我尝试发送下一个字符串,它就会破坏我的第一次发送。有谁能指点我做错了什么吗?
发布于 2017-02-17 07:09:44
从您的代码中,我不能确定您是否在等待USART在发送第二个字符串之前完成发送您的第一条消息。
如果不是,并且TxBuffer为两个字符串指向相同的内存位置,则在第二次调用memset时,您将更改内存部分,而后者仍在发送前一个字符串。
编辑:回答你的问题,维基百科报道:
使用DMA时,中央处理器首先启动传输,然后在传输过程中执行其他操作,最后在操作完成时从
控制器接收中断。
这意味着当您通过USART总线开始传输时,DMA控制器从RAM获取数据,并将此数据提供给USART控制器,同时CPU可以执行其他操作。这意味着,在为USART控制器提供服务时,您的CPU可能会动态更改DMA控制器正在访问的RAM部分。
我不知道您的实现和硬件配置的具体细节,但我认为您应该在开始第二次传输之前检查USART或DMA控制器何时结束传输。如何做到这一点取决于您当前的配置。检查XE是否可以工作,或者您可以依赖于DMA结束传输时引发的中断。
例如,也许你可以在这个块中设置一个内部标志able_to_transmit:
/* Test on DMA Stream Transfer Complete interrupt */
if (DMA_GetITStatus(DMA1_IT_TC7)) {
able_to_transmit = 1;
}在传输之前做一些这样的事情:
while(!able_to_transmit)
; //wait or do something else
SCICommsStringIntoTxQ("\n\rTEST_CODE V0.01: \r\n");
able_to_transmit = 0;我希望这能帮到你。
发布于 2017-02-17 21:55:58
感谢您抽出时间来回复。我不是在检查或等待USART完成。我以为DMA已经处理好了。在将下一个字符串发送到DMA之前,我是否应该查看UART XE (传输数据空标志)?
https://stackoverflow.com/questions/42281603
复制相似问题