文章目录
- 一、简介
- 二、功能描述
- 三、GPIO寄存器
- 1. GPIO 配置 低寄存器 (GPIOx_CFGLR )(x=A..E )
- 2. GPIO 配置高寄存器 (GPIOx_CFGHR )(A..E )
- 3. GPIO 输入数据寄存器 (GPIOx_IDT )(x=A..E )
- 4. GPIO 输出数据寄存器 (GPIOx_ODT )(x=A..E)
- 5. GPIO 设置/ 清除寄存器 (GPIOx_SCR )(x=A..E )
- 6. GPIO 清除寄存器 (GPIOx_CLR )(x=A..E )
- 7. GPIO 写保护 寄存器 (GPIOx_WPR )(x=A..E)
- 8. GPIO 极大电流推动/ 吸入能力 切换控制寄存器(GPIOx_HDRV )(x=A..E )
- 四、GPIO编程实例
一、简介
AT32F403A/407/407A 支持多达 80 个双向 I/O 管脚,这些管脚分为 5 组,分别为 PA、PB、PC、PD 和
PE,每组最多包含 16 个管脚,每个管脚都可以实现与外部的通讯、控制以及数据采集的功能。
每个管脚都支持通用功能输入输出(GPIO)或复用功能输入输出(IOMUX)。本章节详细介绍 GPIO 功
能,IOMUX 功能详见复用功能输入输出章节。
每个管脚都可以软件配置成浮空输入、上拉/下拉输入、模拟输入/输出、通用推挽/开漏输出、复用推挽/开
漏输出。
每个管脚都可以软件配置输出驱动能力以及输出信号斜率。
每个管脚都可以配置为外部中断输入。
每个管脚都支持配置锁定功能。
二、功能描述
1.GPIO结构
``
每个管脚可以由软件配置成四种输入模式(输入浮空、输入上拉、输入下拉、模拟输入)和四种输出模式
(开漏输出、推挽式输出、推挽式复用、开漏复用)。
每个 I/O 端口对应的寄存器不允许半字或字节访问,必须按 32 位字被访问,每个 I/O 端口位可以自由编
程。
下图给出了一个 I/O 端口位的基本结构。
2.GPIO 复位状态
系统上电或复位后,所有管脚除了 JATG 相关管脚以外,都被配置为浮空输入模式,JTAG 相关管脚则配
置为:PA15/JTDI 、PA13/JTMS 和 PB4/JNTRST 为输入上拉模式,PA14/JTCK 为输入下拉模式,
PB3/TDO 为浮空输入模式。
2.通用功能输入配置
当管脚配置为输入时:
管脚状态可通过对输入数据寄存器的读访问得到
可配置管脚为浮空输入、上拉输入或下拉输入
施密特触发器有效
不能对该管脚进行输出。
注意: 如果是浮空输入模式,为避免复杂环境下,没有使用的管脚有干扰,导致漏电,建
议,如管脚不使用,则配置为模拟输入模式。
3.模拟 输入/ 输出
当 GPIO 端口被配置为模拟输入配置时:
施密特触发无效
不能对该管脚进行数字输入输出
对应的管脚,无任何上拉/下拉电阻。
4.通用功能输出配置
当 GPIO 端口被配置为输出时:
施密特触发器有效
可通过输出寄存器让对应管脚输出
上拉和下拉电阻不能被使用
在开漏模式时,可强输出 0,可用上拉电阻输出 1。
在推挽模式时,可通过输出寄存器输出数字 0/1。
CONF = 10 或 11 时,为复用输出,详情请参考 IOMUX 章节
5.I/O 端口 保护
为了防止误操作导致 GPIO 功能混乱,提供每个对应管脚的的锁定机制。一旦锁定,在下次复位或者上电
之前都不能进行对应管脚的 GPIO 配置。
三、GPIO寄存器
下面列出了 GPIO 寄存器映射和复位数值。
必须以字(32 位)的方式操作这些外设寄存器。
表 6-1 GPIO寄存器地址映射和复位值
1. GPIO 配置 低寄存器 (GPIOx_CFGLR )(x=A…E )
注意:有些端口寄存器复位值不同,比如 PA 有些管脚默认是 JTAG/SWD 有上拉输入管脚。
2. GPIO 配置高寄存器 (GPIOx_CFGHR )(A…E )
注意:有些端口寄存器复位值不同,比如 PB 有些管脚默认是 JTAG/SWD 有上拉输入管脚
3. GPIO 输入数据寄存器 (GPIOx_IDT )(x=A…E )
4. GPIO 输出数据寄存器 (GPIOx_ODT )(x=A…E)
5. GPIO 设置/ 清除寄存器 (GPIOx_SCR )(x=A…E )
6. GPIO 清除寄存器 (GPIOx_CLR )(x=A…E )
7. GPIO 写保护 寄存器 (GPIOx_WPR )(x=A…E)
8. GPIO 极大电流推动/ 吸入能力 切换控制寄存器(GPIOx_HDRV )(x=A…E )
四、GPIO编程实例
以最新的AT32F403A_407_Firmware_Library-v2.0.9库为例
1. 按键输入GPIO配置
头文件宏定义
/******************* define button *******************/
typedef enum
{
USER_BUTTON = 0,
NO_BUTTON = 1
} button_type;
#define USER_BUTTON_PIN GPIO_PINS_0
#define USER_BUTTON_PORT GPIOA
#define USER_BUTTON_CRM_CLK CRM_GPIOA_PERIPH_CLOCK
源文件程序按键输入配置
/**
* @brief configure button gpio
* @param button: specifies the button to be configured.
* @retval none
*/
void at32_button_init(void)
{
gpio_init_type gpio_init_struct;
/* enable the button clock */
crm_periph_clock_enable(USER_BUTTON_CRM_CLK, TRUE);
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
/* configure button pin as input with pull-up/pull-down */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pins = USER_BUTTON_PIN;
gpio_init_struct.gpio_pull = GPIO_PULL_DOWN;
gpio_init(USER_BUTTON_PORT, &gpio_init_struct);
}
2. LED灯输出配置
头文件定义:
/******************** define led ********************/
typedef enum
{
LED2 = 0,
LED3 = 1,
LED4 = 2
} led_type;
#define LED_NUM 3
#if defined (AT_START_F403A_V1) || defined (AT_START_F407_V1)
#define LED2_PIN GPIO_PINS_13
#define LED2_GPIO GPIOD
#define LED2_GPIO_CRM_CLK CRM_GPIOD_PERIPH_CLOCK
#define LED3_PIN GPIO_PINS_14
#define LED3_GPIO GPIOD
#define LED3_GPIO_CRM_CLK CRM_GPIOD_PERIPH_CLOCK
#define LED4_PIN GPIO_PINS_15
#define LED4_GPIO GPIOD
#define LED4_GPIO_CRM_CLK CRM_GPIOD_PERIPH_CLOCK
#endif
源文件程序LED初始化配置
/**
* @brief configure led gpio
* @param led: specifies the led to be configured.
* @retval none
*/
void at32_led_init(led_type led)
{
gpio_init_type gpio_init_struct;
/* enable the led clock */
crm_periph_clock_enable(led_gpio_crm_clk[led], TRUE);
/* set default parameter */
gpio_default_para_init(&gpio_init_struct);
/* configure the led gpio */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
gpio_init_struct.gpio_pins = led_gpio_pin[led];
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(led_gpio_port[led], &gpio_init_struct);
}
3. 模拟量输入配置
/**
* @brief gpio configuration.
* @param none
* @retval none
*/
static void adc_gpio_config(void)
{
gpio_init_type gpio_initstructure;
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_initstructure);
gpio_initstructure.gpio_mode = GPIO_MODE_ANALOG;
gpio_initstructure.gpio_pins = GPIO_PINS_4 | GPIO_PINS_5 | GPIO_PINS_6 | GPIO_PINS_7;
gpio_init(GPIOA, &gpio_initstructure);
gpio_initstructure.gpio_mode = GPIO_MODE_ANALOG;
gpio_initstructure.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1;
gpio_init(GPIOB, &gpio_initstructure);
}