【雅特力AT-START-F435】GPIO&EXTI
[复制链接]
【雅特力AT-START-F435】GPIO&EXTI使用
本文主要是学习AT32F435的GPIO&EXTI功能。参考代码为AT32F435_437_Firmware_Library_V2.1.2\project\at_start_f435\templates
模板中代码主要分为五个部分
①时钟初始化:
②GPIO初始化
③外部中断初始化
④While(1)中闪灯程序
⑤外部中断中更改闪灯速度
其中①时钟配置部分已经完成,本文针对②-⑤部分
GPIO
初始化API
配置过程:首先打开初始化GPIO的时钟,然后配置GPIO的参数(很经典了)
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);
}
GPIO的配置参数有IO引脚、IO模式、输出模式(开漏输出、推挽式输出、推挽式复用、开漏复用)、输入模式(输入浮空、输入上拉、输入下拉、模拟输入)、驱动能力(强、弱两个等级)
typedef struct
{
uint32_t gpio_pins; /*!< pins number selection */
gpio_output_type gpio_out_type; /*!< output type selection */
gpio_pull_type gpio_pull; /*!< pull type selection */
gpio_mode_type gpio_mode; /*!< mode selection */
gpio_drive_type gpio_drive_strength; /*!< drive strength selection */
} gpio_init_type;
功能函数API
输入模式:
flag_status gpio_input_data_bit_read(gpio_type *gpio_x, uint16_t pins);
uint16_t gpio_input_data_read(gpio_type *gpio_x);
flag_status gpio_output_data_bit_read(gpio_type *gpio_x, uint16_t pins);
uint16_t gpio_output_data_read(gpio_type *gpio_x);
输出模式:
void gpio_bits_set(gpio_type *gpio_x, uint16_t pins);
void gpio_bits_reset(gpio_type *gpio_x, uint16_t pins);
void gpio_bits_write(gpio_type *gpio_x, uint16_t pins, confirm_state bit_state);
void gpio_port_write(gpio_type *gpio_x, uint16_t port_value);
EXTI
初始化
在crm中使能EXTI的时钟,配置GPIO引脚和外部中断源,配置外部中断的参数,分配NVIC优先级,使能NVIC。
void button_exint_init(void)
{
exint_init_type exint_init_struct;
crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOA, SCFG_PINS_SOURCE0);
exint_default_para_init(&exint_init_struct);
exint_init_struct.line_enable = TRUE;
exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
exint_init_struct.line_select = EXINT_LINE_0;
exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
exint_init(&exint_init_struct);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(EXINT0_IRQn, 0, 0);
}
参数上需要选择外部中断的类型(事件或者中断)、中断源、极性(上升沿、下降沿、上升下降沿)、使能位
typedef struct
{
exint_line_mode_type line_mode;
uint32_t line_select;
exint_polarity_config_type line_polarity;
confirm_state line_enable;
} exint_init_type;
功能函数API
清除中断标志位
void exint_flag_clear(uint32_t exint_line);
获取中断标志位
flag_status exint_flag_get(uint32_t exint_line);
软件产生一个外部中断
void exint_software_interrupt_event_generate(uint32_t exint_line);
中断使能
void exint_interrupt_enable(uint32_t exint_line, confirm_state new_state);
事件使能
void exint_event_enable(uint32_t exint_line, confirm_state new_state);
闪灯程序改写
都说会点灯就算是单片机入门了,但是例程中实现的方式不太优雅,因此稍稍改写了一点。
大概思路是用一个uint_32类型的变量记录LED的闪烁顺序,用然后依次移位判断LED的闪烁次序,因此只用提供一个周期性调度就可以显示LED的复杂闪烁效果了
LED参数结构体如下:
typedef struct
{
gpio_type* led_port;
uint16_t led_pin;
uint8_t blink_tikcs;
x_l_blink_mode_t x_l_blink_mode;
}x_l_blink_init_t;
LED状态类型
typedef enum
{
X_L_LED_ON = 0,
X_L_LED_OFF,
X_L_LED_BLINK_MODE_A,
X_L_LED_BLINK_MODE_B,
X_L_LED_BLINK_MODE_C,
}x_l_blink_mode_t;
__IO const uint32_t x_l_blink_mode_a = 0x0F0F0F0F;
__IO const uint32_t x_l_blink_mode_b = 0x50505050;
__IO const uint32_t x_l_blink_mode_c = 0x0A0A0A0A;
灯闪逻辑
uint8_t mode_a_status = 0;
mode_a_status = (((x_l_blink_mode_a >> (x_l_blink_init->blink_tikcs)) & 0x00000001) == 1) ? 1 : 0;
x_l_blink_init->blink_tikcs++;
if (x_l_blink_init->blink_tikcs >= 31)
{
x_l_blink_init->blink_tikcs = 0;
}
if (mode_a_status == 1)
{
LED_ON;
}
else
{
LED_OFF;
}
实现效果
通过按键切换灯的模式,编辑灯的闪烁顺序就可实现复杂的效果
飞书20230531-225456
|