简体   繁体   中英

DMA USART Tx using stm32f407xx as terminal log

I was trying to send 2 different strings on the same global array with the DMA to be transmitted via UART to act as a terminal log for me. However what happens is that it sends the first string, and no matter what i try (re initializing the whole DMA and the UART all over again, it only sends the first string. I want it to transmit 1 time any string whenever I write to the global array

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);  
 }

please note: I already wrote these in functions. However I was trying to use the While (1) to tackle where the problem is, yet I couldn't find it. The code is a bit messy as I was trying to desperately trigger several bits on the hope that it might work.

It is hard to tell where the problem is without debugging, but:

  1. while(!(USART2->SR) & (USART_SR_TC)) is incorrect. It first logically inverts SR and only then applies the bitwise AND.
  2. When using peripherals with DMA, do not check peripheral's status registers, but check DMA completion status. While DMA is running, peripheral status may change arbitrarily. Once DMA completes, you can check peripherals for errors, etc, as needed.
  3. You enable DMA for both transmission and reception on the UART, but the code only initializes a DMA channel for transmission. Try debugging without setting DMAR first.
  4. It is really hard to tell what (1U<<5)|(1U<<9)|(1U<<11)|(1U<<13)|(1U<<15)|(1u<<21) means.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM