打印
[AT32L021]

【AT-START-L021测评】GPIO学习以及移植开源按键驱动

[复制链接]
38|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lulugl|  楼主 | 2024-11-26 14:46 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
【前言】
按照试用计划,这篇将进行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)


1292367455e6439d9a.png (238.8 KB )

1292367455e6439d9a.png

33404674560bf83b63.png (359.85 KB )

33404674560bf83b63.png

24523674560e1df965.png (367 KB )

24523674560e1df965.png

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

150

主题

722

帖子

9

粉丝