SN_UART.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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. return ch;
  82. }
  83. int fgetc(FILE*f){
  84. /* 等待接收完毕 */
  85. while(!std_uart_get_flag(UART1,UART_FLAG_RXNE));
  86. return (int) std_uart_rx_read_data(UART2);
  87. }
  88. #else
  89. int fputc(int ch, FILE *f)
  90. {
  91. /* 发送一个字节数据到串口 */
  92. std_uart_tx_write_data(UART2, (uint32_t)ch);
  93. /* 等待发送完毕 */
  94. while(! std_uart_get_flag(UART2,UART_FLAG_TXE));
  95. return ch;
  96. }
  97. int fgetc(FILE*f){
  98. /* 等待接收完毕 */
  99. while(! std_uart_get_flag(UART2,UART_FLAG_RXNE));
  100. return (int) std_uart_rx_read_data(UART2);
  101. }
  102. #endif
  103. //UARTx_IO列表
  104. const uint32_t UARTX_IO_list[] =
  105. {
  106. //TX UART1
  107. GPIO_PIN_3,
  108. GPIO_PIN_6,
  109. GPIO_PIN_7,
  110. GPIO_PIN_0,
  111. GPIO_PIN_4,
  112. GPIO_PIN_6,
  113. GPIO_PIN_0,
  114. //RX
  115. GPIO_PIN_2,
  116. GPIO_PIN_4,
  117. GPIO_PIN_7,
  118. GPIO_PIN_5,
  119. GPIO_PIN_7,
  120. //TX UART2
  121. GPIO_PIN_4,
  122. GPIO_PIN_5,
  123. GPIO_PIN_6,
  124. //RX
  125. GPIO_PIN_3,
  126. GPIO_PIN_6,
  127. GPIO_PIN_2,
  128. };
  129. //全局接收数组设定
  130. uint8_t * G_UART1_BULL = NULL;
  131. //全局接收数组长度设定
  132. uint8_t G_UART1_BULL_LEN = 0;
  133. //全局接收接口函数使用选择
  134. uint8_t G_UART1_RX_FUN = 0;
  135. //全局接收函数指针
  136. void (*UART1_RX_CALL) (void) = NULL;
  137. //全局ORE溢出函数指针
  138. void (*UART1_ORE_CALL) (void) = NULL;
  139. //全局接收数组设定
  140. uint8_t * G_UART2_BULL = NULL;
  141. //全局接收数组长度设定
  142. uint8_t G_UART2_BULL_LEN = 0;
  143. //全局接收接口函数使用选择
  144. uint8_t G_UART2_RX_FUN = 0;
  145. //全局接收函数指针
  146. void (*UART2_RX_CALL) (void) = NULL;
  147. //全局ORE溢出函数指针
  148. void (*UART2_ORE_CALL) (void) = NULL;
  149. /*
  150. 函数:SN_UART1_init(uint32_t baudrate,uint16_t RX_IO,uint32_t TX_IO)
  151. 功能:初始化串口1
  152. 参数:UART1设备
  153. @UART1
  154. @UART2
  155. 参数:baudrate 波特率
  156. 参数:RX_IO 接收引脚IO
  157. #UART1_RX_PA2
  158. #UART1_RX_PA4
  159. #UART1_RX_PA7
  160. #UART1_RX_PB5
  161. #UART1_RX_PB7
  162. #UART2_TX_PA4
  163. #UART2_TX_PA5
  164. #UART2_TX_PB6
  165. 参数:TX_IO 发送硬件IO
  166. #UART1_TX_PA3
  167. #UART1_TX_PA6
  168. #UART1_TX_PA7
  169. #UART1_TX_PB0
  170. #UART1_TX_PB4
  171. #UART1_TX_PB6
  172. #UART1_TX_PC0 (PC0该引脚需要修改选项字节之后才能使用,不推荐使用这个引脚)
  173. #UART2_RX_PA3
  174. #UART2_RX_PA6
  175. #UART2_RX_PB2
  176. 返回值:无
  177. */
  178. void SN_UART_init(UART_t *uartx,uint32_t baudrate,uint8_t RX_IO,uint8_t TX_IO)
  179. {
  180. GPIO_t * GPIO_X = NULL;
  181. std_gpio_init_t gpio_config = {0} ;
  182. gpio_config.mode = GPIO_MODE_ALTERNATE;
  183. gpio_config.pull = GPIO_PULLUP;
  184. gpio_config.output_type = GPIO_OUTPUT_PUSHPULL;
  185. if(uartx == UART1 ){
  186. //设置TX
  187. if(TX_IO < 7){
  188. if( TX_IO < 3 ){
  189. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  190. GPIO_X = GPIOA;
  191. }else if(TX_IO < 6 ) {
  192. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  193. GPIO_X = GPIOB;
  194. }else if(TX_IO == 6){
  195. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOC);
  196. GPIO_X = GPIOC;
  197. }
  198. }
  199. gpio_config.pin = UARTX_IO_list[TX_IO];
  200. gpio_config.alternate = GPIO_AF1_UART1;
  201. std_gpio_init(GPIO_X,&gpio_config);
  202. //设置RX
  203. GPIO_X = NULL;
  204. if(RX_IO > 7){
  205. if( RX_IO < 10 ){
  206. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  207. GPIO_X = GPIOA;
  208. if(RX_IO == 9){gpio_config.alternate = GPIO_AF5_UART1;}
  209. }else if(RX_IO < 12){
  210. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  211. GPIO_X = GPIOB;
  212. }
  213. }
  214. gpio_config.pin = UARTX_IO_list[RX_IO];
  215. std_gpio_init(GPIO_X,&gpio_config);
  216. }else{
  217. gpio_config.alternate = GPIO_AF5_UART2;
  218. //设置TX
  219. if(TX_IO < 15 ){
  220. if(TX_IO < 14){
  221. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  222. GPIO_X = GPIOA;
  223. }else if(TX_IO == 14){
  224. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  225. GPIO_X = GPIOB;
  226. }
  227. }
  228. gpio_config.pin = UARTX_IO_list[TX_IO];
  229. std_gpio_init(GPIO_X,&gpio_config);
  230. //设置RX
  231. GPIO_X = NULL;
  232. if(RX_IO > 14 ){
  233. if(RX_IO < 17){
  234. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA);
  235. GPIO_X = GPIOA;
  236. }else if(RX_IO == 17){
  237. std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB);
  238. GPIO_X = GPIOB;
  239. }
  240. }
  241. gpio_config.pin = UARTX_IO_list[RX_IO];
  242. std_gpio_init(GPIO_X,&gpio_config);
  243. }
  244. //初始串口
  245. std_uart_init_t uart_confg = {0};
  246. /* UART 时钟使能 */
  247. if(uartx == UART1 ){ std_rcc_apb2_clk_enable(RCC_PERIPH_CLK_UART1);}
  248. else{std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_UART2);}
  249. /* UART 初始化 */
  250. uart_confg.baudrate = baudrate;
  251. uart_confg.direction = UART_DIRECTION_SEND_RECEIVE;
  252. uart_confg.wordlength = UART_WORDLENGTH_8BITS;
  253. uart_confg.stopbits = UART_STOPBITS_1;
  254. uart_confg.parity = UART_PARITY_NONE;
  255. std_uart_init(uartx,&uart_confg);
  256. /* 使能UART */
  257. std_uart_enable(uartx);
  258. }
  259. /*
  260. 函数:SN_UART_TX_BULL(UART_t *uartx ,uint8_t * BULL , uint16_t BULL_LEN)
  261. 功能:通过UART发送一组数据
  262. 参数:UART1设备
  263. @UART1
  264. @UART2
  265. 参数:BULL 数据数组
  266. 参数:BULL_LEN 数据数组长度
  267. */
  268. void SN_UART_TX_BULL( UART_t *uartx, uint8_t * BULL , uint16_t BULL_LEN){
  269. for(int i = 0 ; i < BULL_LEN ;i++){
  270. while(! std_uart_get_flag(uartx,UART_FLAG_TXE));
  271. std_uart_tx_write_data(uartx, BULL[i]);
  272. }
  273. while(! std_uart_get_flag(uartx,UART_FLAG_TC));
  274. }
  275. /*
  276. 函数:SN_UART1_RX_BULL_set(UART_t *uartx ,uint8_t * BULL,uint16_t BULL_LEN );
  277. 功能:设置自动接收的数组(缓冲区) 使用了该接口后就不能使用SN_UART1_RX_CALL()
  278. 参数:UART1设备
  279. @UART1
  280. @UART2
  281. 参数:BULL 数据数组
  282. 参数:BULL_LEN 长度大小
  283. 参数:NVIC_PRIO_X 中断优先级
  284. @NVIC_PRIO_0 高
  285. @NVIC_PRIO_1
  286. @NVIC_PRIO_2
  287. @NVIC_PRIO_3 低
  288. 返回:无
  289. */
  290. void SN_UART_RX_BULL_set( UART_t *uartx, uint8_t * BULL ,uint16_t BULL_LEN, uint16_t NVIC_PRIO_x){
  291. /* 配置UART1中断优先级以及使能UART1的NVIC中断 */
  292. if(uartx == UART1){
  293. G_UART1_BULL = BULL;
  294. G_UART1_BULL_LEN = BULL_LEN;
  295. NVIC_SetPriority(UART1_IRQn,NVIC_PRIO_x);
  296. NVIC_EnableIRQ(UART1_IRQn);
  297. }else{
  298. G_UART2_BULL = BULL;
  299. G_UART2_BULL_LEN = BULL_LEN;
  300. NVIC_SetPriority(UART2_IRQn,NVIC_PRIO_x);
  301. NVIC_EnableIRQ(UART2_IRQn);
  302. }
  303. /* UART 使能中断接收 */
  304. std_uart_cr1_interrupt_enable(uartx,UART_CR1_INTERRUPT_RXNE);
  305. }
  306. /*
  307. 函数:SN_UART1_RX_CALL(UART_t *uartx, void (*UART1_CALL_FUN)(void),uint16_t NVIC_PRIO_x );
  308. 功能:用户自己处理中断接收处理 (使用了该接口后就不能使用 SN_UART1_RX_BULL_set())
  309. 参数:UART1设备
  310. @UART1
  311. @UART2
  312. 参数:*UART1_CALL_FUN 自定义中断处理函数
  313. 参数:NVIC_PRIO_X 中断优先级
  314. @NVIC_PRIO_0
  315. @NVIC_PRIO_1
  316. @NVIC_PRIO_2
  317. @NVIC_PRIO_3
  318. 返回:无
  319. */
  320. void SN_UART_RX_CALL( UART_t *uartx , void (*UART_CALL_FUN)(void),uint16_t NVIC_PRIO_x ){
  321. /* 配置UART1中断优先级以及使能UART1的NVIC中断 */
  322. if(uartx == UART1){
  323. NVIC_SetPriority(UART1_IRQn,NVIC_PRIO_x);
  324. NVIC_EnableIRQ(UART1_IRQn);
  325. UART1_RX_CALL = UART_CALL_FUN;
  326. G_UART1_RX_FUN = 1;
  327. }else{
  328. NVIC_SetPriority(UART2_IRQn,NVIC_PRIO_x);
  329. NVIC_EnableIRQ(UART2_IRQn);
  330. UART2_RX_CALL = UART_CALL_FUN;
  331. G_UART2_RX_FUN = 1;
  332. }
  333. /* UART 使能中断接收 */
  334. std_uart_cr1_interrupt_enable(uartx,UART_CR1_INTERRUPT_RXNE);
  335. }
  336. /*
  337. 函数:SN_UART_ORE_CALL(UART_t *uartx, void (*UART1_CALL_FUN)(void) );
  338. 功能:用户自己处理中断接收处理 (使用了该接口后就不能使用 SN_UART1_RX_BULL_set())
  339. 参数:UART1设备
  340. @UART1
  341. @UART2
  342. 参数:*UART1_CALL_FUN 自定义中断处理函数
  343. 返回:无
  344. */
  345. void SN_UART_ORE_CALL(UART_t *uartx , void (*UART_CALL_FUN)(void)){
  346. if(uartx == UART1){
  347. UART1_ORE_CALL = UART_CALL_FUN;
  348. }else{
  349. UART2_ORE_CALL = UART_CALL_FUN;
  350. }
  351. }
  352. //中断处理--------------------------------------------------------------------
  353. void UART1_IRQHandler(void){
  354. static uint16_t len = 0;
  355. if(std_uart_get_cr1_interrupt_enable(UART1,UART_CR1_INTERRUPT_RXNE) \
  356. && std_uart_get_flag(UART1,UART_FLAG_RXNE))
  357. { std_uart_clear_flag(UART1,UART_FLAG_RXNE);
  358. if(G_UART1_RX_FUN){
  359. UART1_RX_CALL(); //用户自定义处理
  360. }else{
  361. G_UART1_BULL[len++] = std_uart_rx_read_data(UART1); //默认处理
  362. if(len >= G_UART1_BULL_LEN){
  363. len = 0;
  364. }
  365. }
  366. }
  367. //ORE中断
  368. if(std_uart_get_flag(UART1,UART_FLAG_ORE)){
  369. std_uart_clear_flag(UART1,UART_CLEAR_ORE);
  370. UART1_ORE_CALL();
  371. }
  372. }
  373. //中断处理--------------------------------------------------------------------
  374. void UART2_IRQHandler(void){
  375. static uint16_t len1 = 0;
  376. if(std_uart_get_cr1_interrupt_enable(UART2,UART_CR1_INTERRUPT_RXNE) \
  377. && std_uart_get_flag(UART2,UART_FLAG_RXNE))
  378. { std_uart_clear_flag(UART2,UART_FLAG_RXNE);
  379. if(G_UART2_RX_FUN){
  380. UART2_RX_CALL(); //用户自定义处理
  381. }else{
  382. G_UART1_BULL[len1++] = std_uart_rx_read_data(UART2); //默认处理
  383. if(len1 >= G_UART2_BULL_LEN){
  384. len1 = 0;
  385. }
  386. }
  387. }
  388. //ORE中断
  389. if(std_uart_get_flag(UART2,UART_FLAG_ORE)){
  390. std_uart_clear_flag(UART2,UART_CLEAR_ORE);
  391. UART2_ORE_CALL();
  392. }
  393. }
  394. /*
  395. 函数名称:SN_UART_Deinit(uint8 UART_X)
  396. 参数: UART1
  397. UART2
  398. 返回:无
  399. */
  400. void SN_UART_Deinit(UART_t *uartx){
  401. std_uart_deinit(uartx);
  402. if(uartx == UART1){
  403. std_rcc_apb2_clk_disable(RCC_PERIPH_CLK_UART1);
  404. }else if(uartx == UART2){
  405. std_rcc_apb1_clk_disable(RCC_PERIPH_CLK_UART2);
  406. }
  407. }