STM32 hal library solves serial port + DMA receiving data

STM32F407 serial port idle interrupt + DMA reception, applied to DJI DT7 wireless remote control

#stm32CubeIDE STM32F4 HAL library DJI DT7 serial port + DMA ()

1. Hardware design
First understand the signal type of the serial port data sent by the DJI receiver Need to make an inversion circuit, insert the picture description here
as shown in the figure, you need to make an inversion circuit... as shown below:
Insert picture description here

The pictures are taken from the Internet. These can be found on the Internet. Remember to have a pull-up resistor, if there is no external, you can use the GPIO of the MCU USART RX to configure it to
be sent after the pull-up remote control is received, which is equivalent to the TX of the external serial port. Connect with the RX of the microcontroller.

Next is the software part, I use STM32CubeIDE, first configure the environment
1. Configure the RCC clock, I won't say more about this, if you can’t, the comment area will tell me
2. Insert picture description here
Configure the serial port data,
Insert picture description hereconfigure the serial port DMA to receive the
Insert picture description here
GPIO mode configuration, and
finally, Enable the serial port to receive interrupts.
Insert picture description here
I used a 10ms timer interrupt to process data in the timer, not in the interrupt. The interrupt is only used to receive data. I won’t say much about the timer configuration.

Insert picture description here
Add a picture, the
code below

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); //使能串口空闲中断
  HAL_UART_Receive_DMA(&huart1, receive_buff,18);//开启串口DMA接收
  HAL_TIM_Base_Start_IT(&htim2);//开启1定时器中断
  /* USER CODE END 2 */

uint8_t receive_buff[18]; This is the defined receiving array
receive_buff is the receiving array, the received data is placed here, 18 represents receiving 18 bytes at a time.
Next, find the stm32f4xx_it.c file

 * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);  //这个可有可无
  /* USER CODE BEGIN USART1_IRQn 1 */
  if(USART1==huart1.Instance)  //判断是否为串口1的中断
  {
  if( __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)!=RESET )                /判断是否为空闲中断
  			   {
  				__HAL_UART_CLEAR_IDLEFLAG(&huart1);        //  如果是空闲中断清除空闲中断标志
  				HAL_UART_DMAStop(&huart1);                 // 关闭串口的DMA接收
  				DMA2_Stream2->NDTR=(uint16_t)(RC_FRAME_LENGTH);  //  这个参考的大疆DT7历程,重置DMA存储指针到起始位置
  				HAL_UART_Receive_DMA(&huart1, (uint8_t*) receive_buff, 18); //再开启接收
  				HAL_Delay(25);    //为什么加延时呢,见后面
              if(__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)==0&&receive_buff[17]==4)  // 见后面
                {
                memcpy(data_Handle, receive_buff, 18);      //复制到其他数组方便处理
      
                }
  			   }
  }
  /* USER CODE END USART1_IRQn 1 */
}
/**

Explain, the sentence __HAL_DMA_GET_COUNTER(&hdma_usart1_rx) means the number of remaining data units in the current DMA stream transmission, that is to say, after the reception is turned on, you need to wait for the reception to complete before processing the data, that is, __HAL_DMA_GET_COUNTER(&hdma_usart1_rx) This is equal to zero. It means that all 18 bytes have been received.
You can look at this macro definition in the HAL library #define __HAL_DMA_GET_COUNTER( HANDLE ) (( HANDLE )->Instance->NDTR) and then
look at the meaning of the ST document NDTR register,
Insert picture description here
so I am in HAL_UART_Receive_DMA(&huart1, (uint8_t*) receive_buff, 18); After the reception is turned on, you need to wait for 20m' to complete the reception before you can make this judgment. Otherwise, setting a breakpoint during debugging will not enter this if. Because there is still remaining, it will not be equal to 0.
About &&receive_buff [17]==4, it should be the characteristics of receiving data for my root, and I added a judgment condition to improve the correctness of the data. To
put it bluntly, this sentence is a length check of the received data plus one that I find myself A feature of the data in the data can guarantee the correctness of the data. When the data is chaotic, it will filter out
if (__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)==0&&receive_buff[17]==4)
Okay, that's all, it's the first time to write Article, welcome criticism and criticism from netizens, see what can be improved in this, learn from each other, cheer!

Guess you like

Origin blog.csdn.net/m0_49933527/article/details/114187881