分享

使用stm32cubemx开发四:串口标准化输出

 奔跑的瓦力 2019-01-28

 硬件平台:stm32F407Zet6

软件平台:stm32cubeMX 4.7+MDK5.14

电路连接:PA9,PA10

第一步、通过Stm32CubeMX图形界面创建Keil工程

需要配置的地方是



在这里可以修改串口工作的一下参数,软件就可以生成配置好的工程,不需要亲自去配置这些了。

第二步。打开工程,编写代码,验证

  1. /* USER CODE BEGIN PV */
  2. #include "stdio.h"
  3. #ifdef __GNUC__
  4. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  5. #else
  6. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  7. #endif /* __GNUC__ */
  8. PUTCHAR_PROTOTYPE
  9. {
  10. HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
  11. return ch;
  12. }
  13. /* USER CODE END PV */

这段程序为了可以使用printf()函数,对字符输出函数进行了重定向,这样我们就可以在程序中使用printf函数进行输出了,这里使用的是查询发送方式,有超时控制的。接下来来看中断方式的。

  1. /**
  2. * @brief This function handles UART interrupt request.
  3. * @param huart: pointer to a UART_HandleTypeDef structure that contains
  4. * the configuration information for the specified UART module.
  5. * @retval None
  6. */
  7. void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
  8. {
  9. uint32_t tmp1 = 0, tmp2 = 0;
  10. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);
  11. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE);
  12. /* UART parity error interrupt occurred ------------------------------------*/
  13. if((tmp1 != RESET) && (tmp2 != RESET))
  14. {
  15. __HAL_UART_CLEAR_PEFLAG(huart);
  16. huart->ErrorCode |= HAL_UART_ERROR_PE;
  17. }
  18. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_FE);
  19. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  20. /* UART frame error interrupt occurred -------------------------------------*/
  21. if((tmp1 != RESET) && (tmp2 != RESET))
  22. {
  23. __HAL_UART_CLEAR_FEFLAG(huart);
  24. huart->ErrorCode |= HAL_UART_ERROR_FE;
  25. }
  26. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_NE);
  27. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  28. /* UART noise error interrupt occurred -------------------------------------*/
  29. if((tmp1 != RESET) && (tmp2 != RESET))
  30. {
  31. __HAL_UART_CLEAR_NEFLAG(huart);
  32. huart->ErrorCode |= HAL_UART_ERROR_NE;
  33. }
  34. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);
  35. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR);
  36. /* UART Over-Run interrupt occurred ----------------------------------------*/
  37. if((tmp1 != RESET) && (tmp2 != RESET))
  38. {
  39. __HAL_UART_CLEAR_OREFLAG(huart);
  40. huart->ErrorCode |= HAL_UART_ERROR_ORE;
  41. }
  42. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_RXNE);
  43. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE);
  44. /* UART in mode Receiver ---------------------------------------------------*/
  45. if((tmp1 != RESET) && (tmp2 != RESET))
  46. {
  47. UART_Receive_IT(huart);
  48. }
  49. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TXE);
  50. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE);
  51. /* UART in mode Transmitter ------------------------------------------------*/
  52. if((tmp1 != RESET) && (tmp2 != RESET))
  53. {
  54. UART_Transmit_IT(huart);
  55. }
  56. tmp1 = __HAL_UART_GET_FLAG(huart, UART_FLAG_TC);
  57. tmp2 = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC);
  58. /* UART in mode Transmitter end --------------------------------------------*/
  59. if((tmp1 != RESET) && (tmp2 != RESET))
  60. {
  61. UART_EndTransmit_IT(huart);
  62. }
  63. if(huart->ErrorCode != HAL_UART_ERROR_NONE)
  64. {
  65. /* Set the UART state ready to be able to start again the process */
  66. huart->State = HAL_UART_STATE_READY;
  67. HAL_UART_ErrorCallback(huart);
  68. }
  69. }
这个函数中查询了所有可能发生的中断。用到的中断是发送完成中断,就找到了UART_EndTransmit_IT(huart);再跳进去看看,

  1. /**
  2. * @brief Wraps up transmission in non blocking mode.
  3. * @param huart: pointer to a UART_HandleTypeDef structure that contains
  4. * the configuration information for the specified UART module.
  5. * @retval HAL status
  6. */
  7. static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
  8. {
  9. /* Disable the UART Transmit Complete Interrupt */
  10. __HAL_UART_DISABLE_IT(huart, UART_IT_TC);
  11. /* Check if a receive process is ongoing or not */
  12. if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
  13. {
  14. huart->State = HAL_UART_STATE_BUSY_RX;
  15. }
  16. else
  17. {
  18. /* Disable the UART Parity Error Interrupt */
  19. __HAL_UART_DISABLE_IT(huart, UART_IT_PE);
  20. /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
  21. __HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
  22. huart->State = HAL_UART_STATE_READY;
  23. }
  24. HAL_UART_TxCpltCallback(huart);
  25. return HAL_OK;
  26. }
这个函数在确定中断发生了之后调用了,HAL_UART_TxCpltCallback(huart);从函数名上可以看出,这是个回调函数,就是留给上层来实现的函数,由这个函数的实现不同,来实现不同的功能。这里来实现这个函数,让它在中断发生的时候吧USART1Ready置为SET;代码修改如下

  1. /* USER CODE BEGIN PV */
  2. #include "stdio.h"
  3. #ifdef __GNUC__
  4. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  5. #else
  6. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  7. #endif /* __GNUC__ */
  8. __IO ITStatus USART1Ready = RESET;
  9. PUTCHAR_PROTOTYPE
  10. {
  11. HAL_UART_Transmit_IT(&huart1 , (uint8_t *)&ch, 1);
  12. while (USART1Ready != SET)
  13. {
  14. }
  15. USART1Ready = RESET;
  16. return ch;
  17. }
  18. /* USER CODE END PV */
这是重定向函数的修改,启动发送之后,等待发送完成。重新实现的回调函数如下图所示:

  1. /**
  2. * @brief Tx Transfer completed callbacks.
  3. * @param huart: pointer to a UART_HandleTypeDef structure that contains
  4. * the configuration information for the specified UART module.
  5. * @retval None
  6. */
  7. void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
  8. {
  9. /* NOTE: This function Should not be modified, when the callback is needed,
  10. the HAL_UART_TxCpltCallback could be implemented in the user file
  11. */
  12. USART1Ready = SET;
  13. }

这样就可以了,下载验证。





    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多