SN_UART.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. #include "SN_UART.h"
  2. #include <stdio.h>
  3. /*
  4. 文件名:SN_UART.c/.h
  5. 作者: SN_FAE_黄泽洪
  6. 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证
  7. 本人不担负商业使用上带来的风险。
  8. */
  9. /*
  10. SN_UART 模块的使用方法
  11. SN_UART.h 文件中的: SN_PRINTF_DEFAULT 的宏定义 //默认使用UART1作为printf() 注释掉这行宏定义就使用UART2作为printf()
  12. 方法1:使用printf() 修改头文件中的宏定义,选择UART1 或是 UART2 作为printf接口
  13. int main(void){
  14. SN_SYSCLK_set(SYSCLK_48MHZ);
  15. std_delay_init();
  16. SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 );
  17. while(1){
  18. std_delayms(500);
  19. printf("CIU32F003,司诺电子一级代理\r\n");
  20. }
  21. }
  22. 方法2:发送数组数据
  23. uint8_t TX_BULL[8] = {1,2,3,4,5,6,7,8};
  24. int main(void){
  25. SN_SYSCLK_set(SYSCLK_48MHZ);
  26. std_delay_init();
  27. SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 );
  28. while(1){
  29. std_delayms(500);
  30. SN_UART_TX_BULL(UART1,TX_BULL , 8);
  31. }
  32. }
  33. 方法3:接收数据到缓存数组中
  34. uint8_t RX_BULL[8] = {0};
  35. uint8_t val = 0;
  36. int main(void){
  37. SN_SYSCLK_set(SYSCLK_48MHZ);
  38. std_delay_init();
  39. SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 );
  40. SN_UART_RX_BULL_set(UART1, RX_BULL ,8,NVIC_PRIO_2 );//设置缓冲区和缓冲区大小,并启动中断接收
  41. while(1){
  42. //用户直接处理自己数组内容
  43. td_delayms(500);
  44. val = RX_BULL[0];
  45. }
  46. }
  47. 方法4:接收数据自己处理
  48. //用户自定义的处理函数
  49. void fun(void){
  50. RX_BULL[k++] = std_uart_rx_read_data(UART1);
  51. std_gpio_toggle_pin(LED_GPIO_PORT, LED_PIN);
  52. if(k == 8){ k = 0;}
  53. }
  54. int main(void){
  55. //处理串口设置
  56. SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 );
  57. SN_UART_RX_CALL(UART1, fun, NVIC_PRIO_2 ); //UART1_CALL_FUN 是用户自己的代码处理逻辑
  58. while(1){};
  59. }
  60. 其他可用的std标准接口:
  61. std_uart_overrun_disable(UART_t *uartx) //关闭ORE
  62. std_uart_overrun_enable(UART_t *uartx) //开启ORE
  63. std_uart_cr1_interrupt_disable(UART_t *uartx, uint32_t interrupt) //关闭对应的中断
  64. std_uart_cr1_interrupt_enable(UART_t *uartx, uint32_t interrupt) //开启对应的中断
  65. 其他接口访问: #include "ciu32f003_std_uart.h"
  66. */
  67. /*
  68. 该函数是KEIL C 提供的标准printf重定向
  69. 必须勾选Micro LIB
  70. * @brief 重定向c库函数printf到串口,重定向后可使用printf函数
  71. * @param ch 待发送字符
  72. * @retval ch 发送的字符
  73. */
  74. #ifdef SN_PRINTF_DEFAULT
  75. int fputc(int ch, FILE *f)
  76. {
  77. /* 发送一个字节数据到串口 */
  78. std_uart_tx_write_data(UART1, (uint32_t)ch);
  79. /* 等待发送完毕 */
  80. while (!std_uart_get_flag(UART1, UART_FLAG_TXE))
  81. ;
  82. return ch;
  83. }
  84. int fgetc(FILE *f)
  85. {
  86. /* 等待接收完毕 */
  87. while (!std_uart_get_flag(UART1, UART_FLAG_RXNE))
  88. ;
  89. return (int)std_uart_rx_read_data(UART2);
  90. }
  91. #else
  92. int fputc(int ch, FILE *f)
  93. {
  94. /* 发送一个字节数据到串口 */
  95. std_uart_tx_write_data(UART2, (uint32_t)ch);
  96. /* 等待发送完毕 */
  97. while (!std_uart_get_flag(UART2, UART_FLAG_TXE))
  98. ;
  99. return ch;
  100. }
  101. int fgetc(FILE *f)
  102. {
  103. /* 等待接收完毕 */
  104. while (!std_uart_get_flag(UART2, UART_FLAG_RXNE))
  105. ;
  106. return (int)std_uart_rx_read_data(UART2);
  107. }
  108. #endif
  109. // UARTx_IO列表
  110. const uint32_t UARTX_IO_list[] =
  111. {
  112. // TX UART1
  113. GPIO_PIN_3,
  114. GPIO_PIN_6,
  115. GPIO_PIN_7,
  116. GPIO_PIN_0,
  117. GPIO_PIN_4,
  118. GPIO_PIN_6,
  119. GPIO_PIN_0,
  120. // RX
  121. GPIO_PIN_2,
  122. GPIO_PIN_4,
  123. GPIO_PIN_7,
  124. GPIO_PIN_5,
  125. GPIO_PIN_7,
  126. // TX UART2
  127. GPIO_PIN_4,
  128. GPIO_PIN_5,
  129. GPIO_PIN_6,
  130. // RX
  131. GPIO_PIN_3,
  132. GPIO_PIN_6,
  133. GPIO_PIN_2,
  134. };
  135. // 全局接收数组设定
  136. uint8_t *G_UART1_BULL = NULL;
  137. // 全局接收数组长度设定
  138. uint8_t G_UART1_BULL_LEN = 0;
  139. // 全局接收接口函数使用选择
  140. uint8_t G_UART1_RX_FUN = 0;
  141. // 全局接收函数指针
  142. void (*UART1_RX_CALL)(void) = NULL;
  143. // 全局ORE溢出函数指针
  144. void (*UART1_ORE_CALL)(void) = NULL;
  145. // 全局接收数组设定
  146. uint8_t *G_UART2_BULL = NULL;
  147. // 全局接收数组长度设定
  148. uint8_t G_UART2_BULL_LEN = 0;
  149. // 全局接收接口函数使用选择
  150. uint8_t G_UART2_RX_FUN = 0;
  151. // 全局接收函数指针
  152. void (*UART2_RX_CALL)(void) = NULL;
  153. // 全局ORE溢出函数指针
  154. void (*UART2_ORE_CALL)(void) = NULL;
  155. /*
  156. 函数:SN_UART1_init(uint32_t baudrate,uint16_t RX_IO,uint32_t TX_IO)
  157. 功能:初始化串口1
  158. 参数:UART1设备
  159. @UART1
  160. @UART2
  161. 参数:baudrate 波特率
  162. 参数:RX_IO 接收引脚IO
  163. #UART1_RX_PA2
  164. #UART1_RX_PA4
  165. #UART1_RX_PA7
  166. #UART1_RX_PB5
  167. #UART1_RX_PB7
  168. #UART2_TX_PA4
  169. #UART2_TX_PA5
  170. #UART2_TX_PB6
  171. 参数:TX_IO 发送硬件IO
  172. #UART1_TX_PA3
  173. #UART1_TX_PA6
  174. #UART1_TX_PA7
  175. #UART1_TX_PB0
  176. #UART1_TX_PB4
  177. #UART1_TX_PB6
  178. #UART1_TX_PC0 (PC0该引脚需要修改选项字节之后才能使用,不推荐使用这个引脚)
  179. #UART2_RX_PA3
  180. #UART2_RX_PA6
  181. #UART2_RX_PB2
  182. 返回值:无
  183. */
  184. void SN_UART_init(UART_t *uartx, uint32_t baudrate, uint8_t RX_IO, uint8_t TX_IO)
  185. {
  186. GPIO_t *GPIO_X = NULL;
  187. std_gpio_init_t gpio_config = {0};
  188. gpio_config.mode = GPIO_MODE_ALTERNATE;
  189. gpio_config.pull = GPIO_PULLUP;
  190. gpio_config.output_type = GPIO_OUTPUT_PUSHPULL;
  191. if (uartx == UART1)
  192. {
  193. // 设置TX
  194. if (TX_IO < 7)
  195. {
  196. if (TX_IO < 3)
  197. {
  198. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  199. GPIO_X = GPIOA;
  200. }
  201. else if (TX_IO < 6)
  202. {
  203. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  204. GPIO_X = GPIOB;
  205. }
  206. else if (TX_IO == 6)
  207. {
  208. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOC);
  209. GPIO_X = GPIOC;
  210. }
  211. }
  212. gpio_config.pin = UARTX_IO_list[TX_IO];
  213. gpio_config.alternate = GPIO_AF1_UART1;
  214. std_gpio_init(GPIO_X, &gpio_config);
  215. // 设置RX
  216. GPIO_X = NULL;
  217. if (RX_IO > 7)
  218. {
  219. if (RX_IO < 10)
  220. {
  221. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  222. GPIO_X = GPIOA;
  223. if (RX_IO == 9)
  224. {
  225. gpio_config.alternate = GPIO_AF5_UART1;
  226. }
  227. }
  228. else if (RX_IO < 12)
  229. {
  230. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  231. GPIO_X = GPIOB;
  232. }
  233. }
  234. gpio_config.pin = UARTX_IO_list[RX_IO];
  235. std_gpio_init(GPIO_X, &gpio_config);
  236. }
  237. else
  238. {
  239. gpio_config.alternate = GPIO_AF5_UART2;
  240. // 设置TX
  241. if (TX_IO < 15)
  242. {
  243. if (TX_IO < 14)
  244. {
  245. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  246. GPIO_X = GPIOA;
  247. }
  248. else if (TX_IO == 14)
  249. {
  250. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  251. GPIO_X = GPIOB;
  252. }
  253. }
  254. gpio_config.pin = UARTX_IO_list[TX_IO];
  255. std_gpio_init(GPIO_X, &gpio_config);
  256. // 设置RX
  257. GPIO_X = NULL;
  258. if (RX_IO > 14)
  259. {
  260. if (RX_IO < 17)
  261. {
  262. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  263. GPIO_X = GPIOA;
  264. }
  265. else if (RX_IO == 17)
  266. {
  267. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  268. GPIO_X = GPIOB;
  269. }
  270. }
  271. gpio_config.pin = UARTX_IO_list[RX_IO];
  272. std_gpio_init(GPIO_X, &gpio_config);
  273. }
  274. // 初始串口
  275. std_uart_init_t uart_confg = {0};
  276. /* UART 时钟使能 */
  277. if (uartx == UART1)
  278. {
  279. std_rcc_apb2_clk_enable(RCC_PERIPH_CLK_UART1);
  280. }
  281. else
  282. {
  283. std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_UART2);
  284. }
  285. /* UART 初始化 */
  286. uart_confg.baudrate = baudrate;
  287. uart_confg.direction = UART_DIRECTION_SEND_RECEIVE;
  288. uart_confg.wordlength = UART_WORDLENGTH_8BITS;
  289. uart_confg.stopbits = UART_STOPBITS_1;
  290. uart_confg.parity = UART_PARITY_NONE;
  291. std_uart_init(uartx, &uart_confg);
  292. /* 使能UART */
  293. std_uart_enable(uartx);
  294. }
  295. /*
  296. 函数:SN_UART_TX_BULL(UART_t *uartx ,uint8_t * BULL , uint16_t BULL_LEN)
  297. 功能:通过UART发送一组数据
  298. 参数:UART1设备
  299. @UART1
  300. @UART2
  301. 参数:BULL 数据数组
  302. 参数:BULL_LEN 数据数组长度
  303. */
  304. void SN_UART_TX_BULL(UART_t *uartx, uint8_t *BULL, uint16_t BULL_LEN)
  305. {
  306. for (int i = 0; i < BULL_LEN; i++)
  307. {
  308. while (!std_uart_get_flag(uartx, UART_FLAG_TXE))
  309. ;
  310. std_uart_tx_write_data(uartx, BULL[i]);
  311. }
  312. while (!std_uart_get_flag(uartx, UART_FLAG_TC))
  313. ;
  314. }
  315. /*
  316. 函数:SN_UART1_RX_BULL_set(UART_t *uartx ,uint8_t * BULL,uint16_t BULL_LEN );
  317. 功能:设置自动接收的数组(缓冲区) 使用了该接口后就不能使用SN_UART1_RX_CALL()
  318. 参数:UART1设备
  319. @UART1
  320. @UART2
  321. 参数:BULL 数据数组
  322. 参数:BULL_LEN 长度大小
  323. 参数:NVIC_PRIO_X 中断优先级
  324. @NVIC_PRIO_0 高
  325. @NVIC_PRIO_1
  326. @NVIC_PRIO_2
  327. @NVIC_PRIO_3 低
  328. 返回:无
  329. */
  330. void SN_UART_RX_BULL_set(UART_t *uartx, uint8_t *BULL, uint16_t BULL_LEN, uint16_t NVIC_PRIO_x)
  331. {
  332. /* 配置UART1中断优先级以及使能UART1的NVIC中断 */
  333. if (uartx == UART1)
  334. {
  335. G_UART1_BULL = BULL;
  336. G_UART1_BULL_LEN = BULL_LEN;
  337. NVIC_SetPriority(UART1_IRQn, NVIC_PRIO_x);
  338. NVIC_EnableIRQ(UART1_IRQn);
  339. }
  340. else
  341. {
  342. G_UART2_BULL = BULL;
  343. G_UART2_BULL_LEN = BULL_LEN;
  344. NVIC_SetPriority(UART2_IRQn, NVIC_PRIO_x);
  345. NVIC_EnableIRQ(UART2_IRQn);
  346. }
  347. /* UART 使能中断接收 */
  348. std_uart_cr1_interrupt_enable(uartx, UART_CR1_INTERRUPT_RXNE);
  349. }
  350. /*
  351. 函数:SN_UART1_RX_CALL(UART_t *uartx, void (*UART1_CALL_FUN)(void),uint16_t NVIC_PRIO_x );
  352. 功能:用户自己处理中断接收处理 (使用了该接口后就不能使用 SN_UART1_RX_BULL_set())
  353. 参数:UART1设备
  354. @UART1
  355. @UART2
  356. 参数:*UART1_CALL_FUN 自定义中断处理函数
  357. 参数:NVIC_PRIO_X 中断优先级
  358. @NVIC_PRIO_0
  359. @NVIC_PRIO_1
  360. @NVIC_PRIO_2
  361. @NVIC_PRIO_3
  362. 返回:无
  363. */
  364. void SN_UART_RX_CALL(UART_t *uartx, void (*UART_CALL_FUN)(void), uint16_t NVIC_PRIO_x)
  365. {
  366. /* 配置UART1中断优先级以及使能UART1的NVIC中断 */
  367. if (uartx == UART1)
  368. {
  369. NVIC_SetPriority(UART1_IRQn, NVIC_PRIO_x);
  370. NVIC_EnableIRQ(UART1_IRQn);
  371. UART1_RX_CALL = UART_CALL_FUN;
  372. G_UART1_RX_FUN = 1;
  373. }
  374. else
  375. {
  376. NVIC_SetPriority(UART2_IRQn, NVIC_PRIO_x);
  377. NVIC_EnableIRQ(UART2_IRQn);
  378. UART2_RX_CALL = UART_CALL_FUN;
  379. G_UART2_RX_FUN = 1;
  380. }
  381. /* UART 使能中断接收 */
  382. std_uart_cr1_interrupt_enable(uartx, UART_CR1_INTERRUPT_RXNE);
  383. }
  384. /*
  385. 函数:SN_UART_ORE_CALL(UART_t *uartx, void (*UART1_CALL_FUN)(void) );
  386. 功能:用户自己处理中断接收处理 (使用了该接口后就不能使用 SN_UART1_RX_BULL_set())
  387. 参数:UART1设备
  388. @UART1
  389. @UART2
  390. 参数:*UART1_CALL_FUN 自定义中断处理函数
  391. 返回:无
  392. */
  393. void SN_UART_ORE_CALL(UART_t *uartx, void (*UART_CALL_FUN)(void))
  394. {
  395. if (uartx == UART1)
  396. {
  397. UART1_ORE_CALL = UART_CALL_FUN;
  398. }
  399. else
  400. {
  401. UART2_ORE_CALL = UART_CALL_FUN;
  402. }
  403. }
  404. // 中断处理--------------------------------------------------------------------
  405. void UART1_IRQHandler(void)
  406. {
  407. static uint16_t len = 0;
  408. if (std_uart_get_cr1_interrupt_enable(UART1, UART_CR1_INTERRUPT_RXNE) && std_uart_get_flag(UART1, UART_FLAG_RXNE))
  409. {
  410. std_uart_clear_flag(UART1, UART_FLAG_RXNE);
  411. if (G_UART1_RX_FUN)
  412. {
  413. UART1_RX_CALL(); // 用户自定义处理
  414. }
  415. else
  416. {
  417. G_UART1_BULL[len++] = std_uart_rx_read_data(UART1); // 默认处理
  418. if (len >= G_UART1_BULL_LEN)
  419. {
  420. len = 0;
  421. }
  422. }
  423. }
  424. // ORE中断
  425. if (std_uart_get_flag(UART1, UART_FLAG_ORE))
  426. {
  427. std_uart_clear_flag(UART1, UART_CLEAR_ORE);
  428. UART1_ORE_CALL();
  429. }
  430. }
  431. // 中断处理--------------------------------------------------------------------
  432. void UART2_IRQHandler(void)
  433. {
  434. static uint16_t len1 = 0;
  435. if (std_uart_get_cr1_interrupt_enable(UART2, UART_CR1_INTERRUPT_RXNE) && std_uart_get_flag(UART2, UART_FLAG_RXNE))
  436. {
  437. std_uart_clear_flag(UART2, UART_FLAG_RXNE);
  438. if (G_UART2_RX_FUN)
  439. {
  440. UART2_RX_CALL(); // 用户自定义处理
  441. }
  442. else
  443. {
  444. G_UART1_BULL[len1++] = std_uart_rx_read_data(UART2); // 默认处理
  445. if (len1 >= G_UART2_BULL_LEN)
  446. {
  447. len1 = 0;
  448. }
  449. }
  450. }
  451. // ORE中断
  452. if (std_uart_get_flag(UART2, UART_FLAG_ORE))
  453. {
  454. std_uart_clear_flag(UART2, UART_CLEAR_ORE);
  455. UART2_ORE_CALL();
  456. }
  457. }
  458. /*
  459. 函数名称:SN_UART_Deinit(uint8 UART_X)
  460. 参数: UART1
  461. UART2
  462. 返回:无
  463. */
  464. void SN_UART_Deinit(UART_t *uartx)
  465. {
  466. std_uart_deinit(uartx);
  467. if (uartx == UART1)
  468. {
  469. std_rcc_apb2_clk_disable(RCC_PERIPH_CLK_UART1);
  470. }
  471. else if (uartx == UART2)
  472. {
  473. std_rcc_apb1_clk_disable(RCC_PERIPH_CLK_UART2);
  474. }
  475. }