///********************************************************************************************************* //* 模块名称:Uart1.c //* 摘 要:串口模块,包括串口模块初始化,以及中断服务函数处理,以及读写串口函数实现 //* 当前版本:1.0.0 //* 作 者:Leyutek(COPYRIGHT 2018 - 2021 Leyutek. All rights reserved.) //* 完成日期:2021年07月01日 //* 内 容: //* 注 意: //********************************************************************************************************** //* 取代版本: //* 作 者: //* 完成日期: //* 修改内容: //* 修改文件: //*********************************************************************************************************/ ///********************************************************************************************************* //* 包含头文件 //*********************************************************************************************************/ //#include "Uart1.h" //#include "gd32e230x_conf.h" //#include "Queue.h" ///********************************************************************************************************* //* 宏定义 //*********************************************************************************************************/ ///********************************************************************************************************* //* 枚举结构体 //*********************************************************************************************************/ ////串口发送状态 //typedef enum //{ // UART_STATE_OFF, //串口未发送数据 // UART_STATE_ON, //串口正在发送数据 // UART_STATE_MAX //}EnumUARTState; ///********************************************************************************************************* //* 内部变量定义 //*********************************************************************************************************/ //static StructCirQue s_structUARTSendCirQue; //发送串口循环队列 //static StructCirQue s_structUARTRecCirQue; //接收串口循环队列 //static unsigned char s_arrSendBuf[UART1_BUF_SIZE]; //发送串口循环队列的缓冲区 //static unsigned char s_arrRecBuf[UART1_BUF_SIZE]; //接收串口循环队列的缓冲区 //static unsigned char s_iUARTTxSts; //串口发送数据状态 // ///********************************************************************************************************* //* 内部函数声明 //*********************************************************************************************************/ //static void InitUARTBuf(void); //初始化串口缓冲区,包括发送缓冲区和接收缓冲区 //static unsigned char WriteReceiveBuf(unsigned char d); //将接收到的数据写入接收缓冲区 //static unsigned char ReadSendBuf(unsigned char *p); //读取发送缓冲区中的数据 //static void ConfigUART0(unsigned int bound); //配置串口相关的参数,包括GPIO、RCU、UART和NVIC //static void EnableUARTTx(void); //使能串口发送,WriteUARTx中调用,每次发送数据之后需要调用 // ///********************************************************************************************************* //* 内部函数实现 //*********************************************************************************************************/ ///********************************************************************************************************* //* 函数名称:InitUARTBuf //* 函数功能:初始化串口缓冲区,包括发送缓冲区和接收缓冲区 //* 输入参数:void //* 输出参数:void //* 返 回 值:void //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //static void InitUARTBuf(void) //{ // short i; // for(i = 0; i < UART1_BUF_SIZE; i++) // { // s_arrSendBuf[i] = 0; // s_arrRecBuf[i] = 0; // } // InitQueue(&s_structUARTSendCirQue, s_arrSendBuf, UART1_BUF_SIZE); // InitQueue(&s_structUARTRecCirQue, s_arrRecBuf, UART1_BUF_SIZE); //} ///********************************************************************************************************* //* 函数名称:WriteReceiveBuf //* 函数功能:写数据到串口接收缓冲区 //* 输入参数:d,待写入串口接收缓冲区的数据 //* 输出参数:void //* 返 回 值:写入数据成功标志,0-不成功,1-成功 //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //static unsigned char WriteReceiveBuf(unsigned char d) //{ // unsigned char ok = 0; //写入数据成功标志,0-不成功,1-成功 // // ok = EnQueue(&s_structUARTRecCirQue, &d, 1); // // return ok; //返回写入数据成功标志,0-不成功,1-成功 //} ///********************************************************************************************************* //* 函数名称:ReadSendBuf //* 函数功能:读取串口发送缓冲区中的数据 //* 输入参数:p,读出来的数据存放的首地址 //* 输出参数:p,读出来的数据存放的首地址 //* 返 回 值:读取数据成功标志,0-不成功,1-成功 //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //static unsigned char ReadSendBuf(unsigned char *p) //{ // unsigned char ok = 0; //读取数据成功标志,0-不成功,1-成功 // // ok = DeQueue(&s_structUARTSendCirQue, p, 1); // // return ok; //返回读取数据成功标志,0-不成功,1-成功 //} ///********************************************************************************************************* //* 函数名称:ConfigCH448FGPIO //* 函数功能:配置CH448F的切换GPIO //* 输入参数:void //* 输出参数:void //* 返 回 值:void //* 创建日期:2021年07月01日 //* 注 意:真值表 //* XEN# YEN# SEL2 SEL1 SEL0 AX AY //* 0 0 0 0 0 选择A0X 选择A0Y //* 0 0 0 0 1 选择A1X 选择A1Y //* 0 0 0 1 0 选择A2X 选择A2Y //* 0 0 0 1 1 选择A3X 选择A3Y //* 0 0 1 0 0 选择A4X 选择A4Y //* 0 0 1 0 1 选择A5X 选择A5Y //* 0 0 1 1 0 选择A6X 选择A6Y //* 0 0 1 1 1 选择A7X 选择A7Y //* 1 1 X X X 全部断开 全部断开 //*********************************************************************************************************/ //static void ConfigCH448FGPIO(void) //{ // //使能RCU相关时钟 // rcu_periph_clock_enable(RCU_GPIOA); //使能GPIOB的时钟 // gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, XEN); //设置GPIO模式 // gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, XEN); //设置GPIO输出模式及速度 // gpio_bit_set(XYEN_SEL0_1_RCU, XEN); //不使能,全部断开 // // gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, YEN); //设置GPIO模式 // gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, YEN); //设置GPIO输出模式及速度 // gpio_bit_set(XYEN_SEL0_1_RCU, YEN); //不使能,全部断开 // // gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEL0); //设置GPIO模式 // gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEL0); //设置GPIO输出模式及速度 // gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); //选择A0 // // gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEL1); //设置GPIO模式 // gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEL1); //设置GPIO输出模式及速度 // gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); //选择A0 // // gpio_mode_set(SEL_2_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEL2); //设置GPIO模式 // gpio_output_options_set(SEL_2_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEL2); //设置GPIO输出模式及速度 // gpio_bit_reset(SEL_2_RCU, SEL2); //选择A0 // //} ///********************************************************************************************************* //* 函数名称:ConfigUART //* 函数功能:配置串口相关的参数,包括GPIO、RCU、USART和NVIC //* 输入参数:bound,波特率 //* 输出参数:void //* 返 回 值:void //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //static void ConfigUART1(unsigned int bound) //{ // nvic_irq_enable(USART1_IRQn, 0); //使能串口中断,设置优先级 // rcu_periph_clock_enable(RCU_GPIOA); //使能GPIOA时钟 // //配置TX的GPIO // gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2); //复用PA9 // gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2); // gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2); // // //配置RX的GPIO // gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3); //复用PA10 // gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3); // gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3); // //配置USART的参数 // rcu_periph_clock_enable(RCU_USART1); //使能串口时钟 // usart_deinit(USART1); //RCU配置恢复默认值 // usart_baudrate_set(USART1, bound); //设置波特率 // usart_stop_bit_set(USART1,USART_STB_1BIT); //设置停止位 // usart_word_length_set(USART1,USART_WL_8BIT); //设置数据字长度 // usart_parity_config(USART1,USART_PM_NONE); //设置奇偶校验位 // usart_receive_config(USART1, USART_RECEIVE_ENABLE); //使能接收 // usart_transmit_config(USART1, USART_TRANSMIT_ENABLE); //使能发送 // usart_enable(USART1); //使能串口 // usart_interrupt_enable(USART1, USART_INT_RBNE); //使能接收缓冲区非空中断 // usart_interrupt_enable(USART1, USART_INT_TBE); //使能发送缓冲区空中断 // // s_iUARTTxSts = UART_STATE_OFF; //串口发送数据状态设置为未发送数据 //} ///********************************************************************************************************* //* 函数名称:EnableUARTTx //* 函数功能:使能串口发送,在WriteUARTx中调用,即每次发送数据之后需要调用这个函数来使能发送中断 //* 输入参数:void //* 输出参数:void //* 返 回 值:void //* 创建日期:2021年07月01日 //* 注 意:s_iUARTTxSts = UART_STATE_ON;这句话必须放在USART_ITConfig之前,否则会导致中断打开无法执行 //*********************************************************************************************************/ //static void EnableUARTTx(void) //{ // s_iUARTTxSts = UART_STATE_ON; //串口发送数据状态设置为正在发送数据 // usart_interrupt_enable(USART1, USART_INT_TBE); //} ///********************************************************************************************************* //* 函数名称:USART1_IRQHandler //* 函数功能:USART1中断服务函数 //* 输入参数:void //* 输出参数:void //* 返 回 值:void //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //void USART1_IRQHandler(void) //{ // unsigned char uData = 0; // if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) != RESET) //接收缓冲区非空中断 // { // usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RBNE); //清除USART1中断挂起 // uData = usart_data_receive(USART1); //将USART1接收到的数据保存到uData // // WriteReceiveBuf(uData); //将接收到的数据写入接收缓冲区 // } // // if(usart_flag_get(USART1, USART_FLAG_ORERR) == SET) //溢出错误标志为1 // { // usart_flag_clear(USART1, USART_FLAG_ORERR); //清除溢出错误标志 // // usart_data_receive(USART1); //读取USART_DR // } // // if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_TBE)!= RESET) //发送缓冲区空中断 // { // // usart_interrupt_flag_clear(USART1, USART_INT_FLAG_TBE); //清除发送中断标志 // __NVIC_ClearPendingIRQ(USART1_IRQn); // // ReadSendBuf(&uData); //读取发送缓冲区的数据到uData // // usart_data_transmit(USART1, uData); //将uData写入USART_DR // // if(QueueEmpty(&s_structUARTSendCirQue)) //当发送缓冲区为空时 // { // s_iUARTTxSts = UART_STATE_OFF; //串口发送数据状态设置为未发送数据 // usart_interrupt_disable(USART1, USART_INT_TBE); //关闭串口发送缓冲区空中断 // } // } //} ///********************************************************************************************************* //* API函数实现 //*********************************************************************************************************/ ///********************************************************************************************************* //* 函数名称:InitUART0 //* 函数功能:初始化UART模块 //* 输入参数:bound,波特率 //* 输出参数:void //* 返 回 值:void //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //void InitUART1(unsigned int bound) //{ // InitUARTBuf(); //初始化串口缓冲区,包括发送缓冲区和接收缓冲区 // // ConfigUART1(bound); //配置串口相关的参数,包括GPIO、RCU、USART和NVIC // // ConfigCH448FGPIO(); //配置串口切换开关IO //} ///********************************************************************************************************* //* 函数名称:WriteUART1 //* 函数功能:写串口,即写数据到的串口发送缓冲区 //* 输入参数:pBuf,要写入数据的首地址,len,期望写入数据的个数 //* 输出参数:void //* 返 回 值:成功写入数据的个数,不一定与形参len相等 //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //unsigned char WriteUART1(unsigned char *pBuf, unsigned char len) //{ // unsigned char wLen = 0; //实际写入数据的个数 // // wLen = EnQueue(&s_structUARTSendCirQue, pBuf, len); // if(wLen < UART1_BUF_SIZE) // { // if(s_iUARTTxSts == UART_STATE_OFF) // { // EnableUARTTx(); // } // } // return wLen; //返回实际写入数据的个数 //} ///********************************************************************************************************* //* 函数名称:ReadUART1 //* 函数功能:读串口,即读取串口接收缓冲区中的数据 //* 输入参数:pBuf,读取的数据存放的首地址,len,期望读取数据的个数 //* 输出参数:pBuf,读取的数据存放的首地址 //* 返 回 值:成功读取数据的个数,不一定与形参len相等 //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //unsigned char ReadUART1(unsigned char *pBuf, unsigned char len) //{ // unsigned char rLen = 0; //实际读取数据长度 // // rLen = DeQueue(&s_structUARTRecCirQue, pBuf, len); // return rLen; //返回实际读取数据的长度 //} // ///********************************************************************************************************* //* 函数名称:fputc //* 函数功能:重定向函数 //* 输入参数:ch,f //* 输出参数:void //* 返 回 值:int //* 创建日期:2021年07月01日 //* 注 意: //*********************************************************************************************************/ //int fputc(int ch, FILE *f) //{ // usart_data_transmit(USART1, (uint8_t) ch); //发送字符函数,专由fputc函数调用 // // while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)); // // return ch; //返回ch //} /********************************************************************************************************* * 模块名称:Uart1.c * 摘 要:串口模块,包括串口模块初始化,以及中断服务函数处理,以及读写串口函数实现 * 当前版本:1.0.0 * 作 者:Leyutek(COPYRIGHT 2018 - 2021 Leyutek. All rights reserved.) * 完成日期:2021年07月01日 * 内 容: * 注 意: ********************************************************************************************************** * 取代版本: * 作 者: * 完成日期: * 修改内容: * 修改文件: *********************************************************************************************************/ /********************************************************************************************************* * 包含头文件 *********************************************************************************************************/ #include "Uart1.h" #include "gd32e230x_conf.h" #include "Hlw8110.h" /********************************************************************************************************* * 宏定义 *********************************************************************************************************/ extern unsigned char u8_TxBuf[UART1_BUF_SIZE]; extern unsigned char u8_RxBuf[UART1_BUF_SIZE]; extern unsigned char u8_TX_Length; extern unsigned char u8_RX_Length; extern unsigned char u8_RX_Index; extern unsigned char B_Rx_Data_ING; // 接收数据标志位 , < 1:接收数据中,0:未接收到数据 > extern unsigned char B_Rx_Finish; /********************************************************************************************************* * 枚举结构体 *********************************************************************************************************/ /********************************************************************************************************* * 内部变量定义 *********************************************************************************************************/ /********************************************************************************************************* * 内部函数声明 *********************************************************************************************************/ static void ConfigUART0(unsigned int bound); //配置串口相关的参数,包括GPIO、RCU、UART和NVIC /********************************************************************************************************* * 内部函数实现 *********************************************************************************************************/ /********************************************************************************************************* * 函数名称:ConfigCH448FGPIO * 函数功能:配置CH448F的切换GPIO * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意:真值表 * XEN# YEN# SEL2 SEL1 SEL0 AX AY * 0 0 0 0 0 选择A0X 选择A0Y 实际是4 * 0 0 0 0 1 选择A1X 选择A1Y 实际是3 * 0 0 0 1 0 选择A2X 选择A2Y 实际是2 * 0 0 0 1 1 选择A3X 选择A3Y 实际是1 * 0 0 1 0 0 选择A4X 选择A4Y 实际是8 * 0 0 1 0 1 选择A5X 选择A5Y 实际是7 * 0 0 1 1 0 选择A6X 选择A6Y 实际是6 * 0 0 1 1 1 选择A7X 选择A7Y 实际是5 * 1 1 X X X 全部断开 全部断开 *********************************************************************************************************/ static void ConfigCH448FGPIO(void) { //使能RCU相关时钟 rcu_periph_clock_enable(RCU_GPIOA); //使能GPIOA的时钟 gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, XEN); //设置GPIO模式 gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, XEN); //设置GPIO输出模式及速度 gpio_bit_reset(XYEN_SEL0_1_RCU, XEN); //不使能,全部断开 gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, YEN); //设置GPIO模式 gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, YEN); //设置GPIO输出模式及速度 gpio_bit_reset(XYEN_SEL0_1_RCU, YEN); //不使能,全部断开 gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEL0); //设置GPIO模式 gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEL0); //设置GPIO输出模式及速度 gpio_bit_reset(XYEN_SEL0_1_RCU, SEL0); //选择A0 gpio_mode_set(XYEN_SEL0_1_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEL1); //设置GPIO模式 gpio_output_options_set(XYEN_SEL0_1_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEL1); //设置GPIO输出模式及速度 gpio_bit_reset(XYEN_SEL0_1_RCU, SEL1); //选择A0 rcu_periph_clock_enable(RCU_GPIOB); //使能GPIOA的时钟 gpio_mode_set(SEL_2_RCU, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, SEL2); //设置GPIO模式 gpio_output_options_set(SEL_2_RCU, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, SEL2); //设置GPIO输出模式及速度 gpio_bit_reset(SEL_2_RCU, SEL2); //选择A0 } /********************************************************************************************************* * 函数名称:ConfigUART * 函数功能:配置串口相关的参数,包括GPIO、RCU、USART和NVIC * 输入参数:bound,波特率 * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ static void ConfigUART1(unsigned int bound) { nvic_irq_enable(USART1_IRQn, 2); //使能串口中断,设置优先级 rcu_periph_clock_enable(RCU_GPIOA); //使能GPIOA时钟 //配置TX的GPIO gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2); //复用PA2 gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2); //配置RX的GPIO gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3); //复用PA3 gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3); //配置USART的参数 rcu_periph_clock_enable(RCU_USART1); //使能串口时钟 usart_deinit(USART1); //RCU配置恢复默认值 usart_baudrate_set(USART1, bound); //设置波特率 usart_stop_bit_set(USART1,USART_STB_1BIT); //设置停止位 usart_word_length_set(USART1,USART_WL_9BIT); //设置数据字长度 usart_parity_config(USART1,USART_PM_EVEN); //设置奇偶校验位,偶校验 usart_receive_config(USART1, USART_RECEIVE_ENABLE); //使能接收 usart_transmit_config(USART1, USART_TRANSMIT_ENABLE); //使能发送 usart_enable(USART1); //使能串口 usart_interrupt_enable(USART1, USART_INT_RBNE); //使能接收缓冲区非空中断 } /********************************************************************************************************* * 函数名称:USART1_IRQHandler * 函数功能:USART1中断服务函数 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ void USART1_IRQHandler(void) { if(usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE) != RESET) //接收缓冲区非空中断 { usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RBNE); //清除USART1中断挂起 if (u8_RX_Index < u8_RX_Length ) { u8_RxBuf[u8_RX_Index] = usart_data_receive(USART1); //将USART1接收到的数据保存到u8_RxBuf u8_RX_Index++; B_Rx_Data_ING = 1; // 置数据接收标志位 } else { B_Rx_Finish = TRUE; // 数据接收完毕 u8_RX_Index = 0; } } } /********************************************************************************************************* * API函数实现 *********************************************************************************************************/ /********************************************************************************************************* * 函数名称:InitUART0 * 函数功能:初始化UART模块 * 输入参数:bound,波特率 * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ void InitUART1(unsigned int bound) { ConfigUART1(bound); //配置串口相关的参数,包括GPIO、RCU、USART和NVIC } /********************************************************************************************************* * 函数名称:InitCH448F * 函数功能:初始化LED模块 * 输入参数:void * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ void InitCH448F(void) { ConfigCH448FGPIO(); //配置串口切换开关IO } /********************************************************************************************************* * 函数名称:Start_Send_UartData * 函数功能:发送数据函数 * 输入参数:发送数据长度 * 输出参数:void * 返 回 值:void * 创建日期:2021年07月01日 * 注 意: *********************************************************************************************************/ void Start_Send_UartData(unsigned char len) { unsigned int i; for(i=0;i