UART是最常用的外设了,这里不做过多的解释。但是大家要注意的是,华大的F072 UART 么有空闲中断,所以处理起来需要一路定时器配合。
  • #include "bsp_uart.h"
  • /* 以下几个全局变量仅用于测试*/
  • volatile uint8_t u8TxData[2] = {0xaa,0x55};
  • volatile uint8_t u8RxData[2] = {0x00};
  • uint8_t u8TxCnt=0,u8RxCnt=0;
  • //串口模块配置
  • // PA9 -- TX
  • // PA10 -- RX
  • void BSP_Uart0_Config(void)
  • {
  •         stc_uart_cfg_t  stcCfg;       
  •     stc_uart_baud_t stcBaud;
  •         stc_gpio_cfg_t stcGpioCfg;
  •    
  •         DDL_ZERO_STRUCT(stcCfg);
  •     DDL_ZERO_STRUCT(stcBaud);
  •     DDL_ZERO_STRUCT(stcGpioCfg);
  •          
  •     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///<使能GPIO外设时钟门控开关
  •    
  •     stcGpioCfg.enDir = GpioDirOut;
  •         Gpio_Init(GpioPortA,GpioPin9,&stcGpioCfg);
  •         Gpio_SetAfMode(GpioPortA,GpioPin9,GpioAf1); //配置PA9 为UART0 TX
  •         stcGpioCfg.enDir = GpioDirIn;
  •         Gpio_Init(GpioPortA,GpioPin10,&stcGpioCfg);
  •         Gpio_SetAfMode(GpioPortA,GpioPin10,GpioAf1);//配置PA10 为UART0 RX
  •    
  •     Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE); ///<使能UART2外设时钟门控开关
  •    
  •     ///<UART Init
  •     stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
  •     stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位
  •     stcCfg.enMmdorCk        = UartMskNone;                            ///<无校验位
  •     stcCfg.stcBaud.u32Baud  = 115200;                       ///<波特率 9600 无误差,115200 误差0.16%
  •                      
  •     stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
  •     stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///</<获得外设时钟(PCLK)频率值
  •     Uart_Init(M0P_UART0, &stcCfg);                          ///<串口初始化
  •    
  •         ///<UART中断使能
  •     Uart_EnableIrq(M0P_UART0,UartRxIrq); //使能串口接收中断
  •         //Uart_EnableIrq(M0P_UART0,UartTxIrq); //使能串口发送中断
  •        
  •         ///<系统中断使能
  •     EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE);   
  •        
  •         Uart_ClrStatus(M0P_UART0,UartRC);    //清接收请求
  •     Uart_ClrStatus(M0P_UART0,UartTC);    //清发送请求
  • }
  • //串口模块配置
  • // PA2 -- TX
  • // PA3 -- RX
  • void BSP_Uart1_Config(void)
  • {
  •         stc_uart_cfg_t  stcCfg;       
  •     stc_uart_baud_t stcBaud;
  •         stc_gpio_cfg_t stcGpioCfg;
  •    
  •         DDL_ZERO_STRUCT(stcCfg);
  •     DDL_ZERO_STRUCT(stcBaud);
  •     DDL_ZERO_STRUCT(stcGpioCfg);
  •          
  •     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///<使能GPIO外设时钟门控开关
  •    
  •     stcGpioCfg.enDir = GpioDirOut;
  •     Gpio_Init(GpioPortA,GpioPin2,&stcGpioCfg);
  •     Gpio_SetAfMode(GpioPortA,GpioPin2,GpioAf1); //配置PA2 为UART1 TX
  •        
  •     stcGpioCfg.enDir = GpioDirIn;
  •     Gpio_Init(GpioPortA,GpioPin3,&stcGpioCfg);
  •     Gpio_SetAfMode(GpioPortA,GpioPin3,GpioAf1);//配置PA3 为UART1 RX
  •             
  •     Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE); ///<使能UART2外设时钟门控开关
  •    
  •     ///<UART Init
  •     stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
  •     stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位
  •     stcCfg.enMmdorCk        = UartMskNone;                            ///<无校验位
  •     stcCfg.stcBaud.u32Baud  = 115200;                       ///<波特率 9600 无误差,115200 误差0.16%
  •                      
  •     stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
  •     stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///</<获得外设时钟(PCLK)频率值
  •     Uart_Init(M0P_UART1, &stcCfg);                          ///<串口初始化
  •    
  •         ///<UART中断使能
  •     Uart_EnableIrq(M0P_UART1,UartRxIrq); //使能串口接收中断
  •         //Uart_EnableIrq(M0P_UART1,UartTxIrq); //使能串口发送中断
  •        
  •         ///<系统中断使能
  •     EnableNvic(UART0_2_IRQn, IrqLevel3, TRUE);   
  •        
  •         Uart_ClrStatus(M0P_UART1,UartRC);    //清接收请求
  •     Uart_ClrStatus(M0P_UART1,UartTC);    //清发送请求
  • }
  • //串口模块配置
  • void BSP_Uart2_Config(void)
  • {
  •     stc_uart_cfg_t  stcCfg;       
  •     stc_uart_baud_t stcBaud;
  •         stc_gpio_cfg_t stcGpioCfg;
  •    
  •         DDL_ZERO_STRUCT(stcCfg);
  •     DDL_ZERO_STRUCT(stcBaud);
  •     DDL_ZERO_STRUCT(stcGpioCfg);
  •          
  •     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///<使能GPIO外设时钟门控开关
  •    
  •     stcGpioCfg.enDir = GpioDirOut;
  •     Gpio_Init(GpioPortC,GpioPin3,&stcGpioCfg);
  •     Gpio_SetAfMode(GpioPortC,GpioPin3,GpioAf5); //配置PC03 为UART2 TX
  •     stcGpioCfg.enDir = GpioDirIn;
  •     Gpio_Init(GpioPortC,GpioPin2,&stcGpioCfg);
  •     Gpio_SetAfMode(GpioPortC,GpioPin2,GpioAf4);//配置PC02 为UART2 RX
  •             
  •     Sysctrl_SetPeripheralGate(SysctrlPeripheralUart2,TRUE); ///<使能UART2外设时钟门控开关
  •    
  •     ///<UART Init
  •     stcCfg.enRunMode        = UartMskMode1;                 ///<模式1
  •     stcCfg.enStopBit        = UartMsk1bit;                  ///<1bit停止位
  •     stcCfg.enMmdorCk        = UartMskNone;                            ///<无校验位
  •     stcCfg.stcBaud.u32Baud  = 115200;                       ///<波特率9600无误差,115200误差0.16%
  •                      
  •     stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div;              ///<通道采样分频配置
  •     stcCfg.stcBaud.u32Pclk  = Sysctrl_GetPClkFreq();        ///</<获得外设时钟(PCLK)频率值
  •     Uart_Init(M0P_UART2, &stcCfg);                          ///<串口初始化
  •    
  •         ///<UART中断使能
  •     Uart_EnableIrq(M0P_UART2,UartRxIrq); //使能串口接收中断
  •         //Uart_EnableIrq(M0P_UART2,UartTxIrq); //使能串口发送中断
  •        
  •         ///<系统中断使能
  •     EnableNvic(UART0_2_IRQn, IrqLevel2, TRUE);   
  •        
  •         Uart_ClrStatus(M0P_UART2,UartRC);    //清接收请求
  •     Uart_ClrStatus(M0P_UART2,UartTC);    //清发送请求
  •        
  • }
  • void Uart2_IRQHandler(void)
  • {
  •     if(Uart_GetStatus(M0P_UART2, UartRC))
  •     {
  •         Uart_ClrStatus(M0P_UART2, UartRC);              //清除接收中断状态位
  •         }
  • }
  • void Uart0_IRQHandler(void)
  • {
  •     if(Uart_GetStatus(M0P_UART0, UartRC))
  •     {
  •         Uart_ClrStatus(M0P_UART0, UartRC);              //清除接收中断状态位
  •                
  •         //u8RxData[u8RxCnt] = Uart_ReceiveData(M0P_UART0);         
  •         //u8RxCnt++;
  • //        if(u8RxCnt>1)                                   //如果已接收两个字节
  • //        {
  • //            Uart_DisableIrq(M0P_UART1,UartRxIrq);       //禁止接收中断
  • //       }       
  •     }
  •    
  •     if(Uart_GetStatus(M0P_UART0, UartTC))
  •     {
  •         Uart_ClrStatus(M0P_UART0, UartTC);              //清除发送中断状态位
  • //        Uart_SendDataIt(M0P_UART1, u8TxData[u8TxCnt++]);//发送数据
  • //        if(u8TxCnt>1)                                   //如果已发送两个字节
  • //       {
  • //            u8TxCnt = 0;
  • //            u8RxCnt = 0;
  • //           Uart_DisableIrq(M0P_UART1,UartTxIrq);       //禁止发送中断
  • //            Uart_EnableIrq(M0P_UART1,UartRxIrq);        //使能接收中断
  • //        }
  •     }
  • }
  • // how to use:    Uart_SendDataIt(M0P_UART1, ~u8RxData); Uart_SendDataPoll(M0P_UART0, 0x16);     
  • 复制代码
    头文件:
    #ifndef __BSP_UART_H__
  • #define __BSP_UART_H__
  • #include "uart.h"
  • #include "gpio.h"
  • #include <stdio.h>
  • void BSP_Uart0_Config(void);
  • void BSP_Uart1_Config(void);
  • void BSP_Uart2_Config(void);
  • extern volatile uint8_t u8TxData[2];
  • extern volatile uint8_t u8RxData[2];
  • extern uint8_t u8TxCnt,u8RxCnt;
  • #endif
  • 复制代码

    以上代码都经过了验证,可以放心使用户。