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.
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