//******************************************************************** // Ver 1.0 // 2019.10.09 1、新建文件。 // 2020.03.06 2、增加写入缓冲区数据时,复位串口超时计数 //******************************************************************** #include "config.h" UART_Str UART_Info; const INT32U UART_BOUND_Tab[] = { 1200, 2400, 4800, 9600, 19200, 38400, 56000, 57600, 115200, }; /* void UART_ModeSet(M0P_UART_TypeDef* USARTx, INT8U ModeMask, INT8U Value) { if (Value != 0) { USARTx->CR1 |= ((USART_Mode_Tx | USART_Mode_Rx) & ModeMask); } else { USARTx->CR1 &= ~((USART_Mode_Tx | USART_Mode_Rx) & ModeMask); } } */ /* INT8U UART_NumSeach(en_uart_channel_t UARTx) { return(UARTx); } */ void UART_EnableIrq(en_uart_channel_t UARTx, INT8U IrqType) { if(IrqType == UartTxIrq) { if(UARTx == UART0) INTC_EnableIRQ(ST0_IRQn); else if(UARTx == UART1) INTC_EnableIRQ(ST1_IRQn); #ifdef UART2 else if(UARTx == UART2) INTC_EnableIRQ(ST2_IRQn); #endif } else if(IrqType == UartRxIrq) { if(UARTx == UART0) INTC_EnableIRQ(SR0_IRQn); else if(UARTx == UART1) INTC_EnableIRQ(SR1_IRQn); #ifdef UART2 else if(UARTx == UART2) INTC_EnableIRQ(SR2_IRQn); #endif } } void UART_DisableIrq(en_uart_channel_t UARTx, INT8U IrqType) { if(IrqType == UartTxIrq) { if(UARTx == UART0) INTC_DisableIRQ(ST0_IRQn); else if(UARTx == UART1) INTC_DisableIRQ(ST1_IRQn); #ifdef UART2 else if(UARTx == UART2) INTC_DisableIRQ(ST2_IRQn); #endif } else if(IrqType == UartRxIrq) { if(UARTx == UART0) INTC_DisableIRQ(SR0_IRQn); else if(UARTx == UART1) INTC_DisableIRQ(SR1_IRQn); #ifdef UART2 else if(UARTx == UART2) INTC_DisableIRQ(SR2_IRQn); #endif } } void UART_SendData(en_uart_channel_t UARTx, INT16U ch) { if(UARTx == UART0) SCI0->TXD0 = ch; else if(UARTx == UART1) SCI0->TXD1 = ch; #ifdef UART2 else if(UARTx == UART2) SCI1->TXD2 = ch; #endif } INT8U UART_ReceiveData(en_uart_channel_t UARTx) { INT8U Value = 0; if(UARTx == UART0) Value = SCI0->RXD0; else if(UARTx == UART1) Value = SCI0->RXD1; #ifdef UART2 else if(UARTx == UART2) Value = SCI1->RXD2; #endif return(Value); } INT8U UART_GetStatus(en_uart_channel_t UARTx, INT16U SSR_Mask) { INT8U tFlag = 0; if(UARTx == UART0) tFlag = (SCI0->SSR00 & SSR_Mask); else if(UARTx == UART1) tFlag = (SCI0->SSR02 & SSR_Mask); #ifdef UART2 else if(UARTx == UART2) tFlag = (SCI1->SSR10 & SSR_Mask); #endif if(tFlag == 0) return(FALSE); else return(TRUE); } //从串口发送数据 void UART_SendChar(en_uart_channel_t UARTx, INT16U ch) { //UART_ClrStatus(UARTx, UartTC); // 清除发送完成标识 UART_SendData(UARTx, ch); // 发送字符 while(FALSE != UART_GetStatus(UARTx, UartTC)) { NOP(); } //UART_ClrStatus(UARTx, UartTC); } //向串口发送字符串 void UART_SendString(en_uart_channel_t UARTx, uint8_t *s) { while (*s != '\0') { UART_SendChar(UARTx, *s++); } } //写缓冲区 INT8U UART_WriteBuff(en_uart_channel_t UARTx, INT8U *ptr, INT16U Len) { INT16U wrCnt; //INT8U UartNum = UART_NumSeach(UARTx); if(UARTx == UART_SIZE) { return(0); } UART_IdleRest(UARTx, 10); //2020.03.06 增加写入缓冲区数据时,复位串口超时计数 ATOMIC_Start(); while (Len--) { wrCnt = (UART_Info.Uart[UARTx].wCnt + UART_Info.Uart[UARTx].wPtr) % UART_TX_BUFF_SIZE; UART_Info.Uart[UARTx].wBuff[wrCnt] = *ptr++; //写入一个字节 if (UART_Info.Uart[UARTx].wCnt >= (UART_TX_BUFF_SIZE - 1)) { UART_Info.Uart[UARTx].wPtr++; UART_Info.Uart[UARTx].wPtr %= UART_TX_BUFF_SIZE; break; } else { UART_Info.Uart[UARTx].wCnt++; } } ATOMIC_Stop(); //UART_ModeSet(UARTx, USART_Mode_Tx, ENABLE); //打开发送模式 if(UART_GetStatus(UARTx, UartTxe) == FALSE) { //UART_Func(UARTx, UartRenFunc, DISABLE); //关闭接收模式 UART_EnableIrq(UARTx, UartTxIrq); UART_SendData(UARTx, UART_Info.Uart[UARTx].wBuff[UART_Info.Uart[UARTx].wPtr]); //取一个数据发送出去 UART_Info.Uart[UARTx].wCnt --; //写入数据个数减1 UART_Info.Uart[UARTx].wPtr++; UART_Info.Uart[UARTx].wPtr %= UART_TX_BUFF_SIZE; } return (1); } //读缓冲区 INT8U UART_ReadBuff(en_uart_channel_t UARTx, INT8U *ptr, INT16U Len) { //INT8U UartNum = UART_NumSeach(UARTx); if(UARTx == UART_SIZE) { return(0); } ATOMIC_Start(); while (Len--) { *ptr = UART_Info.Uart[UARTx].rBuff[UART_Info.Uart[UARTx].rPtr]; //写入一个字节 if (UART_Info.Uart[UARTx].rPtr < (UART_RX_BUFF_SIZE - 1)) { UART_Info.Uart[UARTx].rPtr++; UART_Info.Uart[UARTx].rPtr %= UART_RX_BUFF_SIZE; } else { UART_Info.Uart[UARTx].rPtr = 0; } if (UART_Info.Uart[UARTx].rCnt == 0) { break; } else { UART_Info.Uart[UARTx].rCnt--; } ptr++; } ATOMIC_Stop(); return (1); } void UART_IdleCnt(void) { INT8U i; for(i = 0; i < UART_SIZE; i++) { if (UART_Info.Uart[i].Idle > 0) { UART_Info.Uart[i].Idle --; } } } INT8U UART_IdleRest(en_uart_channel_t UARTx, INT16U Value) { UART_Info.Uart[UARTx].Idle = Value; return(1); } INT8U UART_IdleState(en_uart_channel_t UARTx) { if(UART_Info.Uart[UARTx].Idle == 0) { return(1); } else { return(0); } } //UART0接收中断服务程序 #if 1 //UART0 //void UART0_Handler(void) volatile uint8_t err_type; void SCI0_RX_Handler(void) { INT16U wrCnt; UART_IdleRest(UART0, 10); if (INTC_GetPendingIRQ(UART0_RX_IRQn) != 0) { INTC_ClearPendingIRQ(UART0_RX_IRQn); // 清除接收中断标志 wrCnt = (UART_Info.Uart[UART0].rCnt + UART_Info.Uart[UART0].rPtr) % UART_RX_BUFF_SIZE; //使用覆盖写入的方式 UART_Info.Uart[UART0].rBuff[wrCnt] = UART_ReceiveData(UART0); // 读取数据 if (UART_Info.Uart[UART0].rCnt < (UART_RX_BUFF_SIZE - 1)) { UART_Info.Uart[UART0].rCnt++; } else { UART_Info.Uart[UART0].rPtr++; UART_Info.Uart[UART0].rPtr %= UART_RX_BUFF_SIZE; } } } void SCI0_TX_Handler(void) { if (INTC_GetPendingIRQ(UART0_TX_IRQn) != 0) { INTC_ClearPendingIRQ(UART0_TX_IRQn); if (UART_Info.Uart[UART0].wCnt == 0) //发送数据已经完成,关闭发送使能中断 { UART_DisableIrq(UART0, UartTxIrq); //UART_Func(UART0, UartRenFunc, ENABLE); //打开接收模式 //RS485DE0_Set2Rx(); } else { //RS485_Mode(RS485_TxMode); UART_SendData(UART0, UART_Info.Uart[UART0].wBuff[UART_Info.Uart[UART0].wPtr]); //取一个数据发送出去 UART_Info.Uart[UART0].wCnt --; //写入数据个数减1 UART_Info.Uart[UART0].wPtr++; UART_Info.Uart[UART0].wPtr %= UART_TX_BUFF_SIZE; } } UART0_ClrErrorFlag(); } #endif //UART1接收中断服务程序 //void USART1_IRQHandler(void) #if 1 //UART1 //void UART1_IRQHandler(void) void SCI1_TX_Handler(void) { INT16U wrCnt; UART_IdleRest(UART1, 10); if (INTC_GetPendingIRQ(UART1_TX_IRQn) != 0) { INTC_ClearPendingIRQ(UART1_TX_IRQn); // 清除接收中断标志 wrCnt = (UART_Info.Uart[UART1].rCnt + UART_Info.Uart[UART1].rPtr) % UART_RX_BUFF_SIZE; //使用覆盖写入的方式 UART_Info.Uart[UART1].rBuff[wrCnt] = UART_ReceiveData(UART1); // 读取数据 if (UART_Info.Uart[UART1].rCnt < (UART_RX_BUFF_SIZE - 1)) { UART_Info.Uart[UART1].rCnt++; } else { UART_Info.Uart[UART1].rPtr++; UART_Info.Uart[UART1].rPtr %= UART_RX_BUFF_SIZE; } } } void SCI1_RX_Handler(void) { if (INTC_GetPendingIRQ(UART1_RX_IRQn) != 0) { INTC_ClearPendingIRQ(UART0_RX_IRQn); if (UART_Info.Uart[UART1].wCnt == 0) //发送数据已经完成,关闭发送使能中断 { UART_DisableIrq(UART1, UartTxIrq); //Uart_Func(UART1, UartRenFunc, ENABLE); //RS485_Mode(RS485_RxMode); //UART1_RxHigh(); //BATT_FLAG_TX = 0; } else { //RS485_Mode(RS485_TxMode); UART_SendData(UART1, UART_Info.Uart[UART1].wBuff[UART_Info.Uart[UART1].wPtr]); //取一个数据发送出去 UART_Info.Uart[UART1].wCnt --; //写入数据个数减1 UART_Info.Uart[UART1].wPtr++; UART_Info.Uart[UART1].wPtr %= UART_TX_BUFF_SIZE; } } UART1_ClrErrorFlag(); } #endif //UART2接收中断服务程序 #ifdef LPUART0 //void USART2_IRQHandler(void) void LPUART0_IRQHandler(void) { INT16U wrCnt; UART_IdleRest(UART2, 10); if (INTC_GetPendingIRQ(UART2_TX_IRQn) != 0) { INTC_ClearPendingIRQ(UART2_TX_IRQn); // 清除接收中断标志 wrCnt = (UART_Info.Uart[UART2].rCnt + UART_Info.Uart[UART2].rPtr) % UART_RX_BUFF_SIZE; //使用覆盖写入的方式 UART_Info.Uart[UART2].rBuff[wrCnt] = UART_ReceiveData(UART2); // 读取数据 if (UART_Info.Uart[UART2].rCnt < (UART_RX_BUFF_SIZE - 1)) { UART_Info.Uart[UART2].rCnt++; } else { UART_Info.Uart[UART2].rPtr++; UART_Info.Uart[UART2].rPtr %= UART_RX_BUFF_SIZE; } } if (INTC_GetPendingIRQ(UART1_RX_IRQn) != 0) { INTC_ClearPendingIRQ(UART0_RX_IRQn); if (UART_Info.Uart[UART2].wCnt == 0) //发送数据已经完成,关闭发送使能中断 { UART_DisableIrq(UART2, UartTxIrq); //RS485_Mode(RS485_RxMode); } else { //RS485_Mode(RS485_TxMode); UART_SendData(UART2, UART_Info.Uart[UART2].wBuff[UART_Info.Uart[UART2].wPtr]); //取一个数据发送出去 UART_Info.Uart[UART2].wCnt --; //写入数据个数减1 UART_Info.Uart[UART2].wPtr++; UART_Info.Uart[UART2].wPtr %= UART_TX_BUFF_SIZE; } } UART2_ClrErrorFlag(); } #endif #if 0 //重定义fputc函数 int fputc(int ch, FILE *f) { while (!USART_GetFlagStatus(PRINTF_UART, USART_FLAG_TC)); //USART_GetFlagStatus:得到发送状态位 //USART_FLAG_TXE:发送寄存器为空 1:为空;0:忙状态 USART_SendData(PRINTF_UART, ch); //发送一个字符 return ch; //返回一个值 } int fgetc(FILE *f) { while (USART_GetFlagStatus(PRINTF_UART, USART_FLAG_RXNE) == RESET); return (USART_ReceiveData(PRINTF_UART)); } uint8_t fscanfc(uint32_t value) { uint32_t index = 0; uint32_t tmp[2] = {0, 0}; while (index < 2) { /* Loop until RXNE = 1 */ while (USART_GetFlagStatus(PRINTF_UART, USART_FLAG_RXNE) == RESET) {} tmp[index++] = (USART_ReceiveData(PRINTF_UART)); if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)) { UART_SendString(PRINTF_UART, "\n\r Please enter valid number between 0 and 9 \n\r"); index--; } } /* Calculate the Corresponding value */ index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10); /* Checks */ if (index > value) { UART_SendString(PRINTF_UART, "\n\r Please enter valid number between 0 and 59 \n\r"); return 0xFF; } return index; } #endif