入门第四步——uart串口通信
通用同步异步收发器(UART)能够灵活地与外部设备进行全双工数据交换,它支持同步单向通信、单线半双工通信以及多处理器通信。常用于短距离、低速的串行通信中。UART 通过可编程波特率发生器提供了多种波特率。UART 支持多种工作模式。
模式比较多,但是我们常用的是模式3,异步全双工。异步不需要时钟线,全双工保证了数据的高速通信,所以推荐使用模式3。
发送数据时,与 UARTx_SCON.REN 的值无关,将所发送数据写入 UARTx_SBUF 寄存器中,数据就会从 TXD 移出(低位在先,高位在后)
接收数据时,将 UARTx_SCON.REN 位置 1,并将 UARTx_ISR.RC 位清 0。开始接收 RXD 上数据(低位在先,高位在后),当接收完毕,可以从 UARTx_SBUF 寄存器读出。
从上面的两个图可以看出,在初始状态TX和RX都是高电平,这个是UART协议规定的,当总线处于空闲状态时信号线的状态为1即高电平。也就是说明了,发送数据的时候是将高电平拉低作为起始位的。
老样子,咱们先新建一个App_Serial_Init.c和 App_Serial_Init.h。
根据数据手册,我们可以发现PA02和PA03引脚可以作为UART1串口的TX和RX。
我们都知道串口通信属于最简单的通信方式了,在模式3(异步全双工)下只需要三根线即可,TX、RX和GND。连接如图所示
下面看代码部分:
main.c
```c
#include "main.h"
static boolean_t Flag=0;
SystemStatus_t SystemStatus;
int main()
{
App_LedInit();
Timer0_Init();
App_PortInit();
App_Serial_Init();
while(1)
{
switch(SystemStatus)
{
case RxCompleteState:
{
Gpio_WriteOutputIO(GpioPortA, GpioPin0, Flag);
Flag ^= 1;
SystemStatus=DummyState;
break;
}
default:
break;
}
}
}
main.h
#ifndef __MAIN_H__
#define __MAIN_H__
#include "App_Gpio_Init.h"
#include "Timer0_Init.h"
typedef enum SystemStatus
{
DummyState = 0u,
RxCompleteState = 1u,
}SystemStatus_t;
extern SystemStatus_t SystemStatus;
#endif
App_Gpio_Init.c
#include "App_Gpio_Init.h"
void App_LedInit(void)
{
stc_gpio_cfg_t stcGpioCfg; ///定义结构体变量
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); ///< 打开GPIO外设时钟门控
stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出(其它参数与以上(输入)配置参数一致)
stcGpioCfg.enPu = GpioPuDisable; ///< 端口上拉配置->不使能
stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->不使能
stcGpioCfg.bOutputVal=TRUE; ///< 端口低电平驱动,初始化为高电平,使LED处于熄灭状态
Gpio_Init(GpioPortA, GpioPin0, &stcGpioCfg); ///< GPIO IO LED端口初始化
}
//串口引脚配置
void App_PortInit(void)
{
stc_gpio_cfg_t stcGpioCfg;
DDL_ZERO_STRUCT(stcGpioCfg);
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE); //使能GPIO模块时钟
///<TX
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(GpioPortA, GpioPin2, &stcGpioCfg);
Gpio_SetAfMode(GpioPortA, GpioPin2, GpioAf1); //配置PA02 端口为URART1_TX
///<RX
stcGpioCfg.enDir = GpioDirIn;
Gpio_Init(GpioPortA, GpioPin3, &stcGpioCfg);
Gpio_SetAfMode(GpioPortA, GpioPin3, GpioAf1); //配置PA03 端口为URART1_RX
}
App_Gpio_Init.h
#ifndef __APP_GPIO_INIT_H__
#define __APP_GPIO_INIT_H__
#include "gpio.h"
void App_LedInit(void);
void App_PortInit(void);
#endif
Timer0_Init.c
#include "Timer0_Init.h"
void Timer0_Init(void)
{
stc_bt_mode0_cfg_t stcBtConfig;
DDL_ZERO_STRUCT(stcBtConfig);
Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE);
stcBtConfig.enWorkMode = BtWorkMode0; ///< 定时器模式
stcBtConfig.bEnGate = FALSE; ///< 门控极性控制->关闭
stcBtConfig.enPRS = BtPCLKDiv32; ///< 预除频配置
stcBtConfig.bEnTog = FALSE; ///< 翻转输出使能
stcBtConfig.enCT = BtTimer; ///< 定时功能
stcBtConfig.enCntMode = Bt16bitArrMode; ///< 自动重载16位定时器
Bt_Mode0_Init(TIM0, &stcBtConfig);
Bt_M0_ARRSet(TIM0,3036); //重载值,1s/(4M/32)=1*10^6 / (4*1*10^6/32) =8us 500ms/8us = 62500 65536-62500=3036
Bt_ClearIntFlag(TIM0,BtUevIrq); //中断清除
Bt_Mode0_EnableIrq(TIM0); //中断使能
EnableNvic(TIM0_IRQn,IrqLevel3,TRUE); //NVIC使能
}
Timer0_Init.h
#ifndef __TIMER0_INIT_H__
#define __TIMER0_INIT_H__
#include "bt.h"
void Timer0_Init(void);
#endif
App_Serial_Init.c
#include "App_Serial_Init.h"
//串口配置
void App_UartCfg(void)
{
stc_uart_cfg_t stcCfg;
DDL_ZERO_STRUCT(stcCfg);
///< 开启外设时钟
Sysctrl_SetPeripheralGate(SysctrlPeripheralUart1,TRUE);///<使能uart1模块时钟
///<UART Init
stcCfg.enRunMode = UartMskMode3; ///<模式3
stcCfg.enStopBit = UartMsk1bit; ///<1bit停止位
stcCfg.enMmdorCk = UartMskEven; ///<偶检验
stcCfg.stcBaud.u32Baud = 9600; ///<波特率9600
stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; ///<通道采样分频配置
stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); ///<获得外设时钟(PCLK)频率值
Uart_Init(M0P_UART1, &stcCfg); ///<串口初始化
///<UART中断使能
Uart_ClrStatus(M0P_UART1,UartRC); ///<清接收请求
Uart_ClrStatus(M0P_UART1,UartTC); ///<清接收请求
Uart_EnableIrq(M0P_UART1,UartRxIrq); ///<使能串口接收中断
Uart_EnableIrq(M0P_UART1,UartTxIrq); ///<使能串口接收中断
EnableNvic(UART1_3_IRQn, IrqLevel3, TRUE); ///<系统中断使能
}
App_Serial_Init.h
#ifndef __APP_SERIAL_INIT_H__
#define __APP_SERIAL_INIT_H__
#include "uart.h"
#include "sysctrl.h"
#endif
App_interrupts.c
/**
******************************************************************************
** \brief 中断函数的集合(低功耗串口,定时器Timer0中断)
**
** \return 无返回值
**
******************************************************************************/
#include "App_interrupts.h"
RxBuf Rxbuff; //定义结构体类型变量
/**
******************************************************************************
** \brief LPUART1 中断服务函数
**
** \return 无返回值
**
******************************************************************************/
///<LPUART1 中断服务函数
void LpUart1_IRQHandler(void)
{
if(Uart_GetStatus(M0P_UART1, UartTC)) ///发送数据
{
Uart_ClrStatus(M0P_UART1, UartTC); ///<清发送中断请求
}
if(Uart_GetStatus(M0P_UART1, UartRC)) ///接收数据
{
Uart_ClrStatus(M0P_UART1, UartRC); ///<清接收中断请求
Rxbuff.u8[Rxbuff.idx] = Uart_ReceiveData(M0P_UART1);///读取数据
Rxbuff.idx = (Rxbuff.idx > sizeof(Rxbuff.u8)? Rxbuff.idx:(Rxbuff.idx+1));
Bt_M0_Cnt16Set(TIM0,60736); //初值
Bt_M0_Run(TIM0);
}
}
/**
******************************************************************************
** \brief Tim0中断服务函数
**
** \return 无返回值
**
******************************************************************************/
//Tim0中断服务函数
void Tim0_IRQHandler(void)
{
Bt_ClearIntFlag(TIM0,BtUevIrq); //中断清除
Bt_M0_Stop(TIM0); //停止timer0
Rxbuff.len=Rxbuff.idx; //存储接收数组长度
Rxbuff.idx=0; //清除接收数组长度缓存,方便下次使用
SystemStatus = RxCompleteState; //更新系统状态,RX接收完成
}
App_interrupts.h
```c
#ifndef __APP_INTERRUPTS_H__
#define __APP_INTERRUPTS_H__
#include "main.h"
#include "uart.h"
#include "bt.h"
typedef struct
{
uint8_t u8[32]; //串口接收数据缓存
uint8_t I2[32]; //I2C接收数据缓存
uint8_t idx; //串口接收数据索引
uint8_t len;
}RxBuf;
extern volatile uint8_t State;
extern RxBuf Rxbuff;
#endif
通过代码,我们可以发现,这个GPIO初始化,似乎有些是一样的,有些是不一样的,那么我们可不可以优化一下呢,另外我们发现在主函数里面调用的函数比较多,又都是一些初始化的函数,我们能不能处理一下呢?
话不多时我们在看代码:
新建Sys_Init.c和Sys_Init.h,将初始化函数放在这,在主函数直接调用Sys_Init()函数,可读性更强。
新建App_Gpio_Init.c和App_Gpio_Init.h,将GPIO引脚初始化都写在这,去掉App_LedInit();
和App_PortInit();函数,优化了代码,可读性更强。优化代码如下:
main.c
#include "main.h"
static boolean_t Flag=0;
SystemStatus_t SystemStatus;
int main()
{
Sys_Init();
while(1)
{
switch(SystemStatus)
{
case RxCompleteState:
{
Gpio_WriteOutputIO(GpioPortA, GpioPin0, Flag);
Flag ^= 1;
SystemStatus=DummyState;
break;
}
default:
break;
}
}
}
Sys_Init.c
/**
******************************************************************************
** \brief 系统初始化函数
**
** \return 无返回值
**
** 时钟初始化,设定为外部低速时钟32768Hz
** GPIO初始化
** 串口Serial初始化
** Timer0初始化 4M
** I2C1初始化
******************************************************************************/
#include "Sys_Init.h"
/**
******************************************************************************
** \brief 初始化函数
**
** \return 无返回值
**
** 各个函数初始化
**
******************************************************************************/
void Sys_Init(void)
{
App_Gpio_Init(); //GPIO初始化
App_Serial_Init(); //Serial初始化
Timer0_Init(); //Timer0初始化 4M
}
Sys_Init.h
#ifndef __SYS_INIT_H__
#define __SYS_INIT_H__
#include "App_Gpio_Init.h"
#include "App_Serial_Init.h"
#include "Timer0_Init.h"
#include "App_interrupts.h"
#include "ddl.h"
extern void Sys_Init(void);
extern uint8_t XoRCheck(uint8_t *array,uint8_t length);
#endif
App_Gpio_Init.c
#include "App_Gpio_Init.h"
/**
******************************************************************************
** \brief GPIO初始化函数
**
** \return 无返回值
** 晶振引脚初始化
** I2C引脚初始化,配置复用功能
** LPUART1引脚初始化,配置复用功能
******************************************************************************/
volatile uint8_t Flag;
void App_Gpio_Init()
{
const MCU_IO_TypeDef McuIoInitTbl[] =
{
{.port = GpioPortE, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE02
{.port = GpioPortE, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE03
{.port = GpioPortE, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE04
{.port = GpioPortE, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE05
{.port = GpioPortC, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC13
{.port = GpioPortC, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvH,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC14
{.port = GpioPortC, .pin = GpioPin15, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC15
{.port = GpioPortF, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF00
{.port = GpioPortF, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvH,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF01->Key
{.port = GpioPortC, .pin = GpioPin0, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC00->LED1
{.port = GpioPortC, .pin = GpioPin1, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC01->LED2
{.port = GpioPortC, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC02
{.port = GpioPortC, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC03
{.port = GpioPortA, .pin = GpioPin0, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA00
{.port = GpioPortA, .pin = GpioPin1, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA01
{.port = GpioPortA, .pin = GpioPin2, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA02->UART1_TXD
{.port = GpioPortA, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA03->UART1_RXD
{.port = GpioPortF, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF04
{.port = GpioPortF, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PF05
{.port = GpioPortA, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA04
{.port = GpioPortA, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA05
{.port = GpioPortA, .pin = GpioPin6, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA06
{.port = GpioPortA, .pin = GpioPin7, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA07
{.port = GpioPortC, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC04
{.port = GpioPortC, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC05
{.port = GpioPortB, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB00
{.port = GpioPortB, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB01
{.port = GpioPortB, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB02
{.port = GpioPortE, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE11
{.port = GpioPortE, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE12
{.port = GpioPortE, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE13
{.port = GpioPortE, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PE14
{.port = GpioPortB, .pin = GpioPin10, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB10
{.port = GpioPortB, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB11
{.port = GpioPortB, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB12
{.port = GpioPortB, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB13
{.port = GpioPortB, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB14
{.port = GpioPortB, .pin = GpioPin15, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PB15
{.port = GpioPortD, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD08
{.port = GpioPortD, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD09
{.port = GpioPortD, .pin = GpioPin10, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD10
{.port = GpioPortD, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD11
{.port = GpioPortC, .pin = GpioPin6, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC06
{.port = GpioPortC, .pin = GpioPin7, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC07
{.port = GpioPortC, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC08
{.port = GpioPortC, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC09
{.port = GpioPortA, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA08
{.port = GpioPortA, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA09
{.port = GpioPortA, .pin = GpioPin10, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA10
{.port = GpioPortA, .pin = GpioPin11, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA11
{.port = GpioPortA, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA12
//{.port = GpioPortA, .pin = GpioPin13, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
//.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA13->SWDIO
{.port = GpioPortF, .pin = GpioPin6, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdEnable, .io_cfg.enCtrlMode = GpioAHB}, //PF06->SCL
{.port = GpioPortF, .pin = GpioPin7, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdEnable, .io_cfg.enCtrlMode = GpioAHB}, //PF07->SCL
//{.port = GpioPortA, .pin = GpioPin14, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
//.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA14->SWCLK
{.port = GpioPortA, .pin = GpioPin15, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PA15->WP
{.port = GpioPortC, .pin = GpioPin10, .io_cfg.bOutputVal = TRUE , .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC10
{.port = GpioPortC, .pin = GpioPin11, .io_cfg.bOutputVal = TRUE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuEnable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC11
{.port = GpioPortC, .pin = GpioPin12, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PC12
{.port = GpioPortD, .pin = GpioPin0, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD00->SPI1_CS
{.port = GpioPortD, .pin = GpioPin1, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD01->SPI1_SCK
{.port = GpioPortD, .pin = GpioPin2, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD02
{.port = GpioPortD, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD03->SPI1_MISO
{.port = GpioPortD, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB}, //PD04->SPI1_MOSI
{.port = GpioPortB, .pin = GpioPin3, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB03
{.port = GpioPortB, .pin = GpioPin4, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB04
{.port = GpioPortB, .pin = GpioPin5, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB05
{.port = GpioPortB, .pin = GpioPin6, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB06
{.port = GpioPortB, .pin = GpioPin7, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB07
{.port = GpioPortB, .pin = GpioPin8, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirOut, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB }, //PB08->UART0_TXD
{.port = GpioPortB, .pin = GpioPin9, .io_cfg.bOutputVal = FALSE, .io_cfg.enDir = GpioDirIn, .io_cfg.enDrv = GpioDrvL,
.io_cfg.enPu = GpioPuDisable, .io_cfg.enPd = GpioPdDisable, .io_cfg.enOD = GpioOdDisable, .io_cfg.enCtrlMode = GpioAHB } //PB09->UART0_RXD
};
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
for(uint16_t i = 0; i<ARRAY_SZ(McuIoInitTbl); i++)
{
Gpio_Init(McuIoInitTbl[i].port, McuIoInitTbl[i].pin, (stc_gpio_cfg_t *)&McuIoInitTbl[i].io_cfg);
}
Gpio_SetAfMode(GpioPortA,GpioPin2,GpioAf1); //配置PA02为UART1_TX
Gpio_SetAfMode(GpioPortA,GpioPin3,GpioAf1); //配置PA03为UART1_RX
}
App_Gpio_Init.h
#ifndef __APP_GPIO_INIT_H__
#define __APP_GPIO_INIT_H__
#include "gpio.h"
#include "ddl.h"
#include "sysctrl.h"
/********************************************************************************
** \brief GPIO外设初始化结构体
******************************************************************************/
typedef struct{
en_gpio_port_t port; // GPIO端口号
en_gpio_pin_t pin; // GPIO引脚号
stc_gpio_cfg_t io_cfg; // GPIO配置信息
}MCU_IO_TypeDef;
void App_Gpio_Init(void);
#endif
写到这里,我们测试一下没啥问题。
但是单片机好像执行不起来,这是什么问题呢?复盘一下,我们就加了2个.c文件,为何运行不起来了?调试一下,发现我们在GPIO初始化的时候执行不下去了,我们给所有的引脚都初始化了,占据较大篇幅,根据Program Size: Code=4100 RO-data=2740 RW-data=4 ZI-data=596 ,计算出RAM在使用中的大小为4+596=600,转化为十六进制为258,再查看启动文件发现堆栈空间设置较小,不足以支持GPIO初始化操作。
更改堆栈空间的大小,查看数据手册发现,整个片内RAM区域的任何位置都可以作为堆栈区使用,因此我们可以将堆栈的空间调大一些,设置为0x00002000,也就是8192,8个字节。
重新烧录程序,进行测试,发现问题解决!