/**** *****串口通信模块 *****在中断中接收数据 *****数据存放环形缓冲队列中 *****创建串口接收任务 *****创建中断接收函数 *****创建串口发送函数 ****/ #include "Usart.h" #include "ptz_struct.h" #include "gd32f4xx_it.h" device_handle uart_485_handle = 0; device_handle uart_422_handle = 0; BSP_OS_SEM ser_mutex;//用于锁调用发生一个字节函数 uart_device_info uart_devices[6]={ // init index { 0, 0,}, { 0, 1,}, { 0, 2,}, { 0, 3,}, { 0, 4,}, { 0, 5,} }; RingQueue ring_que; u_int8_t ptz_uart_buff[10]; //串口 //RS422 u_int8_t ptz_uart_422_buff[PTZ_UART_422_BUFF_SIZE]; char uart_422_state = 0; //RS485 u_int8_t ptz_uart_485_buff[PTZ_UART_485_BUFF_SIZE]; char uart_485_state = 0; int bata; char uart_data; /// @brief 初始化串口引脚、波特率 /// @param[in] usart_periph:USARTx(x=0,1,2) /// @param[in] baud:波特率 /// @return none /// @note 修改日志 /// LH于2022-05-20 static void usart_config(uint32_t usart_periph, int baud) { switch(usart_periph) { case TEST://串口0,调试端口 //使能端口时钟 rcu_periph_clock_enable(RCU_GPIOA); //使能串口时钟 rcu_periph_clock_enable(RCU_USART0); gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);//TX gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);//RX gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_9); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9); gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_10); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10); break; case UART_485://串口1,485 //使能端口时钟 rcu_periph_clock_enable(RCU_GPIOD); //使能串口时钟 rcu_periph_clock_enable(RCU_USART1); gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);//TX gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);//RX gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_5); gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5); gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_6); gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6); ///收发模式选择 gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_7); gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7); break; case UART_422://串口2,422 //使能端口时钟 rcu_periph_clock_enable(RCU_GPIOD); //使能串口时钟 rcu_periph_clock_enable(RCU_USART2); gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_8);//TX gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_9);//RX gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_8); gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8); gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_NONE,GPIO_PIN_9); gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9); break; default: break; } ///串口配置使能 usart_deinit(usart_periph);//时钟复位 usart_baudrate_set(usart_periph,baud);//设置波特率,默认9600 usart_receive_config(usart_periph, USART_RECEIVE_ENABLE);//接收使能 usart_transmit_config(usart_periph, USART_TRANSMIT_ENABLE);//发送使能 usart_enable(usart_periph);//串口使能 //使能接收中断 usart_interrupt_enable(usart_periph, USART_INT_RBNE); } /// @brief 中断嵌套向量配置 /// @param[in] usart_periph:USARTx(x=0,1,2) /// @return none /// @note 修改日志 /// LH于2022-05-20 static void Usart_Nvic_config(uint32_t usart_periph) { switch(usart_periph) { case TEST://串口0,调试端口 //使能串口中断请求 nvic_irq_enable(USART0_IRQn, 4, 0);//抢占优先级配置为3,子优先及为0,比以太网低,以太网为2 break; case UART_485://串口1,485 nvic_irq_enable(USART1_IRQn, 3, 0);//优先级配置为3,子优先及为1 break; case UART_422://串口2,422 nvic_irq_enable(USART2_IRQn, 3, 1);//优先级配置为3,子优先及为2 break; default: break; } } /// @brief 初始化环形队列、资源锁 /// @param[in] usart_periph:USARTx(x=0,1,2) /// @param[in] index:设备端口 /// @param[in] *buff:队列地址 /// @param[in] buff_size:队列长度 /// @return device_handle:设备地址 /// @note 修改日志 /// LH于2022-05-20 device_handle uart_init(uint32_t usart_periph, uint32_t index, u_int8_t *buff, int buff_size) { if(!uart_devices[index].init) {//没有初始化 InitRingQueue(&uart_devices[index].uart_ring_queue, buff, buff_size); //初始化环形队列缓存 BSP_OS_SemCreate(&uart_devices[index].port_mutex,1u,"port mutex"); BSP_OS_SemCreate(&uart_devices[index].ser_mutex,1u,"serial mutex"); BSP_OS_SemCreate(&uart_devices[index].sem_recv_data,0u,"sem recv data"); uart_devices[index].init = 1; } return (device_handle)(&uart_devices[index]); } /// @brief 串口设备初始化 /// @param[in] none /// @return none /// @note 修改日志 /// LH于2022-05-20 static void Uart_Init(void) { ///485串口设备初始化UART_485 usart_config(UART_485, g_ptz.uart_485_baud);//串口初始化 Usart_Nvic_config(UART_485);//中断配置 uart_485_handle = uart_init(UART_485, PTZ_UART_485_INDEX, ptz_uart_485_buff, sizeof(ptz_uart_485_buff)); BSP_IntVectSet(54,USART1_IRQHandler); BSP_IntEn(54); ///422串口设备初始化 usart_config(UART_422, g_ptz.uart_422_baud);//串口初始化 Usart_Nvic_config(UART_422);//中断配置 uart_422_handle = uart_init(UART_422, PTZ_UART_422_INDEX, ptz_uart_422_buff, sizeof(ptz_uart_422_buff)); BSP_IntVectSet(55,USART2_IRQHandler); BSP_IntEn(55); } /// @brief 485接收中断处理数据 /// @param[in] data: /// @return none /// @note 修改日志 /// LH于2022-05-20 void IRQHandler_485_process(u_int8_t data) { uart_device_info *dev = (uart_device_info *)uart_485_handle;//终端交互 if(!RingQueueFull(&dev->uart_ring_queue)) { InRingQueue(&dev->uart_ring_queue, data); } } /// @brief 422接收中断处理数据 /// @param[in] data: /// @return none /// @note 修改日志 /// LH于2022-05-20 void IRQHandler_422_process(u_int8_t data) { uart_device_info *dev = (uart_device_info *)uart_422_handle;//终端交互 if(!RingQueueFull(&dev->uart_ring_queue)) { InRingQueue(&dev->uart_ring_queue, data); } } ///串口设备发送数据 void ptz_uart_dev_send(device_handle device, void *data, int len) { unsigned char buff; uart_device_info *device_info = (uart_device_info *)device; if((!device) || (!device_info->init)) { return; } BSP_OS_SemWait(&device_info->ser_mutex, 0u); if(device == uart_485_handle) { PTZ_UART_485_TX; OSTimeDlyHMSM(0u, 0u, 0u, 10u); for (int i = 0; i 0) { OSTimeDlyHMSM(0u, 0u, 0u, 2u); } } OSTimeDlyHMSM(0u, 0u, 0u, 10u); PTZ_UART_485_RX; } if(device == uart_422_handle) { for (int i = 0; i 0) { OSTimeDlyHMSM(0u, 0u, 0u, 2u); } } } BSP_OS_SemPost(&device_info->ser_mutex); } /******************************************************************************* ** 函数名称: ** 功 能:串口设备缓冲区是否有数据 ** 入口参数: ** 出口参数: ********************************************************************************/ int uart_dev_char_present(device_handle device) { uart_device_info *device_info = (uart_device_info *)device; if((!device) || (!device_info->init)) return 0; return !RingQueueEmpty(&device_info->uart_ring_queue); } /******************************************************************************* ** 函数名称: ** 功 能:串口设备从缓冲区读入一个数据 ** 入口参数: ** 出口参数: ********************************************************************************/ char uart_dev_in_char(device_handle device) { uart_device_info *device_info = (uart_device_info *)device; char c = 0; if (uart_dev_char_present(device)) //等待环形队列缓存区有数据 OutRingQueue(&device_info->uart_ring_queue, (u_int8_t*)&c); return c; } //串口设备从缓冲区读入一个数据 char ptz_uart_dev_in_char(device_handle device) { uart_device_info *device_info = (uart_device_info *)device; char c = 0; if (uart_dev_char_present(device)) //等待环形队列缓存区有数据 OutRingQueue(&device_info->uart_ring_queue, (u_int8_t*)&c); return c; } //串口设备缓冲区是否有数据 int ptz_uart_dev_char_present(device_handle device) { uart_device_info *device_info = (uart_device_info *)device; if((!device) || (!device_info->init)) return 0; return !RingQueueEmpty(&device_info->uart_ring_queue); } void Usart_init_module() { Uart_Init(); } //初始化终端串口 void init_term_uart() { //使能端口时钟 rcu_periph_clock_enable(RCU_GPIOA); //使能串口时钟 rcu_periph_clock_enable(RCU_USART0); /* connect port to USARTx_Tx */ gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9); /* connect port to USARTx_Rx */ gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10); /* configure USART Tx as alternate function push-pull */ gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_9); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9); /* configure USART Rx as alternate function push-pull */ gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10); /* USART configure */ usart_deinit(USART0);//时钟复位 usart_baudrate_set(USART0,9600U);//设置波特率 usart_receive_config(USART0, USART_RECEIVE_ENABLE);//接收使能 usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);//发送使能 usart_enable(USART0);//串口使能 // BSP_OS_SemCreate(&ser_mutex,0u,"udp_send_data_mutex"); }