In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.