接下来就该串口了。串口分为UART和USART,但是对我来说尽可能的统一命名,所以都改为UART了。一般情况我用不到太高级的功能,能通讯就OK。
废话少说,直接上代码:
- #ifdef DBGLOG
- #define LOG(...) printf(__VA_ARGS__)
- #else
- #define LOG(...) //NOLOG
- #endif
- typedef struct _UART CUART;
- typedef void (*tiSR_UART)(CUART* UARTx, uint8_t DAT);
- typedef struct _UART
- {
- USART_Module* TUART;
- CIO* TX;
- CIO* RX;
- IRQn_Type _IRQn;
- USART_InitType _hUART;
- TISR_UART _OnUART;
- } CUART;
- extern void UART_InitCM(CUART* UARTx, TISR_UART OnUART);
- extern void UART_Config(CUART* UARTx, u8 DataBit, u8 Parity, u8 StopBits);
- extern void UART_Start(CUART* UARTx, u32 Baudrate);
- extern void UART_Stop(CUART* UARTx);
- extern void UART_Send(CUART* UARTx, u8* Data, u16 Size);
复制代码
连调试的功能都给加上了,可以自行打开关闭宏来定义是否使用调试功能。
- void UART_InitCM(CUART* UARTx, TISR_UART OnUART)
- {
- RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);
- UARTx->TX->Mode = AFPP; UARTx->TX->Speed = FAST;
- UARTx->RX->Mode = IPN; UARTx->RX->Speed = FAST;
- IO_Config(UARTx->RX, 0);
- UARTx->_OnUART = OnUART;
- switch ((u32) UARTx->TUART)
- {
- case ((u32) USART1):
- _UARTx[0] = UARTx; UARTx->_IRQn = USART1_IRQn;
- IO_Config(UARTx->TX, GPIO_RMP_USART1);
- RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1, ENABLE);
- break;
- case ((u32) UART4):
- _UARTx[3] = UARTx; UARTx->_IRQn = UART4_IRQn;
- IO_Config(UARTx->TX, GPIO_RMP3_UART4);
- RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_UART4, ENABLE);
- break;
- }
- ECLIC_SetCfgNlbits(0);
- ECLIC_SetPriorityIRQ(UARTx->_IRQn, 1);
- ECLIC_SetTrigIRQ(UARTx->_IRQn, ECLIC_LEVEL_TRIGGER);
- UART_Config(UARTx, USART_WL_8B, USART_PE_NO, USART_STPB_1);
- }
- void UART_Config(CUART* UARTx, u8 DataBit, u8 Parity, u8 StopBits)
- {
- UARTx->_hUART.WordLength = USART_WL_8B;
- UARTx->_hUART.StopBits = USART_STPB_1;
- UARTx->_hUART.Parity = USART_PE_NO;
- UARTx->_hUART.HardwareFlowControl = USART_HFCTRL_NONE;
- UARTx->_hUART.Mode = USART_MODE_RX | USART_MODE_TX;
- }
- void UART_Start(CUART* UARTx, u32 Baudrate)
- {
- __disable_irq();
- UARTx->_hUART.BaudRate = Baudrate;
- USART_Init(UARTx->TUART, &UARTx->_hUART);
- USART_ConfigInt(UARTx->TUART, USART_INT_RXDNE, ENABLE);
- USART_Enable(UARTx->TUART, ENABLE);
- ECLIC_EnableIRQ(UARTx->_IRQn);
- __enable_irq();
- }
- void UART_Stop(CUART* UARTx)
- {
- ECLIC_DisableIRQ(UARTx->_IRQn);
- USART_Enable(UARTx->TUART, DISABLE);
- USART_ConfigInt(UARTx->TUART, USART_INT_RXDNE, DISABLE);
- }
- void UART_Send(CUART* UARTx, u8* Data, u16 Size)
- {
- while (Size--)
- {
- USART_SendData(UARTx->TUART, *Data++);
- while (!USART_GetFlagStatus(UARTx->TUART, USART_FLAG_TXDE)) ;
- }
- }
- static void UART_HandlerIRQ(CUART* UARTx)
- {
- if (!UARTx->_OnUART) return ;
- UARTx->_OnUART(UARTx, USART_ReceiveData(UARTx->TUART));
- }
- void USART1_IRQHandler(void)
- {
- if (USART_GetIntStatus(USART1, USART_INT_RXDNE)) UART_HandlerIRQ(_UARTx[0]);
- }
- void UART4_IRQHandler(void)
- {
- if (USART_GetIntStatus(UART4, USART_INT_RXDNE)) UART_HandlerIRQ(_UARTx[3]);
- }
- #ifdef DBGLOG
- int _put_char(int ch)
- {
- USART_SendData(DBGLOG, (u8)ch);
- while (USART_GetFlagStatus(DBGLOG, USART_FLAG_TXDE) == RESET);
- return ch;
- }
- #endif
复制代码
实现的代码有点多了,其实和例程差不多,只不过分解了一下而已,没什么难度。
|