#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); } }