【前言】
按照试用计划,这篇将进行GPIO的输入与输出的分享。GPIO作为MCU的第一外设,可以说MCU一切与外界的交互都是通过GPIO来实现的,因此掌握他是最最基本功。本篇先从GPIO的概述、寄存器配置、at32l021_gpio.c的BSP学习,最后移植开源的按键,来实现对LED灯的不同方式的控制。
【GPIO简介】
在官方的《AT32L021系列 技术手册》中第6章——通用和复用功能I/O,是本篇的重要学习内容。
AT32L021 支持多达 39 个双向 I/O 引脚,这些引脚分为 4 组,分别为 PA0-PA15、PB0-PB15、PC13-PC15、PF0-PF1 与 PF6-PF7,每个引脚都可以实现与外部的通讯、控制以及数据采集的功能。
每个引脚都支持通用功能输入输出(GPIO)或复用功能输入输出(IOMUX)。
每个引脚都可以软件配置成浮空输入、上拉/下拉输入、模拟输入/输出、通用推挽/开漏输出、复用推挽/开漏输出。
每个引脚都有独立的弱上拉/下拉功能。
每个引脚都可以软件配置输出驱动能力。
每个引脚都可以配置为外部中断输入。
每个引脚都支持配置锁定功能。
下图是AT32L021的基本结构图:
从图中,看到GPIO是挂载在AHB高速时钟总线上,最高支持80MHz的速度。相对于STM32等,他们结构比较简洁,比如下图为STM32H7的GPIO功能框图:
GPIO复位状态,除了SWD相关引脚之外,都被配置为模拟模式,当然他还有特有的功能,就是GPIO端口保护,为了防止误操作导致 GPIO 功能混乱,提供每个对应引脚的的锁定机制。一旦锁定,在下次复位或者上电之前都不能进行对应引脚的 GPIO 配置。
【输入配置】
通过IOMC、PUPD两个寄存器的的配置,当IOMC为0,时可以配置为可配置引脚为通用浮空输入、通用上拉输入或通用下拉输入。当IOMC为11时端口配置为模拟输出,PUPD不使用。
【通用输出配置】
在通用输出配置时,多出了OM、HDRV、ODRV两个标志,其配置如下图所示:
【GPIO寄存器】
对于AT32L021的通用输入输出,模拟输入输出,系统提供了11个寄存器,在《AT32L021系列 技术手册》的6.3章有详细介绍。
我们可以通过表6-6来查找:
具体的相关寄存器位的功能表示,我们可以通过查找来得到。
【at32l021_gpio.h函数介绍】
在《AT32L021固件库BSP&Pack应用指南》的第5.9节中有详细的介绍。
当然我们可以通过AT32 Work Bench进行图形化的配置
【按键的配置实例】
开发板,给我们提供了一个用户使用的按键,们打开开发板原理图,找到User key部分,按键接到了PA0中,并通过下拉电阻接到了地。
配置按键按照如下步骤开始
1、打开按键所在GPIO的时钟
2、初始化GPIO黙认参数
3、给gpio结构进行赋值
4、初始化GPIO
其代码如下:
- <blockquote>/******************* define button *******************/
获取按键当前值的函数如下:
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] returns the selected button state
- * @param none
- * @retval the button gpio pin value
- */
- uint8_t at32_button_state(void)
- {
- return gpio_input_data_bit_read(USER_BUTTON_PORT, USER_BUTTON_PIN);
- }
到此按键配置已经完成了。
【移植开源按键驱动】
复制开源按键代码包到工程中,添加进keil工程
修改按键获取函数:
- uint8_t key0_read_pin(void)
- {
- return at32_button_state();
- }
在main.c中添加按键初始化,以及注册的代码,其总的代码如下:
- /**
- **************************************************************************
- * [url=home.php?mod=space&uid=288409]@file[/url] main.c
- * @brief main program
- **************************************************************************
- * Copyright notice & Disclaimer
- *
- * The software Board Support Package (BSP) that is made available to
- * download from Artery official website is the copyrighted work of Artery.
- * Artery authorizes customers to use, copy, and distribute the BSP
- * software and its related documentation for the purpose of design and
- * development in conjunction with Artery microcontrollers. Use of the
- * software is governed by this copyright notice and the following disclaimer.
- *
- * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
- * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
- * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
- * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
- * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
- *
- **************************************************************************
- */
- #include "at32l021_board.h"
- #include "at32l021_clock.h"
- #include "key_manage.h"
- /** @addtogroup AT32L021_periph_template
- * @{
- */
- /** @addtogroup 021_LED_toggle LED_toggle
- * @{
- */
- #define DELAY 100
- #define FAST 1
- #define SLOW 4
- uint8_t g_speed = FAST;
- static struct key_handle _key0;
- static void key0_event_callback(key_handle_t key)
- {
- switch(key->event)
- {
- case Press_Down:
- printf("key0 press down\r\n");
- break;
- case Press_Up:
- printf("key0 press up\r\n");
- break;
- case Singe_Click:
- g_speed = SLOW;
- printf("key0 single click\r\n");
- break;
- case Double_Click:
- g_speed = FAST;
- printf("key0 double click\r\n");
- break;
- case Short_Press_Repeat:
- printf("key0 short press repeat\r\n");
- break;
- case Long_Press_Start:
- printf("key0 long press start\r\n");
- break;
- case Long_Press_Hold:
- // key_handle_detach(&_key0);
- printf("key0 long press hold\r\n");
- break;
- default:
- break;
- }
- }
- void key_test_sample(void)
- {
- key_init(&_key0, key0_read_pin, NO_BUTTON);
- key_event_callback_register(&_key0, Press_Down, key0_event_callback);
- key_event_callback_register(&_key0, Press_Up, key0_event_callback);
- key_event_callback_register(&_key0, Singe_Click, key0_event_callback);
- key_event_callback_register(&_key0, Double_Click, key0_event_callback);
- key_event_callback_register(&_key0, Short_Press_Repeat, key0_event_callback);
- key_event_callback_register(&_key0, Long_Press_Start, key0_event_callback);
- key_event_callback_register(&_key0, Long_Press_Hold, key0_event_callback);
- key_handle_register(&_key0);
- }
- /**
- * @brief main function.
- * @param none
- * @retval none
- */
- int main(void)
- {
- static int tick;
- system_clock_config();
- at32_board_init();
- uart_print_init(115200);
- printf("at32 mcu initialize ok.\r\n");
- key_test_sample();
- while(1)
- {
- key_tick();
- delay_ms(1);
- tick++;
- if(tick > g_speed * DELAY)
- {
- at32_led_toggle(LED2);
- tick = 0;
- }
- }
- }
- /**
- * @}
- */
- /**
- * @}
- */
【实验结果】
程序运行后,LED2快速闪烁,单击按键,LED慢速闪烁,双击后又进入快速闪,串口输出按键的各种状态。
【总结】
通过对AT32L021的系统学习,掌握了GPIO的输入与输出的配置,同时移植了开源的按键驱动,成功的实现了一个按键实现多功能的实验效果。
【注】按键驱动附在源代码中,本篇不做详细介绍。其介绍源码中的使用说明中,大家需要可以自行获取。
附程序代码:
mypro.zip
(50.08 KB, 下载次数: 0)
|