本帖最后由 zhangbaoyin 于 2023-6-2 22:59 编辑
AT32F435 支持多达116 个双向I/O 引脚,这些引脚分为8 组,分别为PA0-PA15、PB0-PB15、PC0-PC15、PD0-PD15、PE0-PE15、PF0-PF15、PG0-PG15、PH0-PH3 每个引脚都可以实现与外部的通讯、控制以及数据采集的功能。
- 每个引脚都支持通用功能输入输出(GPIO)或复用功能输入输出(IOMUX)。
- 每个引脚都可以软件配置成浮空输入、上拉/下拉输入、模拟输入/输出、通用推挽/开漏输出、复用推挽/开漏输出。
- 每个引脚都有独立的弱上拉/下拉功能。
- 每个引脚都可以软件配置输出驱动能力。
- 每个引脚都可以配置为外部中断输入。
- 每个引脚都支持配置锁定功能。
根据寄存器手册6.2.1GPIO功能描述,可以看到,所有GPIO均挂载到AHB高速总线上,其时钟频率和CPU的时钟频率相同(实际GPIO翻转速率将再后续评测中测试)。 所有用户可以正常使用的GPIO默认复位状态均为浮空输入模式。
在官方寄存器手册中有这样一句话:
注意: 如果是浮空输入模式,为避免复杂环境下,没有使用的引脚有干扰,导致漏电,建议, 如引脚不使用,则配置为模拟输入模式。
一、GPIO模式选择
GPIO的模式一般都分为3种情况:通用功能输入、模拟输入/输出、通用功能输出。
- 通用功能输入模式。
- 模拟输入/输出
- 通用功能输出
当GPIO 端口被配置为输出时:
- 施密特触发器有效
- 可通过输出寄存器让对应引脚输出
- 在开漏模式时,可强输出0,可用上拉电阻输出1
- 在推挽模式时,可通过输出寄存器输出数字0/1。
- 提供GPIO 设置/清除寄存器控制对应的GPIO数据输出寄存器的设置/清除
二、IOMUX复用功能
引用STM32寄存器手册中对于端口复用功能的描述:
STM32Fxx内部集成了很多的外设控制器,比如USART、SPI、bxCAN等等,这些外设控制器,也需要通过引脚与外设连接。复用功能是相对于单片机的引脚而言的。所谓“复用功能”,是指单片机的引脚既可以做普通GPIO使用,也可以作为内部外设控制器的引脚来使用。首先,PA5可以做为普通GPIO来使用;其次,如果作为外设的引脚,它可以作为SPI1的时钟(SPI1_SCK)、DAC的输出通道1(DAC_OUT1)或者ADC的输入通道5(ADC12_IN5)。PA5支持的三种外设(SPI1、DAC、ADC)在同一时刻只能选择一种,选择的方法是开启相应外设的时钟,并使其它外设的时钟保持关闭状态。如果PA5被配置为复用功能,但是没有开启它支持的任何外设的时钟,它的输出是不确定的。
也即是说,为了排除其他复用功能带来的干扰(例如STM32F103小蓝板,IIC1的SCL和FSMC功能复用了,导致iic通信的OLED液晶屏无法正常显示,但时序是正确的)。开启MUX复用功能寄存器,管脚只连接其中一个功能的复用功能,把其他功能断开,就可以排除其他功能带来的影响。
例如,AT32F435@iic1 的SCL和SDA连接到管脚PB6和PB7,这两个管脚还复用了TMR4_CH1、TMR4_CH2、TMR8_BRK、SPI4_CS、USART1_TX、USART1_RX、UART5_TX、DVP_D5、DVP_VSYNC等。 通过“ 寄存器手册-6.2.9 IOMUX功能输入/输出 ”章节可以查出每个管脚复用功能的 MUXy 。通过设置相关寄存器,即可连接管脚。
IIC1通信的管脚初始化:
#define I2Cx_SCL_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_PIN GPIO_PINS_6
#define I2Cx_SCL_GPIO_PinsSource GPIO_PINS_SOURCE6
#define I2Cx_SCL_GPIO_PORT GPIOB
#define I2Cx_SCL_GPIO_MUX GPIO_MUX_4
#define I2Cx_SDA_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SDA_GPIO_PIN GPIO_PINS_7
#define I2Cx_SDA_GPIO_PinsSource GPIO_PINS_SOURCE7
#define I2Cx_SDA_GPIO_PORT GPIOB
#define I2Cx_SDA_GPIO_MUX GPIO_MUX_4
/* i2c periph clock enable */
crm_periph_clock_enable(I2Cx_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
/* gpio configuration */
gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
/* configure i2c pins: scl */
gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_structure.gpio_mode = GPIO_MODE_MUX;
gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
gpio_init_structure.gpio_pull = GPIO_PULL_UP;
gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN;
gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);
/* configure i2c pins: sda */
gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN;
gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);
三、寄存器描述
- GPIO配置寄存器(GPIOx_CFGR)
- GPIO输出模式寄存器(GPIOx_OMODE)
- GPIO电流推动/吸入能力切换控制寄存器(GPIOx_ODRVR)
- GPIO上/下拉寄存器(GPIOx_PULL)(x=A..H)
以上寄存器和传统32寄存器配置是一样的,参考技术手册即可。需要注意的是:
1. GPIO_Toggle的方法(SCR、ODT寄存器)
当GPIO配置为通用输出模式时候,可以通过GPIO的ODT寄存器和来SCR寄存器来配置GPIO的高低电平。
但需要注意的是,ODT寄存器为可读可写(RW),SCR寄存器为只读(RO)
所以在配置Toggle的时候,应该使用ODT寄存器异或,如以下代码所示:
//系统时钟设置到144MHz
system_clock_config();
at32_board_init();
// 点灯
GPIOD->odt = (0x0000);
delay_ms(500);
// 灭灯
GPIOD->odt = (0x2000|0x4000|0x8000);
delay_ms(500);
while(1)
{
GPIOD->odt ^= (0x2000|0x4000|0x8000);
delay_ms(500);
}
实际效果
8f928505fc01842ce3214945e4197240
使用SCR寄存器异或:
//系统时钟设置到144MHz
system_clock_config();
at32_board_init();
// 点灯
GPIOD->scr = (0x20000000|0x40000000|0x80000000);
delay_ms(500);
// 灭灯
GPIOD->scr = (0x00002000|0x00004000|0x00008000);
delay_ms(500);
while(1)
{
GPIOD->scr ^= (0x20000000|0x40000000|0x80000000)|(0x00002000|0x00004000|0x00008000);
delay_ms(500);
}
实际效果
8fdb4dc6ec6a62df286fd0da49122758
2. 极大电流推动/吸入能力切换控制(HDRV寄存器)
注意到,在GPIO的最后一个寄存器中,有一个 极大电流推动/吸入能力切换控制 寄存器,该寄存器默认复位值为0x0000,即关闭极大电流驱动。
在 6.2.5通用功能输出配置 中,有如下表格
000:输出模式,适中电流推动/吸入能力
001:输出模式,较大电流推动/吸入能力
010:输出模式,适中电流推动/吸入能力
011:输出模式,适中电流推动/吸入能力
1xx:输出模式,极大电流推动/吸入能力
不难发现,要使用极大电流推动/吸入能力功能,只需要将对应位的HDRV位置1即可。对应代码:
//PD13开启极大电流推动/吸入能力
GPIOD->hdrv = (0x2000);
//PD13关闭极大电流推动/吸入能力
GPIOD->hdrv = (0x0000);
实际测量:
- 关闭HDRV测出的电流值为48.7mA,已经明显大于普通32位单片机的17mA推挽输出电流
- 开启HDRV测出的电流值为91.7mA
至此,GPIO到此为止