Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use DMA+FIFO in stm32f103 Serial Port

2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces you how to use stm32f103 serial port DMA+FIFO, the content is very detailed, interested friends can refer to, hope to be helpful to you.

If stm32f103 uses an ordinary serial port receiver, the baud rate is set to 115200. Because it takes up CPU resources when reading, the actual rate is very slow. However, if DMA is used to process, the speed is very fast. When the baud rate is 115200, and the queue is used, the speed can reach more than 10k. Of course, the actual situation may be different. I am used to receive the firmware sent by the host computer, and then when the length of the data read from FIFO is 1024 bytes, I have to write to FLASH. Of course, at this time, if the FIFO is greater than 1024 bytes, DMA will continue to read the data received from the serial port and store it to FIFO.

1.DMA queue

/ *

* File: [fifo.h]

, /

# include "stm32f10x.h"

# define RINGQ_MAX 10000 / / queue size

Typedef struct

{

U32 OldLen

U32 NewLen

U32 TotalLen; / / data length

U8 * BaseAddr; / / buffer base address

U8 * EndAddr; / / buffer tail address

U8 * ReadAddr; / / data read address

} LinkQueue

Int InitQueue (LinkQueue * Q, U8 * bufbase, U32 size)

Int GetLength (LinkQueue * Q)

Int EnQueue (LinkQueue * Q)

Int OutQueue (LinkQueue * Q, unsigned char * buf, int len)

/ *

* File: [fifo.c]

, /

# include "fifo.h"

# include "usart.h"

/ *

* initialize the queue

, /

Int InitQueue (LinkQueue * Q, U8 * bufbase, U32 size)

{

Q-> BaseAddr = bufbase

Q-> EndAddr = bufbase + RINGQ_MAX

Q-> ReadAddr = bufbase

Q-> NewLen = 0

Q-> OldLen = 0

Q-> TotalLen = 0

Return 0

}

/ *

* get the number of bytes transferred in DMA

, /

Int GetLength (LinkQueue * Q)

{

Q-> NewLen = RINGQ_MAX-DMA_GetCurrDataCounter (DMA1_Channel3)

Return 0

}

/ *

* queued

, /

Int EnQueue (LinkQueue * Q)

{

If (Q-> NewLen > Q-> OldLen)

{

/ / under normal circumstances

Q-> TotalLen + = (Q-> NewLen-Q-> OldLen)

}

Else

{

If (Q-> NewLen)

< Q->

OldLen)

{

/ / DMA starts counting from scratch

Q-> TotalLen + = (Q-> NewLen + RINGQ_MAX-Q-> OldLen)

If (Q-> TotalLen > RINGQ_MAX)

{

Return 1; / / overflow

}

}

}

Q-> OldLen = Q-> NewLen

Return 0

}

/ *

* out of queue

, /

Int OutQueue (LinkQueue * Q, unsigned char * buf, int len)

{

U32 i

If (Q-> TotalLen > 0)

{

If (len > Q-> TotalLen)

{

/ / the number of requests is greater than the number of readable

Len = Q-> TotalLen

}

/ / Q-> TotalLen-= len

For (I = 0; I)

< len; i++) { buf[i] = *(Q->

ReadAddr++)

Q-> TotalLen--

If (Q-> TotalLen = = 0)

{

While (0)

}

If (Q-> ReadAddr = = Q-> EndAddr)

{

/ / read to the end of the buffer and return the base address

Q-> ReadAddr = Q-> BaseAddr

}

}

}

Else

{

Len = 0

}

Return len

}

2. DMA serial port configuration program

/ *

* File: [usart.c]

, /

# include "stm32f10x.h"

# include "usart.h"

# include "fifo.h"

# define USART3_DR_Base 0x40013804

U8 TxBuffer1 [RINGQ _ MAX]; / / send buffer

U8 RxBuffer1 [RINGQ _ MAX]; / / receive buffer

Void DMA_Configuration (void)

{

DMA_InitTypeDef DMA_InitStructure

/ * DMA1 Channel4 (triggered by USART3 Tx event) Config * /

DMA_DeInit (DMA1_Channel2)

DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) TxBuffer1

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST

DMA_InitStructure.DMA_BufferSize = 0

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable

DMA_Init (DMA1_Channel2, & DMA_InitStructure)

DMA_DeInit (DMA1_Channel3)

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) (& USART3- > DR)

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) RxBuffer1

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC

DMA_InitStructure.DMA_BufferSize = RINGQ_MAX

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable

DMA_Init (DMA1_Channel3, & DMA_InitStructure)

}

Void DMA_Send (unsigned char * buf,int len)

{

DMA_InitTypeDef DMA_InitStructure

/ * DMA1 Channel4 (triggered by USART3 Tx event) Config * /

DMA_DeInit (DMA1_Channel2)

DMA_InitStructure.DMA_PeripheralBaseAddr = USART3_DR_Base

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) buf

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST

DMA_InitStructure.DMA_BufferSize = len

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable

DMA_Init (DMA1_Channel2, & DMA_InitStructure)

/ / while (DMA_GetFlagStatus (DMA1_FLAG_TC4) = = RESET) {} / / wait for the transmission to be completed

DMA_ClearFlag (DMA1_FLAG_TC2); / / function

DMA_Cmd (DMA1_Channel2, DISABLE)

DMA1_Channel2- > CNDTR=len; / / DMA1, amount of data transferred

DMA_Cmd (DMA1_Channel2, ENABLE)

DMA_ClearITPendingBit (DMA1_IT_TC2)

DMA_Cmd (DMA1_Channel2, ENABLE)

}

/ *

USART3 initializes baud baud rate

* /

Void USART3_Init (unsigned int baud)

{

USART_InitTypeDef USART_InitStructure

USART_InitStructure.USART_BaudRate = baud

USART_InitStructure.USART_WordLength = USART_WordLength_8b

USART_InitStructure.USART_StopBits = USART_StopBits_1

USART_InitStructure.USART_Parity = USART_Parity_No

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx

USART_Init (USART3, & USART_InitStructure)

USART_ITConfig (USART3, USART_IT_RXNE, ENABLE)

/ * Enable USART3 DMA Rx and TX request * /

USART_DMACmd (USART3, USART_DMAReq_Tx, ENABLE)

USART_DMACmd (USART3, USART_DMAReq_Rx, ENABLE)

USART_Cmd (USART3, ENABLE)

/ * Enable DMA1 Channel4 * /

DMA_Cmd (DMA1_Channel2, ENABLE)

DMA_Cmd (DMA1_Channel3, ENABLE)

}

On the stm32f103 serial port how to use DMA+FIFO to share here, I hope the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report