Skip to main content
mk61
Associate II
March 31, 2017
Question

STM32F407VG using USART with DMA

  • March 31, 2017
  • 7 replies
  • 2207 views
Posted on March 31, 2017 at 07:13

Hi everyone,

I wanted to move a data array(source) to another data array(destination) using USART2 and I wanted to move datas to usart2 and from usart2 by using DMA1. I connect the tx pin to rx pin and it worked. The thing confused me is when I disconnected pins somehow some of the datas were able to go to destination array.

My code is below. Can you explain me what is going on? 

&sharpinclude <stm32f4xx.h>

int sayac = 0;

int main()

{

USART_InitTypeDef USART_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

uint8_t source[500] = 'Hello World

Hello World Hello World Hello World Hello World Hello WorldHello WorldHello WorldHello World Hello World Hello World Hello WorldHello WorldHello WorldHello WorldHello World Hello World Hello World Hello World Hello World Hello World etc..

';

uint8_t destination[500] = {0};

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);

//GPIO Initialisation for USART

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_Init(GPIOD,&GPIO_InitStructure);

GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_USART2);

GPIO_PinAFConfig(GPIOD,GPIO_PinSource6,GPIO_AF_USART2);

//USART Initialisation

USART_InitStructure.USART_BaudRate = 9600;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_Init(USART2,&USART_InitStructure);

USART_Cmd(USART2,ENABLE);

//DMA Stream6 Initialisation for USART Tx

DMA_DeInit(DMA1_Stream6);

while(DMA_GetCmdStatus(DMA1_Stream6) != DISABLE);

DMA_InitStructure.DMA_Channel = DMA_Channel_4; //channel of the stream

DMA_InitStructure.DMA_Priority = DMA_Priority_High; //select priority of the stream

DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)source; //address of source

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; //address of peripheral

DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //Direction of the transfer

DMA_InitStructure.DMA_BufferSize = sizeof(source); //amount of data to be sent

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Enable incremantation of memory address

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Disable incremantation of peripheral address

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //verinin boyutu

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //verinin boyutu

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //Stream is disabled when Transfer finishes

DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //Fifo disable oldugu i�in �ok �nemli degil

DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //minumum burst miktar1 yaz1lmazsa olmuyor

DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //minumum burst miktar1 yaz1lmazsa olmuyor

DMA_Init(DMA1_Stream6,&DMA_InitStructure);

//DMA Stream5 Initialisation for USART Rx

DMA_DeInit(DMA1_Stream5);

while(DMA_GetCmdStatus(DMA1_Stream5) != DISABLE);

DMA_InitStructure.DMA_Channel = DMA_Channel_4; //channel of the stream

DMA_InitStructure.DMA_Priority = DMA_Priority_High; //select priority of the stream

DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)destination; //address of source

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; //address of peripheral

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; //Direction of the transfer

DMA_InitStructure.DMA_BufferSize = sizeof(destination); //amount of data to be sent

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //Enable incremantation of memory address

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //Disable incremantation of peripheral address

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //verinin boyutu

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //verinin boyutu

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //Stream is disabled when Transfer finishes

DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;

DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; //Fifo disable oldugu i�in �ok �nemli degil

DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; //minumum burst miktar1 yaz1lmazsa olmuyor

DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //minumum burst miktar1 yaz1lmazsa olmuyor

DMA_Init(DMA1_Stream5,&DMA_InitStructure);

USART_ClearFlag(USART2,USART_FLAG_RXNE);

USART_ClearFlag(USART2,USART_FLAG_TXE);

USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);

USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);

DMA_Cmd(DMA1_Stream6,ENABLE);

DMA_Cmd(DMA1_Stream5,ENABLE);

while(1)

{

}

}

#stm32f407vg-using-usart-with-dma*
This topic has been closed for replies.

7 replies

Tesla DeLorean
Guru
March 31, 2017
Posted on March 31, 2017 at 08:30

>>Can you explain me what is going on? 

Not really. Make sure your stack is large enough to contain the arrays, or use statics.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
krishna K H
Associate II
March 31, 2017
Posted on March 31, 2017 at 08:40

hi K.M....

You receivi the data  from DMA method ,after the receiving data clear DMA DR regester

Tesla DeLorean
Guru
March 31, 2017
Posted on March 31, 2017 at 12:53

It is not a memory cell,  the peripherals has two different registers at the same address,  but the one being written is not the same one that is being read. Look at a functional diagram in the reference manual. 

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
mk61
mk61Author
Associate II
March 31, 2017
Posted on March 31, 2017 at 14:23

I got it now. Thank you.

mk61
mk61Author
Associate II
March 31, 2017
Posted on March 31, 2017 at 09:37

I suspect it si something with USART_DR.  USART have one register for Transmit and recieve. Dma is writing datas from memory to this register to transmit and reading recieved datas from this register to  another memory place.  I don't understand how does usart handle full duplex  transfer like my example with only one register.

krishna K H
Associate II
March 31, 2017
Posted on March 31, 2017 at 10:01

Method 1 : usart normal method it works on only one register USART_DR register...

Method 2 :your using in DMA  it works on DMA USART Tx and Rx DR Registers 

mk61
mk61Author
Associate II
March 31, 2017
Posted on March 31, 2017 at 09:55

To make it clear.

Usart2 Tx connected to USART2 Rx(array size 500)0690X00000606fJQAQ.png

Usart2 Tx is not connected to USART2 Rx(array size 500)

0690X00000606WrQAI.png

Usart2 Tx is not connected to USART2 Rx

(array size 250)

0690X00000606fYQAQ.png
waclawek.jan
Super User
March 31, 2017
Posted on March 31, 2017 at 10:19

Try to switch on the pullup on the Rx pin.

JW

mk61
mk61Author
Associate II
March 31, 2017
Posted on March 31, 2017 at 10:29

Wow. It worked. What is the difference?

waclawek.jan
Super User
March 31, 2017
Posted on March 31, 2017 at 10:31

You were 'receiving' through some parasitic (capacitive?) coupling between Tx and Rx.

JW

mk61
mk61Author
Associate II
March 31, 2017
Posted on March 31, 2017 at 10:36

Thank you very much. I woukdn't guess that.  I was thinkin there is one register for both transmit and recieve  thats why DMA is somehow taking the data it's just wrote.

Thank you again.