【前言】
按照试用计划,这篇将进行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)
|