#include "SN_UART.h" #include /* 文件名:SN_UART.c/.h 作者: SN_FAE_黄泽洪 免责声明:无版权,可随意传播和篡改,该代码仅供开发参考,如需使用请自行验证 本人不担负商业使用上带来的风险。 */ /* SN_UART 模块的使用方法 SN_UART.h 文件中的: SN_PRINTF_DEFAULT 的宏定义 //默认使用UART1作为printf() 注释掉这行宏定义就使用UART2作为printf() 方法1:使用printf() 修改头文件中的宏定义,选择UART1 或是 UART2 作为printf接口 int main(void){ SN_SYSCLK_set(SYSCLK_48MHZ); std_delay_init(); SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 ); while(1){ std_delayms(500); printf("CIU32F003,司诺电子一级代理\r\n"); } } 方法2:发送数组数据 uint8_t TX_BULL[8] = {1,2,3,4,5,6,7,8}; int main(void){ SN_SYSCLK_set(SYSCLK_48MHZ); std_delay_init(); SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 ); while(1){ std_delayms(500); SN_UART_TX_BULL(UART1,TX_BULL , 8); } } 方法3:接收数据到缓存数组中 uint8_t RX_BULL[8] = {0}; uint8_t val = 0; int main(void){ SN_SYSCLK_set(SYSCLK_48MHZ); std_delay_init(); SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 ); SN_UART_RX_BULL_set(UART1, RX_BULL ,8,NVIC_PRIO_2 );//设置缓冲区和缓冲区大小,并启动中断接收 while(1){ //用户直接处理自己数组内容 td_delayms(500); val = RX_BULL[0]; } } 方法4:接收数据自己处理 //用户自定义的处理函数 void fun(void){ RX_BULL[k++] = std_uart_rx_read_data(UART1); std_gpio_toggle_pin(LED_GPIO_PORT, LED_PIN); if(k == 8){ k = 0;} } int main(void){ //处理串口设置 SN_UART_init(UART1,9600, UART1_RX_PA4 ,UART1_TX_PA3 ); SN_UART_RX_CALL(UART1, fun, NVIC_PRIO_2 ); //UART1_CALL_FUN 是用户自己的代码处理逻辑 while(1){}; } 其他可用的std标准接口: std_uart_overrun_disable(UART_t *uartx) //关闭ORE std_uart_overrun_enable(UART_t *uartx) //开启ORE std_uart_cr1_interrupt_disable(UART_t *uartx, uint32_t interrupt) //关闭对应的中断 std_uart_cr1_interrupt_enable(UART_t *uartx, uint32_t interrupt) //开启对应的中断 其他接口访问: #include "ciu32f003_std_uart.h" */ /* 该函数是KEIL C 提供的标准printf重定向 必须勾选Micro LIB * @brief 重定向c库函数printf到串口,重定向后可使用printf函数 * @param ch 待发送字符 * @retval ch 发送的字符 */ #ifdef SN_PRINTF_DEFAULT int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ std_uart_tx_write_data(UART1, (uint32_t)ch); /* 等待发送完毕 */ while (!std_uart_get_flag(UART1, UART_FLAG_TXE)) ; return ch; } int fgetc(FILE *f) { /* 等待接收完毕 */ while (!std_uart_get_flag(UART1, UART_FLAG_RXNE)) ; return (int)std_uart_rx_read_data(UART2); } #else int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ std_uart_tx_write_data(UART2, (uint32_t)ch); /* 等待发送完毕 */ while (!std_uart_get_flag(UART2, UART_FLAG_TXE)) ; return ch; } int fgetc(FILE *f) { /* 等待接收完毕 */ while (!std_uart_get_flag(UART2, UART_FLAG_RXNE)) ; return (int)std_uart_rx_read_data(UART2); } #endif // UARTx_IO列表 const uint32_t UARTX_IO_list[] = { // TX UART1 GPIO_PIN_3, GPIO_PIN_6, GPIO_PIN_7, GPIO_PIN_0, GPIO_PIN_4, GPIO_PIN_6, GPIO_PIN_0, // RX GPIO_PIN_2, GPIO_PIN_4, GPIO_PIN_7, GPIO_PIN_5, GPIO_PIN_7, // TX UART2 GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, // RX GPIO_PIN_3, GPIO_PIN_6, GPIO_PIN_2, }; // 全局接收数组设定 uint8_t *G_UART1_BULL = NULL; // 全局接收数组长度设定 uint8_t G_UART1_BULL_LEN = 0; // 全局接收接口函数使用选择 uint8_t G_UART1_RX_FUN = 0; // 全局接收函数指针 void (*UART1_RX_CALL)(void) = NULL; // 全局ORE溢出函数指针 void (*UART1_ORE_CALL)(void) = NULL; // 全局接收数组设定 uint8_t *G_UART2_BULL = NULL; // 全局接收数组长度设定 uint8_t G_UART2_BULL_LEN = 0; // 全局接收接口函数使用选择 uint8_t G_UART2_RX_FUN = 0; // 全局接收函数指针 void (*UART2_RX_CALL)(void) = NULL; // 全局ORE溢出函数指针 void (*UART2_ORE_CALL)(void) = NULL; /* 函数:SN_UART1_init(uint32_t baudrate,uint16_t RX_IO,uint32_t TX_IO) 功能:初始化串口1 参数:UART1设备 @UART1 @UART2 参数:baudrate 波特率 参数:RX_IO 接收引脚IO #UART1_RX_PA2 #UART1_RX_PA4 #UART1_RX_PA7 #UART1_RX_PB5 #UART1_RX_PB7 #UART2_TX_PA4 #UART2_TX_PA5 #UART2_TX_PB6 参数:TX_IO 发送硬件IO #UART1_TX_PA3 #UART1_TX_PA6 #UART1_TX_PA7 #UART1_TX_PB0 #UART1_TX_PB4 #UART1_TX_PB6 #UART1_TX_PC0 (PC0该引脚需要修改选项字节之后才能使用,不推荐使用这个引脚) #UART2_RX_PA3 #UART2_RX_PA6 #UART2_RX_PB2 返回值:无 */ void SN_UART_init(UART_t *uartx, uint32_t baudrate, uint8_t RX_IO, uint8_t TX_IO) { GPIO_t *GPIO_X = NULL; std_gpio_init_t gpio_config = {0}; gpio_config.mode = GPIO_MODE_ALTERNATE; gpio_config.pull = GPIO_PULLUP; gpio_config.output_type = GPIO_OUTPUT_PUSHPULL; if (uartx == UART1) { // 设置TX if (TX_IO < 7) { if (TX_IO < 3) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA); GPIO_X = GPIOA; } else if (TX_IO < 6) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB); GPIO_X = GPIOB; } else if (TX_IO == 6) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOC); GPIO_X = GPIOC; } } gpio_config.pin = UARTX_IO_list[TX_IO]; gpio_config.alternate = GPIO_AF1_UART1; std_gpio_init(GPIO_X, &gpio_config); // 设置RX GPIO_X = NULL; if (RX_IO > 7) { if (RX_IO < 10) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA); GPIO_X = GPIOA; if (RX_IO == 9) { gpio_config.alternate = GPIO_AF5_UART1; } } else if (RX_IO < 12) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB); GPIO_X = GPIOB; } } gpio_config.pin = UARTX_IO_list[RX_IO]; std_gpio_init(GPIO_X, &gpio_config); } else { gpio_config.alternate = GPIO_AF5_UART2; // 设置TX if (TX_IO < 15) { if (TX_IO < 14) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA); GPIO_X = GPIOA; } else if (TX_IO == 14) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB); GPIO_X = GPIOB; } } gpio_config.pin = UARTX_IO_list[TX_IO]; std_gpio_init(GPIO_X, &gpio_config); // 设置RX GPIO_X = NULL; if (RX_IO > 14) { if (RX_IO < 17) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOA); GPIO_X = GPIOA; } else if (RX_IO == 17) { std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB); GPIO_X = GPIOB; } } gpio_config.pin = UARTX_IO_list[RX_IO]; std_gpio_init(GPIO_X, &gpio_config); } // 初始串口 std_uart_init_t uart_confg = {0}; /* UART 时钟使能 */ if (uartx == UART1) { std_rcc_apb2_clk_enable(RCC_PERIPH_CLK_UART1); } else { std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_UART2); } /* UART 初始化 */ uart_confg.baudrate = baudrate; uart_confg.direction = UART_DIRECTION_SEND_RECEIVE; uart_confg.wordlength = UART_WORDLENGTH_8BITS; uart_confg.stopbits = UART_STOPBITS_1; uart_confg.parity = UART_PARITY_NONE; std_uart_init(uartx, &uart_confg); /* 使能UART */ std_uart_enable(uartx); } /* 函数:SN_UART_TX_BULL(UART_t *uartx ,uint8_t * BULL , uint16_t BULL_LEN) 功能:通过UART发送一组数据 参数:UART1设备 @UART1 @UART2 参数:BULL 数据数组 参数:BULL_LEN 数据数组长度 */ void SN_UART_TX_BULL(UART_t *uartx, uint8_t *BULL, uint16_t BULL_LEN) { for (int i = 0; i < BULL_LEN; i++) { while (!std_uart_get_flag(uartx, UART_FLAG_TXE)) ; std_uart_tx_write_data(uartx, BULL[i]); } while (!std_uart_get_flag(uartx, UART_FLAG_TC)) ; } /* 函数:SN_UART1_RX_BULL_set(UART_t *uartx ,uint8_t * BULL,uint16_t BULL_LEN ); 功能:设置自动接收的数组(缓冲区) 使用了该接口后就不能使用SN_UART1_RX_CALL() 参数:UART1设备 @UART1 @UART2 参数:BULL 数据数组 参数:BULL_LEN 长度大小 参数:NVIC_PRIO_X 中断优先级 @NVIC_PRIO_0 高 @NVIC_PRIO_1 @NVIC_PRIO_2 @NVIC_PRIO_3 低 返回:无 */ void SN_UART_RX_BULL_set(UART_t *uartx, uint8_t *BULL, uint16_t BULL_LEN, uint16_t NVIC_PRIO_x) { /* 配置UART1中断优先级以及使能UART1的NVIC中断 */ if (uartx == UART1) { G_UART1_BULL = BULL; G_UART1_BULL_LEN = BULL_LEN; NVIC_SetPriority(UART1_IRQn, NVIC_PRIO_x); NVIC_EnableIRQ(UART1_IRQn); } else { G_UART2_BULL = BULL; G_UART2_BULL_LEN = BULL_LEN; NVIC_SetPriority(UART2_IRQn, NVIC_PRIO_x); NVIC_EnableIRQ(UART2_IRQn); } /* UART 使能中断接收 */ std_uart_cr1_interrupt_enable(uartx, UART_CR1_INTERRUPT_RXNE); } /* 函数:SN_UART1_RX_CALL(UART_t *uartx, void (*UART1_CALL_FUN)(void),uint16_t NVIC_PRIO_x ); 功能:用户自己处理中断接收处理 (使用了该接口后就不能使用 SN_UART1_RX_BULL_set()) 参数:UART1设备 @UART1 @UART2 参数:*UART1_CALL_FUN 自定义中断处理函数 参数:NVIC_PRIO_X 中断优先级 @NVIC_PRIO_0 @NVIC_PRIO_1 @NVIC_PRIO_2 @NVIC_PRIO_3 返回:无 */ void SN_UART_RX_CALL(UART_t *uartx, void (*UART_CALL_FUN)(void), uint16_t NVIC_PRIO_x) { /* 配置UART1中断优先级以及使能UART1的NVIC中断 */ if (uartx == UART1) { NVIC_SetPriority(UART1_IRQn, NVIC_PRIO_x); NVIC_EnableIRQ(UART1_IRQn); UART1_RX_CALL = UART_CALL_FUN; G_UART1_RX_FUN = 1; } else { NVIC_SetPriority(UART2_IRQn, NVIC_PRIO_x); NVIC_EnableIRQ(UART2_IRQn); UART2_RX_CALL = UART_CALL_FUN; G_UART2_RX_FUN = 1; } /* UART 使能中断接收 */ std_uart_cr1_interrupt_enable(uartx, UART_CR1_INTERRUPT_RXNE); } /* 函数:SN_UART_ORE_CALL(UART_t *uartx, void (*UART1_CALL_FUN)(void) ); 功能:用户自己处理中断接收处理 (使用了该接口后就不能使用 SN_UART1_RX_BULL_set()) 参数:UART1设备 @UART1 @UART2 参数:*UART1_CALL_FUN 自定义中断处理函数 返回:无 */ void SN_UART_ORE_CALL(UART_t *uartx, void (*UART_CALL_FUN)(void)) { if (uartx == UART1) { UART1_ORE_CALL = UART_CALL_FUN; } else { UART2_ORE_CALL = UART_CALL_FUN; } } // 中断处理-------------------------------------------------------------------- void UART1_IRQHandler(void) { static uint16_t len = 0; if (std_uart_get_cr1_interrupt_enable(UART1, UART_CR1_INTERRUPT_RXNE) && std_uart_get_flag(UART1, UART_FLAG_RXNE)) { std_uart_clear_flag(UART1, UART_FLAG_RXNE); if (G_UART1_RX_FUN) { UART1_RX_CALL(); // 用户自定义处理 } else { G_UART1_BULL[len++] = std_uart_rx_read_data(UART1); // 默认处理 if (len >= G_UART1_BULL_LEN) { len = 0; } } } // ORE中断 if (std_uart_get_flag(UART1, UART_FLAG_ORE)) { std_uart_clear_flag(UART1, UART_CLEAR_ORE); UART1_ORE_CALL(); } } // 中断处理-------------------------------------------------------------------- void UART2_IRQHandler(void) { static uint16_t len1 = 0; if (std_uart_get_cr1_interrupt_enable(UART2, UART_CR1_INTERRUPT_RXNE) && std_uart_get_flag(UART2, UART_FLAG_RXNE)) { std_uart_clear_flag(UART2, UART_FLAG_RXNE); if (G_UART2_RX_FUN) { UART2_RX_CALL(); // 用户自定义处理 } else { G_UART1_BULL[len1++] = std_uart_rx_read_data(UART2); // 默认处理 if (len1 >= G_UART2_BULL_LEN) { len1 = 0; } } } // ORE中断 if (std_uart_get_flag(UART2, UART_FLAG_ORE)) { std_uart_clear_flag(UART2, UART_CLEAR_ORE); UART2_ORE_CALL(); } } /* 函数名称:SN_UART_Deinit(uint8 UART_X) 参数: UART1 UART2 返回:无 */ void SN_UART_Deinit(UART_t *uartx) { std_uart_deinit(uartx); if (uartx == UART1) { std_rcc_apb2_clk_disable(RCC_PERIPH_CLK_UART1); } else if (uartx == UART2) { std_rcc_apb1_clk_disable(RCC_PERIPH_CLK_UART2); } }