3688 views|1 replies

156

Posts

1

Resources
The OP
 

[Nucleo G071 Review] Serial port 1 idle interrupt + DMA to achieve variable length reception [Copy link]

After two days and one night of exploration, I finally figured out the temperament of the DMA of the G0 series models, and I can carry out my next serial port variable length reception DEMO. The G0 series DMA has only one peripheral DMA1, which supports 7 channels. These 7 channels are also very user-friendly and can be arbitrarily assigned to any peripheral that supports DMA transmission, such as serial port, ADC, SPI interface, etc. I believe ST is learning from NXP's new RT1050 series. In other words, the RX receiving DMA channel of serial port 1 can be DMA1 channel 1, DMA1 channel 2, or even DMA1 channel 7. Since the LPUART1 peripheral on the board has been used for debugging and printing, I use serial port 1, namely PA9 PA10, to connect the external serial port module for experiments. First open CubeMX and configure serial port 1 and DMA. As shown in the figure, you can choose any one of the 7 channels. I chose DMA1 channel 1: Other parameters remain unchanged, such as FIFO, which is not turned on: In the generated routine, there is a very important statement. Since the DMA of the G0 series does not specify a specific peripheral to use a specific channel, a DMAMUX controller is required to remap the channel. In layman's terms, it is to lock the channel. The relevant configuration is the Request member variable of DMA_InitTypeDef. It is this variable that troubled me all night last night, because the default Request variable is not specified in the routine generated by CubeMX: Then just follow the official configuration and add idle interrupt detection and response: void UART1_Init(int baud) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF1_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); huart1.Instance = USART1; huart1.Init.BaudRate = baud; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&huart1); HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8); HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8); HAL_UARTEx_DisableFifoMode(&huart1); __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); HAL_NVIC_SetPriority(USART1_IRQn,0,0); HAL_NVIC_EnableIRQ(USART1_IRQn); hdma_usart1_rx.Instance=DMA1_Channel1; hdma_usart1_rx.Init.Direction=DMA_PERIPH_TO_MEMORY; hdma_usart1_rx.Init.PeriphInc=DMA_PINC_DISABLE; hdma_usart1_rx.Init.MemInc=DMA_MINC_ENABLE; hdma_usart1_rx.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE; hdma_usart1_rx.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode=DMA_NORMAL; hdma_usart1_rx.Init.Priority=DMA_PRIORITY_VERY_HIGH; hdma_usart1_rx.Init.Request=DMA_REQUEST_USART1_RX;[/ size] HAL_DMA_Init(&hdma_usart1_rx); __HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx); HAL_UART_Receive_DMA(&huart1,(unsigned char*)rx_buf, BUFFERSIZE); } Write the interrupt service function and add a function to loop through the interrupt response flag in the main program: void USART1_IRQHandler() {[ /size] uint32_t temp; if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG( &huart1); HAL_UART_DMAStop(&huart1); temp=__HAL_DMA_GET_COUNTER(&hdma_usart1_rx); printf("----- -%d-----\n",temp); rx_len=BUFFERSIZE-temp; recv_end_flag=1; } } [/ size] void UART_DMA_Get() { if(recv_end_flag==1) {[/size ] //rx_len=0; recv_end_flag=0; printf("rx_buf=%s\n",rx_buf);[/ size] } HAL_UART_Receive_DMA(&huart1,(unsigned char*)rx_buf,BUFFERSIZE); } Connect the hardware circuit, that is, use a CH340 serial port module to connect the board PA9 PA10: See the effect:

This post is from stm32/stm8

Latest reply

Can you let me see your project? Thank you.  Details Published on 2019-3-25 20:02
 

11

Posts

0

Resources
2
 
Can you let me see your project? Thank you.
This post is from stm32/stm8
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list