本文最后更新于19 天前,其中的信息可能已经过时,如有错误请发送邮件到tudougin@163.com
1. BAT32的GPIO
P00~P02和P10~P13端口只能作为数字通道使用。P20~P26和P30~P37端口既可作为数字通道使用,也可作为模拟通道使用。
- 数字IO:P01, P02, P10, P11, P12, P13, P20, P21, P35, P36, P37
- 数字/模拟IO:P22, P23, P24, P25, P26, P30, P31, P32, P33, P34
- 特殊功能:P00(外部复位输入)
数字功能分类:
- 中断输入:
INTP0
~INTP3
- 定时器输入/输出:
TI00
~TI13
,TO00
~TO13
- 通信接口:
- I²C:
SCLA0
,SDAA0
- SPI/UART:
SS00
,SCLKxx
,SDIxx/RxDx
,SDOxx/TxDx
- I²C:
- 时钟/信号输出:
- 蜂鸣器:
CLKBUZ0
,CLKBUZ1
- VCO:
VCOUT0
,VCOUT1
- RTC:
RTC1HZ
- 蜂鸣器:
2. GPIO的输入输出
2.1 GPIO输入
- 输入浮空
- 输入上拉
- 输入下拉
- 模拟通道
2.1.1 GPIO的输入配置
GPIO_PullUp_Enable(&PORT->P0, 0xFF); //P0上拉使能,Bit[7:0] = 0xFF,每一位均使能
GPIO_PullDown_Enable(&PORT->P2, 0x03); //P2下拉使能,Bit[1:0] = 0b11,P20、P21使能
GPIO_Input_Enable(&PORT->P2, 0x03); //P2输入使能,Bit[1:0] = 0b11,P20、P21使能
2.1.2 GPIO引脚电平读取
GPIO_Get_Value(&PORT->P1); //读取P1各口电平
PORT_GetBit(PORT2,PIN5); //读取P25电平
2.2 GPIO输出
- 开漏输出
- 推挽式输出
- 推挽式复用功能
- 开漏复用功能
2.2.1 GPIO的输出配置
GPIO_Nch_OpenDrain(&PORT->P1, 0x04); //P1开漏使能,Bit[2] = 0b1, P12使能
2.2.2 GPIO引脚电平设置
GPIO_Set_Value(&PORT->P1,0x08); //设置P1各口电平
PORT_SetBit(PORT2,PIN5); //置位P25电平
PORT_ClrBit(PORT2,PIN5); //清零P25电平
PORT_ToggleBit(PORT2,PIN5); //取反P25电平
2.2.3 GPIO引脚一键配置
typedef enum {
INPUT = 0,
PULLUP_INPUT,
TTL_INPUT,
ANALOG_INPUT,
OUTPUT,
OPENDRAIN_OUTPUT,
PULLDOWN_INPUT,
}PIN_ModeDef;
PORT_Init(PORT2,PIN5,PULLUP_INPUT); //设置P25上拉输入
2.3 复用IO
PmnCFG
配置Pmn
引脚功能模式
- 使用端口的数字兼用功能时,端口必须配置成数字模式(PMCxx=0)。
- 对于复用的输入功能,端口必须配置成输入模式(PMxx=1)。
- 对于复用的输出功能,端口必须配置成输出模式(推挽或开漏) (PMxx=0)。
- 对于双向复用功能,端口必须配置成输出模式(推挽或开漏)(PMxx=0)。这时,输入驱动器被配置成浮空输入模式。
- 使用 P01,P02 端口的 GPIO 功能或者复用功能时,确认其 X1 震荡模式和外部时钟输入模式没有开启。参照“4.3.1 时钟运行模式控制寄存器(CMC)”
- 使用 P12,P13 端口的 GPIO 功能或者复用功能时,确认其 XT1 震荡模式和外部时钟输入模式没有开启。参照“4.3.1 时钟运行模式控制寄存器(CMC)”
- P00 没有端口复用功能,仅能作为 GPIO 输入使用。使用 P00 的的 GPIO 输入功能时,需要先配置寄存器 RSTM,将其外部复位功能屏蔽。参照“2.5.1 P00 端口(默认为 RESETB)”。
- 不能将同一个复用输入功能同时配置到不同端口,不能将不同的复用功能同时配置到同一个端口。
2.4 GPIO的初始化
防止漏电流的端口初始化
void Port_Init(void){
GPIO_PullUp_Enable(&PORT->P0, 0xFF);
GPIO_PullUp_Enable(&PORT->P1, 0xFF);
GPIO_PullUp_Enable(&PORT->P2, 0xFC);
GPIO_PullUp_Disable(&PORT->P2, 0x03);
GPIO_PullDown_Enable(&PORT->P2, 0x03);
GPIO_PullUp_Enable(&PORT->P3, 0xFF);
GPIO_Output_Enable(&PORT->P0, 0x06); // P01/X1, P02/X2 output low level
GPIO_Output_Enable(&PORT->P1, 0x0C); // P12/XT1, P13/XT2 output low level
}
3. 外部引脚中断
3.1 外部中断的配置
INTP_Init(1 << 2, INTP_FALLING); // Initializes INTP2
#define INTP2_PORT_SETTING() do{ \
PORT->P32CFG = PTCFG_INTP2; /* allocate INTP2 to P32 */ \
PORT->PM3 |= (1 << 2); /* P32 is used as INTP2 input */ \
PORT->PMC3 &= ~(1 << 2); /* P32 digital function */ \
}while(0)
INTP_Start(1 << 2); // Enable INTP2 Interrupt
3.2 中断处理
/***********************************************************************************************************************
* Function Name: intp_2_interrupt
* @brief INTP2 interrupt service routine
* @param None
* @return None
***********************************************************************************************************************/
void intp_2_interrupt(void)
{
INTC_ClearPendingIRQ(INTP2_IRQn);
intp2_callback();
/* Start user code. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
}
/***********************************************************************************************************************
* Function Name: intp2_callback
* @brief This function is a callback function when INTP2 interrupt occurs.
* @param None
* @return None
***********************************************************************************************************************/
static void intp2_callback(void)
{
/* Start user code. Do not edit comment generated here */
g_intp2Taken++;
/* End user code. Do not edit comment generated here */
}
4. 示例代码
4.1 按键轮询控制
本示例中,P30 引脚配置为输入,用于检测按键状态;P31 引脚配置为输出,用于驱动 LED 灯(LED1)。系统通过轮询方式检测按键是否按下,并在检测到有效按键事件(消抖处理后)时,切换 LED 的状态(高低电平翻转)。
#include "BAT32G133.h"
#include "gpio.h"
#include "userdefine.h"
#define LED1Port PORT3
#define LED1Pin PIN1
#define KEYPort PORT3
#define KEYPin PIN0
#define LED1Init() do{ \
PORT_Init(LED1Port,LED1Pin,OUTPUT);\
PORT_ClrBit(LED1Port,LED1Pin);\
}while(0)
#define KEYInit() do{ \
PORT_Init(KEYPort,KEYPin,INPUT);\
}while(0)
#define ReadKEY() PORT_GetBit(KEYPort,KEYPin)
void BspInit(void){
LED1Init();
KEYInit();
}
void main(void){
BSPInit();
while(1){
if(ReadKEY() == 0){
delayMs(10);
if(ReadKEY() == 0){
while(ReadKEY() == 0);
flag ^= 1;
SetLED1(flag);
}
}
delayMs(10);
}
}
4.2 按键中断控制
在本示例中,P30 引脚配置为外部中断输入,并通过外部上拉电阻保持高电平,按键按下后引脚电平发生变化,在检测到上升沿时触发中断服务程序;P31 引脚配置为通用推挽输出,用于驱动 LED 指示灯(LED1)。系统通过外部中断方式响应按键事件,在中断服务函数中切换 LED 的输出状态,从而实现对 LED 灯的控制。
- 按键输入(KEY):
- 引脚:P30(PORT3, PIN0)
- 功能:配置为外部中断通道 INTP1 的输入引脚
- 触发方式:上升沿触发
- LED 输出(LED1):
- 引脚:P31(PORT3, PIN1)
- 功能:推挽输出,用于驱动 LED
#include "BAT32G133.h"
#include "gpio.h"
#include "intp.h"
#include "userdefine.h"
//宏定义与初始化说明:
#define LED1Port PORT3
#define LED1Pin PIN1
#define KEYPort PORT3
#define KEYPin PIN0
#define KEYIntp 1
#define LED1Init() do{ \
PORT_Init(LED1Port,LED1Pin,OUTPUT);\
PORT_ClrBit(LED1Port,LED1Pin);\
}while(0)
#define ReadKEY() PORT_GetBit(KEYPort,KEYPin)
//按键初始化函数:
void KEYInit(void){
PORT_Init(KEYPort,KEYPin,INPUT);
INTP_Init(1 << KEYIntp, INTP_RISING); // Initializes P32/INTP2
INTP_Start(1 << KEYIntp); // Enable INTP2 Interrupt
}
void main(void){
BSPInit();
while(1){
getchar();
}
}
//中断引脚配置
//如需将 INTP1 分配到其他引脚,请根据 MCU 支持通过 PxxCFG 配置寄存器进行引脚复用设置。
#define INTP1_PORT_SETTING() do{ \
PORT->P30CFG = PTCFG_INTP1; /* allocate INTP1 to P31 */ \
PORT->PM3 |= (1 << 0); /* P31 is used as INTP1 input */ \
PORT->PMC3 &= ~(1 << 0); /* P31 digital function */ \
}while(0)
//修改中断回调函数
static void intp1_callback(void)
{
/* Start user code. Do not edit comment generated here */
g_intp1Taken++;
flag ^= 1;
SetLED1(flag);
/* End user code. Do not edit comment generated here */
}