uart2.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include "uart2.h"
  2. #include <rtthread.h>
  3. #include <stm32f4xx_hal.h>
  4. /* ===================== 全局变量定义 ===================== */
  5. volatile uint8_t u2_rx_flg = 0; /* 接收完成标志 */
  6. volatile uint16_t u2_rx_cnt = 0; /* 接收数据长度 */
  7. volatile uint8_t u2_rx_buf[U2_BUF_MAX]; /* 接收缓冲区 */
  8. /* UART句柄 */
  9. static UART_HandleTypeDef huart2;
  10. /* ===================== 私有函数声明 ===================== */
  11. static void u2_gpio_init(void);
  12. static void u2_nvic_init(void);
  13. static int u2_hw_init(void);
  14. /* ===================== GPIO初始化 ===================== */
  15. static void u2_gpio_init(void)
  16. {
  17. GPIO_InitTypeDef GPIO_InitStruct = {0};
  18. /* 使能GPIO时钟 */
  19. __HAL_RCC_GPIOA_CLK_ENABLE();
  20. /* PA2 - TX, PA3 - RX */
  21. GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
  22. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  23. GPIO_InitStruct.Pull = GPIO_PULLUP;
  24. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  25. GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
  26. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  27. }
  28. /* ===================== NVIC初始化 ===================== */
  29. static void u2_nvic_init(void)
  30. {
  31. HAL_NVIC_SetPriority(USART2_IRQn, 2, 0);
  32. HAL_NVIC_EnableIRQ(USART2_IRQn);
  33. }
  34. /* ===================== UART硬件初始化 ===================== */
  35. static int u2_hw_init(void)
  36. {
  37. /* 使能USART2时钟 */
  38. __HAL_RCC_USART2_CLK_ENABLE();
  39. /* 配置UART参数 */
  40. huart2.Instance = USART2;
  41. huart2.Init.BaudRate = 115200;
  42. huart2.Init.WordLength = UART_WORDLENGTH_8B;
  43. huart2.Init.StopBits = UART_STOPBITS_1;
  44. huart2.Init.Parity = UART_PARITY_NONE;
  45. huart2.Init.Mode = UART_MODE_TX_RX;
  46. huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  47. huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  48. if (HAL_UART_Init(&huart2) != HAL_OK)
  49. {
  50. return -1;
  51. }
  52. /* 使能空闲中断 */
  53. __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);
  54. /* 使能接收中断 */
  55. __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
  56. return 0;
  57. }
  58. /* ===================== 自动初始化 ===================== */
  59. static int u2_init(void)
  60. {
  61. u2_gpio_init();
  62. u2_nvic_init();
  63. if (u2_hw_init() != 0)
  64. {
  65. return -1;
  66. }
  67. return 0;
  68. }
  69. INIT_BOARD_EXPORT(u2_init);
  70. /* ===================== 发送接口 ===================== */
  71. int u2_send_buf(uint8_t *buf , int size)
  72. {
  73. if (buf == NULL || size <= 0)
  74. {
  75. return -1;
  76. }
  77. if (HAL_UART_Transmit(&huart2, buf, size, 1000) != HAL_OK)
  78. {
  79. return -1;
  80. }
  81. return size;
  82. }
  83. /* ===================== 中断服务函数 ===================== */
  84. void USART2_IRQHandler(void)
  85. {
  86. uint32_t isrflags = READ_REG(huart2.Instance->SR);
  87. uint32_t cr1its = READ_REG(huart2.Instance->CR1);
  88. uint32_t cr3its = READ_REG(huart2.Instance->CR3);
  89. /* 检查空闲中断标志 */
  90. if ((isrflags & USART_SR_IDLE) != RESET)
  91. {
  92. /* 清除空闲标志:先读SR再读DR */
  93. (void)huart2.Instance->SR;
  94. (void)huart2.Instance->DR;
  95. /* 设置接收完成标志 */
  96. u2_rx_flg = 1;
  97. }
  98. /* 检查接收中断标志 */
  99. if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
  100. {
  101. /* 读取接收数据 */
  102. uint8_t data = (uint8_t)(huart2.Instance->DR & 0xFF);
  103. /* 存入缓冲区 */
  104. if (u2_rx_cnt < sizeof(u2_rx_buf))
  105. {
  106. u2_rx_buf[u2_rx_cnt++] = data;
  107. }
  108. }
  109. /* 处理其他中断(错误标志等) */
  110. if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
  111. {
  112. /* 清除溢出错误标志 */
  113. (void)huart2.Instance->DR;
  114. (void)huart2.Instance->SR;
  115. }
  116. if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
  117. {
  118. /* 清除帧错误标志 */
  119. (void)huart2.Instance->DR;
  120. (void)huart2.Instance->SR;
  121. }
  122. if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
  123. {
  124. /* 清除噪声错误标志 */
  125. (void)huart2.Instance->DR;
  126. (void)huart2.Instance->SR;
  127. }
  128. if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
  129. {
  130. /* 清除校验错误标志 */
  131. (void)huart2.Instance->DR;
  132. (void)huart2.Instance->SR;
  133. }
  134. }
  135. void uart2_clear_rx_buffer(void)
  136. {
  137. u2_rx_flg = 0;
  138. u2_rx_cnt = 0;
  139. memset(u2_rx_buf , 0 ,U2_BUF_MAX);
  140. }
  141. /* ===================== 测试线程 ===================== */
  142. //static void u2_test_thread_entry(void *parameter)
  143. //{
  144. // (void)parameter;
  145. //
  146. // rt_kprintf("UART2 test thread started\r\n");
  147. //
  148. // while (1)
  149. // {
  150. // /* 检查接收完成标志 */
  151. // if (u2_rx_flg)
  152. // {
  153. // /* 临时保存接收数据 */
  154. // uint16_t rx_len = u2_rx_cnt;
  155. // uint8_t tx_buf[256];
  156. //
  157. // if (rx_len > 0 && rx_len <= sizeof(u2_rx_buf))
  158. // {
  159. // /* 复制数据到发送缓冲区 */
  160. // rt_memcpy(tx_buf, (void *)u2_rx_buf, rx_len);
  161. //
  162. // /* 打印接收信息 */
  163. // rt_kprintf("UART2 RX: len=%d, data=", rx_len);
  164. // for (uint16_t i = 0; i < rx_len; i++)
  165. // {
  166. // rt_kprintf("%02X ", u2_rx_buf[i]);
  167. // }
  168. // rt_kprintf("\r\n");
  169. //
  170. // /* 延迟100ms */
  171. // rt_thread_mdelay(100);
  172. //
  173. // /* 原路发送 */
  174. // u2_send_buf(tx_buf,rx_len);
  175. // rt_kprintf("UART2 TX: echo back %d bytes\r\n", rx_len);
  176. // }
  177. //
  178. // /* 清除标志和计数,准备下次接收 */
  179. // u2_rx_cnt = 0;
  180. // u2_rx_flg = 0;
  181. // }
  182. //
  183. // rt_thread_mdelay(10);
  184. // }
  185. //}
  186. //
  187. ///* 创建测试线程 */
  188. //static void u2_test_thread_init(void)
  189. //{
  190. // rt_thread_t tid;
  191. //
  192. // tid = rt_thread_create("u2_test",
  193. // u2_test_thread_entry,
  194. // RT_NULL,
  195. // 512,
  196. // RT_THREAD_PRIORITY_MAX / 2,
  197. // 10);
  198. // if (tid != RT_NULL)
  199. // {
  200. // rt_thread_startup(tid);
  201. // }
  202. //}
  203. //INIT_APP_EXPORT(u2_test_thread_init);