本帖最后由 chejia12 于 2023-11-30 19:42 编辑
先楫半导体HPM5361EVK--点亮一颗led
gpio分为io控制器和gpio控制器
2.1*IO 控制器 *
2.1.1IOC特性
- 外设复用功能映射
- 输出回送控制 (loopback)
- 模拟功能配置
- 压摆率配置
- 开漏设置
- 施密特触发器
- 上下拉配置
- 驱动能力配置
2.1.2基本配置IOC_X_PAD_CTL 寄存器
2.1.3外设功能配置 IOC_X_FUNC_CTL 寄存器
- 输出回送功能
- 模拟功能和外设
- 功能映射(外设引脚复用)
2.1.5涉及的数据结构
typedef struct {
struct {
__RW uint32_t FUNC_CTL;
__RW uint32_t PAD_CTL;
} PAD[456];
} IOC_Type;
电气属性相关的宏定义
- 回环使能
- 模拟输入使能
- 引脚复用选择ALT0~ALT31
- 施密特触发使能
- 上下拉电阻大小选择
- 上下拉选择
- 上下拉使能
- 电平保持使能
- 开漏使能
- 摇摆率高低速选择
- 引脚速度选择4种
- 驱动能力选择
2.2gpio控制器
2.2.1特性总结
本章节介绍 GPIO 控制器的主要特性:
- 配置 IO 作为输入或者输出
- 读取 IO 输入的状态
- 设置 IO 的输出
- 原子化操作设置 IO 输出高,输出低,翻转
GPIO,PGPIO 支持配置 GPIO 中断,FGPIO0 不支持生成中断。
2.2.2GPIO** 控制
OE:控制gpio方向
DO:控制输出电平
DI 寄存器可以实现 IO 监听和状态读取
原子化操作寄存器
- 输出高寄存器 SET
- 输出低寄存器 CLEAR
- 翻转寄存器 TOGGLE
2.2.3GPIO中断
- IE 寄存器打开 GPIO 中断
- TP 寄存器来指定中断的类型;置 1,表示中断由边沿触发,置0,表示中断由电平触发。
- PL 寄存器来指定中断的极性;位置 1,表示中断由下降沿或者低电平触发,置 0,表示中断由上升沿或高电平触发
- IF 寄存器来查询中断的状态,对应标志位置 1,表示对应 IO 有中断待处理;位写 1,可以清除这个标志位
- GPIO 控制器支持在检测到上升沿或下降沿生成中断,也支持双沿或单沿触发模式。
- GPIO 支持生成异步中断,异步中断允许在系统时钟异常时生成中断。
2.2.4相关的数据结构
typedef struct {
struct {
__Ruint32_t VALUE;
__Ruint8_tRESERVED0[12];
} DI[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} DO[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} OE[16];
struct {
__Wuint32_t VALUE;
__Ruint8_tRESERVED0[12];
} IF[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} IE[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} PL[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} TP[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} AS[16];
struct {
__RW uint32_t VALUE;
__RW uint32_t SET;
__RW uint32_t CLEAR;
__RW uint32_t TOGGLE;
} PD[16];
} GPIO_Type;
LED使用场景的配置方法
配置复用
配置电气属性;
void init_gpio_pins(void)
{
uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_GPIO_A_09;
HPM_IOC->PAD[IOC_PAD_PA09].PAD_CTL = pad_ctl;
}
设置gpio属性
gpio_set_pin_input(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN);
gpio_write_pin(HPM_GPIO0, GPIO_DI_GPIOA,23, 1);
LED电平翻转
gpio_toggle_pin(HPM_GPIO0, GPIO_DI_GPIOA,23, 1);
LED实例
配置gpio
*/
void bsp_init_gpio_pins(void)
{
上下拉使能,上拉,使能施密特触发器
configure pad setting: pull enable and pull up, schmitt trigger enable */
uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
HPM_IOC->PAD[IOC_PAD_PA23].FUNC_CTL = IOC_PA23_FUNC_CTL_GPIO_A_23;
HPM_IOC->PAD[IOC_PAD_PA23].PAD_CTL = pad_ctl;
}
配置gpio方向
in_out=1:out
in_out=1:in
*/
void bsp_init_gpio(int in_out)
{
if(in_out)
{
gpio_set_pin_output(HPM_GPIO0, GPIO_DI_GPIOA, IOC_PAD_PA23);
}
else{
gpio_set_pin_input(HPM_GPIO0, GPIO_DI_GPIOA, IOC_PAD_PA23);
}
}
int main(void)
{
board_init();
bsp_init_gpio_pins();
bsp_init_gpio(1);
printf("gpio example\n");
gpio_write_pin(HPM_GPIO0, GPIO_DI_GPIOA, IOC_PAD_PA23,1);
for (uint32_t i = 0; i < 10; i++) {
gpio_toggle_pin(HPM_GPIO0, GPIO_DI_GPIOA, IOC_PAD_PA23);
board_delay_ms(500);
gpio_toggle_pin(HPM_GPIO0, GPIO_DI_GPIOA, IOC_PAD_PA23);
board_delay_ms(500);
printf("toggling led %u/%u times\n", i + 1, 10);
}
while (1);
return 0;
}
按键中断实例
#include "board.h"
#include "hpm_gpio_drv.h"
void inti_key_int(void)
{
gpio_interrupt_trigger_t trigger;
gpio_set_pin_output(HPM_GPIO0, GPIO_DI_GPIOA,23);
gpio_set_pin_input(HPM_GPIO0, GPIO_DI_GPIOA,9);
trigger = gpio_interrupt_trigger_edge_both;
gpio_config_pin_interrupt(HPM_GPIO0, GPIO_DI_GPIOA,9, trigger);
gpio_enable_pin_interrupt(HPM_GPIO0, GPIO_DI_GPIOA,9);
intc_m_enable_irq_with_priority(IRQn_GPIO0_A, 1);
}
void isr_gpio(void)
{
gpio_clear_pin_interrupt_flag(HPM_GPIO0, GPIO_DI_GPIOA,9);
gpio_toggle_pin(HPM_GPIO0, GPIO_DI_GPIOA,23);
printf("toggle led pin output\n");
if (gpio_read_pin(HPM_GPIO0, GPIO_DI_GPIOA,9) == false) {
printf("user key pressed\n");
} else {
printf("user key released\n");
}
}
SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_A, isr_gpio)
int main(void)
{
board_init();
board_init_gpio_pins();
inti_key_int();
printf("gpio example\n");
while (1);
return 0;
}
寄存器分组
#define GPIO_DI_GPIOA (0UL)
#define GPIO_DI_GPIOB (1UL)
#define GPIO_DI_GPIOC (2UL)
#define GPIO_DI_GPIOD (3UL)
#define GPIO_DI_GPIOE (4UL)
#define GPIO_DI_GPIOF (5UL)
#define GPIO_DI_GPIOX (13UL)
#define GPIO_DI_GPIOY (14UL)
#define GPIO_DI_GPIOZ (15UL)
gpio触发结构体
* @brief Interrupt trigger type
*/
typedef enum gpio_interrupt_trigger {
gpio_interrupt_trigger_level_high = 0,
gpio_interrupt_trigger_level_low,
gpio_interrupt_trigger_edge_rising,
gpio_interrupt_trigger_edge_falling,
#if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)
gpio_interrupt_trigger_edge_both,
#endif
} gpio_interrupt_trigger_t;