C语言 DMA USART Tx使用stm32f407xx作为终端日志



我试图在同一个全局数组上发送 2 个不同的字符串,DMA 通过 UART 传输,作为我的终端日志。但是,发生的情况是它发送第一个字符串,无论我尝试什么(重新初始化整个DMA和UART),它只发送第一个字符串。我希望每当我写入全局数组时,它都会传输 1 次任何字符串

char result2[100];
char result[100];
void UART2INIT(void)
{

  RCC->APB1ENR|=RCC_APB1ENR_USART2EN;
  RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;
  GPIOA->MODER|=((2U<<4)|(2U<<6));  
  GPIOA->AFR[0]=0x7777;
  USART2->CR1|=(1U << 13) | (1U<<5);
  // USART2->CR1|=USART_CR1_M; //IF YOU NEED TO TURN IT ON TO SELECT ANOTHER WORD LENGTH
  USART2->CR2 &=~ (1U << 13);
// CR2 IS MAINLY USED IN CASE IF YOU WANTED TO USE UART AS UNIVERSAL SYNCHRONOUS, THUS IT IS NOT WEIRD YOU CAN FIND POLARITY AND PHASE SETTINGS BY     WHICH YOU CAN SET IT UP
 /*
   The baud rate is computed using the following formula:
    - IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (USART_InitStruct->USART_BaudRate)))
- FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 8 * (OVR8+1)) + 0.5 
   Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */

  USART2->BRR=((42*1000000)/19200)+0.5;
  USART2->CR1|=USART_CR1_TCIE|USART_CR1_RXNEIE; //enabling exceptions mask
  USART2->CR3|=USART_CR3_DMAT;
  USART2->CR3|=USART_CR3_DMAR;
  USART2->CR1|=(1U<<2)|(1U<<3); 
  while(!(USART2->SR) & (USART_SR_TC));
}



void DMA_UART_INIT(void)
{
  RCC->AHB1ENR|=RCC_AHB1ENR_DMA1EN;
  DMA1_Stream6->CR=0;
  while(DMA1_Stream6->CR);
  DMA1->LISR=0;
  DMA1->HISR=0;
  DMA1_Stream6->M0AR= (uint32_t) &result;
  DMA1_Stream6->PAR=0x40004404;
  DMA1_Stream6->NDTR=100; //x items
  DMA1_Stream6->CR&=~((1U<<5)|(1U<<9)|(1U<<11)|(1U<<13)|(1U<<15)|(1u<<21));  
  DMA1_Stream6->CR|=(1u<<4)| (1u<<6)|(1u<<10)|(2u<<16)|(4u<<25)|(1U<<1);
  USART2->SR&=~(1U<<6); 
  DMA1_Stream6->CR&=~(1u<<0);   

}   
while (1)
{
strcpy(result,"testing DMA");
DMA1_Stream6->CR|=(1u<<0);
Delay(0XFFFFFf);  
DMA1_Stream6->CR &= ~(1u<<0);
DMA1->HIFCR &=~ (DMA_HIFCR_CHTIF6 |   DMA_HIFCR_CTCIF6 | DMA_HIFCR_CFEIF6);
while(!(USART2->SR) & (USART_SR_TC));  
strcpy(result2,"TESTING DMA");
DMA_UART_RESET();
UART2INIT();
DMA_UART_INIT();
DMA1_Stream6->M0AR= (uint32_t) &result2;
DMA1_Stream6->NDTR=100;  
DMA1_Stream6->CR|=(1u<<0);

Delay(0XFFFFFf);  
 }

请注意:我已经在函数中写了这些。但是,我试图使用 While (1) 来解决问题所在,但我找不到它。代码有点混乱,因为我试图拼命触发几个位,希望它可以工作。

如果不进行调试,很难说出问题出在哪里,但是:

  1. while(!(USART2->SR) & (USART_SR_TC))不正确。它首先在逻辑上反转SR然后才应用按位 AND。
  2. 将外设与 DMA 配合使用时,请勿检查外设的状态寄存器,而应检查 DMA 完成状态。DMA 运行时,外设状态可能会任意更改。DMA 完成后,您可以根据需要检查外围设备是否存在错误等。
  3. 您可以为 UART 上的传输和接收启用 DMA,但代码仅初始化用于传输的 DMA 通道。尝试调试,而不先设置DMAR
  4. 真的很难说(1U<<5)|(1U<<9)|(1U<<11)|(1U<<13)|(1U<<15)|(1u<<21)是什么意思。