如何快速使用AT32的GPIO?
我们都知道,使用STM32的时候,芯片配置起来很方便使用CubeMX,它们是如何配置我们不用深入的了解,配置好了只要使用相应的函数就可以了,但是AT32没有像CubeMX的软件,那我们如何快速配置呢?我们都知道AT32几乎平替STM32,实际上用CubeMX生成的配置也是可以驱动AT32的,但是我这里推荐使用AT32的官方库,因为他官方的库适配性肯定是最好的,而且性能和功能上能得到深度开发,比如弹性DMA这个是STM32没有的,当然at32的库理解起来不是很难,而且资料健全,也有相关的demo,使用过stm32固件库的配用上手应该能快一点,这里就不多说了,因为芯片内部都大同小异,只是函数上有所区别而已。
手册部分
这是at32f437固件库应用指南GPIO章节的截图,这里讲解了GPIO各个函数的功能及用法,还有结构体成员的说明,等了解之后查看官方提供的demo。
这是at32F437 led闪烁的demo,实际上跟st一样,定义结构体,初始化对应的时钟,对结构成员进行配置,然后最后初始化这个结构体。
实际应用
我对固件库进行了二次封装,方便配置的同时,能够深入了解底层配置了哪里,下面只大概讲解一下,想详细了解的朋友可以自行下载:链接: GitHub
typedef struct my_gpio
{
crm_periph_clock_type gpio_crm_clk;
gpio_type *gpiox;
uint16_t pinx;
uint8_t gpio_mode;
uint8_t init_val;
uint8_t state;
}gpio_struct;
首先定义一个结构体,比如哪个GPIO,哪个引脚,哪个时钟,这里只包含了输入与输出的配置,中断没有添加。
void at32_gpio_init(gpio_struct *gpio)
{
gpio_init_type gpio_init_struct; //gpio 结构体
/* enable the led clock */
crm_periph_clock_enable(gpio->gpio_crm_clk, TRUE); //开启gpiod的时钟
/* set default parameter */
gpio_default_para_init(&gpio_init_struct); //设置gpio结构体默认值
/* 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->gpio_mode; //输出模式
gpio_init_struct.gpio_pins = gpio->pinx; //IO 管脚
gpio_init_struct.gpio_pull = GPIO_PULL_UP; //上拉
gpio_init(gpio->gpiox, &gpio_init_struct);
gpio_bits_write(gpio->gpiox,gpio->pinx,gpio->init_val);
}
uint8_t gpio_write(gpio_struct *gpio,uint8_t val)
{
gpio_bits_write(gpio->gpiox,gpio->pinx,val);
return gpio->state = gpio_output_data_bit_read(gpio->gpiox,gpio->pinx);
}
uint8_t gpio_read(gpio_struct *gpio)
{
gpio_input_data_bit_read(gpio->gpiox,gpio->pinx);
delay_ms(10);
return gpio->state = gpio_input_data_bit_read(gpio->gpiox,gpio->pinx);
}
如上是配置及输入输出函数想必大家都能够看懂。
下面添加应用代码。
struct my_gpio_manage
{
uint8_t num; /* 已注册的数目 */
gpio_struct *gpio_list[10]; /* 储存GPIO指针的数组 */
};
新建一个结构体来管理io口。
static struct my_gpio_manage led_manage = {0};
static struct my_gpio_manage key_manage = {0};
static gpio_struct led0 = {0};
static gpio_struct key0 = {0};
void led_int(void)
{
led0.gpiox = GPIOE;
led0.gpio_crm_clk = CRM_GPIOE_PERIPH_CLOCK;
led0.pinx = GPIO_PINS_15;
led0.gpio_mode = GPIO_MODE_OUTPUT;
led_manage.gpio_list[led_manage.num] = &led0;
printf("led_manage num = %d\n",led_manage.num + 1);
key0.gpiox = GPIOB;
key0.gpio_crm_clk = CRM_GPIOB_PERIPH_CLOCK;
key0.pinx = GPIO_PINS_9;
key0.gpio_mode = GPIO_MODE_INPUT;
key_manage.gpio_list[key_manage.num] = &key0;
printf("key_manage num = %d\n",key_manage.num + 1);
}
配置IO口。
int gpio_register(void)
{
for(uint8_t i = 0;i <= led_manage.num;i++)
at32_gpio_init(led_manage.gpio_list[i]);
for(uint8_t i = 0;i <= key_manage.num;i++)
at32_gpio_init(key_manage.gpio_list[i]);
return 0;
}
void led0_blink(void)
{
gpio_write(led_manage.gpio_list[0],0);
delay_ms(500);
gpio_write(led_manage.gpio_list[0],1);
delay_ms(500);
}
void key0_read(void)
{
static uint8_t state;
state = gpio_read(key_manage.gpio_list[0]);
printf("key0 state = %d\n",state);
}
注册IO口及功能实现。
下方是main函数相关代码。
int main(void)
{
system_clock_config();
at32_board_init();
uart_print_init(115200);
printf("board init ok!\n");
led_int();
gpio_register();
while(1)
{
led0_blink();
key0_read();
}
return 0;
}