Three kinds of serial ports accept variable length data method

Method 1: The serial port accepts data. The timer determines whether the timeout will accept the data.

Method 2: DMA Accepts + IDLE Interrupts

Implementation ideas: Adopt serial port 1 of STM32F103, and configure idle interrupt IDLE mode and enable DMA receiving, and set receiving buffer and initialize DMA at the same time. After the initialization is completed, when externally sending data to the SCM, assuming that the data length of the frame is 200 bytes, then when the SCM receives a byte, it will not generate a serial port interrupt, but the DMA silently mutes the data in the background. Move it to your designated buffer. After the entire frame data is sent, the serial port will only generate an interrupt. At this time, the DMA_GetCurrDataCounter(); function can be used to calculate the current data acceptance length so as to perform data processing.

Application object: Suitable for a variety of serial-related communication protocols, such as: MODBUS, PPI; there are similar to GPS data reception and analysis, serial WIFI data reception, etc., are very good applications.

Three kinds of serial ports accept variable length data method

Key code analysis:

Void uart_init(u32 bound);

Void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx);

#endif

usart.C

// Initialize IO serial port 1

//bound: baud rate

Void uart_init(u32 bound)

{

// GPIO port settings

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE); //Enable USART1, GPIOA clock

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //Enable DMA transfer

RCC_APB1PeriphClockCmd (RCC_APB1Periph_USART2, ENABLE); // Enable the USART2 clock

USART_DeInit(USART1); // reset serial port 1

//USART1_TX PA.9

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9

GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Multiplexed push-pull output

GPIO_Init(GPIOA, &GPIO_InitStructure); // Initialize PA9

//USART1_RX PA.10

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//Floating Input

GPIO_Init(GPIOA, &GPIO_InitStructure); // Initialize the PA10

//Usart1 NVIC configuration

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//preemption priority 3

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //Sub-priority 3

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ channel enable

NVIC_Init(&NVIC_InitStructure); // Initialize the VIC register according to the specified parameters

//USART initialization settings

USART_InitStructure.USART_BaudRate = bound;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;//word length is 8-bit data format

USART_InitStructure.USART_StopBits = USART_StopBits_1;//a stop bit

USART_InitStructure.USART_Parity = USART_Parity_No;//No parity

USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;//No hardware flow control

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // Transceiver Mode

USART_Init(USART1, &USART_InitStructure); // Initialize the serial port

USART_ITConfig (USART1, USART_IT_IDLE, ENABLE); // Open idle interrupt

USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); //Enable serial port 1 DMA reception

USART_Cmd(USART1, ENABLE); //Enable serial port

// The corresponding DMA configuration

DMA_DeInit(DMA1_Channel5); //Reset DMA channel 5 register to default value Serial port 1 corresponds to DMA channel 5

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; // DMA peripheral usart base address

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf; //DMA memory base address

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //Data transfer direction, read from peripheral to send to memory

DMA_InitStructure.DMA_BufferSize = DMA_Rec_Len; // Size of DMA buffer for DMA channel

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //The peripheral address register is unchanged

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // memory address register is incremented

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //Data width is 8 bits

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //Data width is 8 bits

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // works in normal cache mode

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; // DMA channel x has medium priority

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // DMA channel x is not set to memory-to-memory transfer

DMA_Init(DMA1_Channel5, &DMA_InitStructure); // Initialize the DMA channel according to the parameters specified in DMA_InitStruct

DMA_Cmd(DMA1_Channel5, ENABLE); //Formally drives DMA transfers

}

// Recover the DMA pointer

Void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)

{

DMA_Cmd(DMA_CHx, DISABLE); //Close the channel indicated by USART1 TX DMA1

DMA_SetCurrDataCounter (DMA_CHx, DMA_Rec_Len);//DMA channel DMA cache size

DMA_Cmd(DMA_CHx, ENABLE); //Open the channel indicated by USART1 TX DMA1

}

// Send len bytes

//buf: send area first address

//len: the number of bytes sent

Void Usart1_Send(u8 *buf,u8 len)

Ningbo Autrends International Trade Co.,Ltd. , https://www.mosvapor.com