当前位置:   article > 正文

上位机图像处理和嵌入式模块部署(h750 mcu串口命令处理)

上位机图像处理和嵌入式模块部署(h750 mcu串口命令处理)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        前面学习103和407的时候,当时学过串口的收发。不过当时使用的主要是阻塞的方式。这一次,我们看下应该怎么利用中断的形式进行数据的收发。不仅如此,我们还可以看下,怎么把收到的数据放在一起,当成一个完整的命令去处理。

1、基本串口信息定义

        这边的串口主要还是利用a9、a10来实现数据的收发,其中a9负责数据的发送,a10负责数据的接收。除此之外,数据是采用中断的形式进行处理的。

  1. #define DEBUG_USART USART1
  2. #define DEBUG_USART_CLK_ENABLE() __USART1_CLK_ENABLE();
  3. #define DEBUG_USART_RX_GPIO_PORT GPIOA
  4. #define DEBUG_USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
  5. #define DEBUG_USART_RX_PIN GPIO_PIN_10
  6. #define DEBUG_USART_RX_AF GPIO_AF7_USART1
  7. #define DEBUG_USART_TX_GPIO_PORT GPIOA
  8. #define DEBUG_USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
  9. #define DEBUG_USART_TX_PIN GPIO_PIN_9
  10. #define DEBUG_USART_TX_AF GPIO_AF7_USART1
  11. #define DEBUG_USART_IRQHandler USART1_IRQHandler
  12. #define DEBUG_USART_IRQ USART1_IRQn

2、串口的初始化

        串口的初始化这边基本上就是八股文,基本上按照套路下就可以了。一般就是配置时钟、配置gpio、配置uart、配置中断。对于我们来说,最重要的baudrate,也就是波特率,就是在这里配置的。

  1. void DEBUG_USART_Config(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStruct;
  4. RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
  5. DEBUG_USART_RX_GPIO_CLK_ENABLE();
  6. DEBUG_USART_TX_GPIO_CLK_ENABLE();
  7. RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  8. RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
  9. HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
  10. DEBUG_USART_CLK_ENABLE();
  11. GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
  12. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  13. GPIO_InitStruct.Pull = GPIO_PULLUP;
  14. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  15. GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;
  16. HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
  17. GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
  18. GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;
  19. HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct);
  20. UartHandle.Instance = DEBUG_USART;
  21. UartHandle.Init.BaudRate = 115200;
  22. UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  23. UartHandle.Init.StopBits = UART_STOPBITS_1;
  24. UartHandle.Init.Parity = UART_PARITY_NONE;
  25. UartHandle.Init.Mode = UART_MODE_TX_RX;
  26. UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  27. UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
  28. UartHandle.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  29. UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  30. HAL_UART_Init(&UartHandle);
  31. HAL_NVIC_SetPriority(DEBUG_USART_IRQ, 0, 0);
  32. HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ);
  33. __HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);
  34. }

3、函数重定向

        对于喜欢用getchar、printf进行数据收发的同学,一般还需要实现一下fputc、fgetc这两个函数。实现了这两个函数,后续就可以使用getchar和printf了。

  1. void Usart_SendString(uint8_t *str)
  2. {
  3. unsigned int k=0;
  4. do
  5. {
  6. HAL_UART_Transmit( &UartHandle,(uint8_t *)(str + k) ,1,1000);
  7. k++;
  8. } while(*(str + k)!='\0');
  9. }
  10. int fputc(int ch, FILE *f)
  11. {
  12. HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 1000);
  13. return (ch);
  14. }
  15. int fgetc(FILE *f)
  16. {
  17. int ch;
  18. HAL_UART_Receive(&UartHandle, (uint8_t *)&ch, 1, 1000);
  19. return (ch);
  20. }

4、中断处理

        配置好了uart属性部分,下面就是中断处理。这里中断是一个数据、一个数据进行接收的,实际处理的时候,一般是进入中断之后循环接收数据,直到没有新的数据收到为止。

  1. extern uint8_t Rxflag;
  2. extern uint8_t ucTemp;
  3. void DEBUG_USART_IRQHandler(void)
  4. {
  5. if(__HAL_UART_GET_IT( &UartHandle, UART_IT_RXNE ) != RESET)
  6. {
  7. Rxflag=1;
  8. HAL_UART_Receive(&UartHandle, (uint8_t *)&ucTemp, 1, 1000);
  9. }
  10. HAL_UART_IRQHandler(&UartHandle);
  11. }

        代码中Rxflag是标志位,ucTemp代表实际接收到的数据。

5、接收数据实际处理

        单个接收到的数据一般是没有办法直接处理的,通常都是收集到一块来处理。处理结束的标志一般就是回车换行符,或者是某个特殊的标志也可以的。

  1. while (1)
  2. {
  3. if(Rxflag)
  4. {
  5. if (usRxCount < sizeof(ucaRxBuf))
  6. {
  7. ucaRxBuf[usRxCount++] = ucTemp;
  8. }
  9. else
  10. {
  11. usRxCount = 0;
  12. }
  13. if (ucTemp == 0x0A)
  14. {
  15. HAL_UART_Transmit( &UartHandle, (uint8_t *)ucaRxBuf,usRxCount,1000 );
  16. usRxCount = 0;
  17. }
  18. Rxflag=0;
  19. __HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);
  20. }
  21. }

        这边做的比较简单,整个while(1)部分是放在main函数里面的。如果Rxflag为1,那么把接收到的数据放到ucaRxBuf里面。接着检查数据是不是0x0a,也就是换行,如果是,就把数据发送回去。最后把Rxflag重新置0,打开串口接收中断,准备新的数据进来。

        大家如果做的复杂一点,数据上面可以用queue的形式来处理,函数也可以抽象出来,实现部分做成parse command的形式,这样处理起来就会简单的多。另外,数据接收部分要尽快打开中断。

6、测试和验证

        测试就比较简单了,直接把代码编译、下载后,利用ATK-XCOM上位机打开串口,输入123、abc这样的内容,看看有没有回显就知道代码对不对了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/736357
推荐阅读
相关标签
  

闽ICP备14008679号