【学习目的】
在上一篇的文章中我认真的阅读了《GD32H737_757_759_User_Manual_Rev1.1_CN.pdf》,并且对配置EXTI的流程、寄存器做了详细的说明,这一篇进行代码编写并实现展示。
1、为方便后期管理,我先新建了一个头文件,类似官方的gd32h7xx.h,取名为lugl_gd32h7xx.h,定义的寄存器的地址,方便用宏来调用。
容内如下:
#ifndef __LUGL_GD32H7XX_H__
#define __LUGL_GD32H7XX_H__
//key1 -- PA0
//key2 -- PC13
//key3 -- PF8
//定义时钟地址
// RCU 基地址:0x5802 4400
#define LU_RCU_AHB4EN (*(volatile uint32_t *)(uint32_t)(0x58024400+0x3C))
//定义GPIOA_CTL的地址:GPIOA基地址:0x5802 0000
#define LU_GPIOA_CTL (*(volatile uint32_t *)(uint32_t)0x58020000)
#define LU_GPIOA_OMODE (*(volatile uint32_t *)(uint32_t)0x58020004)
#define LU_GPIOA_OSPD (*(volatile uint32_t *)(uint32_t)0x58020008)
#define LU_GPIOA_OCTL (*(volatile uint32_t *)(uint32_t)0x58020014)
#define LU_GPIOA_PUD (*(volatile uint32_t *)(uint32_t)0x5802000C)
#define LU_GPIOA_TG (*(volatile uint32_t *)(uint32_t)0x5802002C)
//定义GPIOA_CTL的地址:GPIOC基地址:0x5802 0080
#define LU_GPIOC_CTL (*(volatile uint32_t *)(uint32_t)0x58020800)
#define LU_GPIOC_OMODE (*(volatile uint32_t *)(uint32_t)0x58020804)
#define LU_GPIOC_OSPD (*(volatile uint32_t *)(uint32_t)0x58020808)
#define LU_GPIOC_OCTL (*(volatile uint32_t *)(uint32_t)0x58020814)
#define LU_GPIOC_PUD (*(volatile uint32_t *)(uint32_t)0x5802080C)
//GPIOF基地址:0x5802 1400
#define LU_GPIOF_CTL (*(volatile uint32_t *)(uint32_t)0x58021400)
#define LU_GPIOF_OMODE (*(volatile uint32_t *)(uint32_t)(0x58021404))
#define LU_GPIOF_OSPD (*(volatile uint32_t *)(uint32_t)(0x58021408))
#define LU_GPIOF_OCTL (*(volatile uint32_t *)(uint32_t)(0x58021414))
#define LU_GPIOF_ISTAT (*(volatile uint32_t *)(uint32_t)(0x58021410))
#define LU_GPIOF_PUD (*(volatile uint32_t *)(uint32_t)0x5802140C)
#define LU_SYSCFG_EXTISS3 (*(volatile uint32_t *)(uint32_t)0x58000414)
// EXTI 基地址:0x5800 0000
#define LU_EXTI_INTEN0 (*(volatile uint32_t *)(uint32_t)0x58000000) //中断使能寄存器 0
#define LU_EXTI_FTEN0 (*(volatile uint32_t *)(uint32_t)0x5800000C) //下降沿触发使能寄存器 0(EXTI_FTEN0)
#define LU_EXTI_PD0 (*(volatile uint32_t *)(uint32_t)0x58000014) //挂起寄存器 0(EXTI_PD0)
//中断使能基地址:RCU 基地址:0x5802 4400 APB4 使能寄存器(RCU_APB4EN)地址偏移:0x4C
#define LU_RCU_APB4EN (*(volatile uint32_t *)(uint32_t)0x5802444C)
#endif
复制代码为了方便LED的管理,我新建了LED的配置与宏定义函数,其中led.h为配置板载的两个LED的驱动,内容如下:
#ifndef __LED_H__
#define __LED_H__
#include "lugl_gd32h7xx.h"
//定义LED1_ON\OFF
#define LED1_ON LU_GPIOF_OCTL |= (uint32_t)0x01<<10;
#define LED1_OFF LU_GPIOF_OCTL &= ~((uint32_t)0x01<<10);
#define LED2_ON LU_GPIOA_OCTL |= (uint32_t)0x01<<6;
#define LED2_OFF LU_GPIOA_OCTL &= ~((uint32_t)0x01<<6);
//LED2翻转
#define TG_LED2 LU_GPIOA_TG |= ((uint32_t)0x01<<6)
void led_io_init(void);
#endif
复制代码#include "led.h"
#include "gd32h7xx.h"
void led_io_init(void)
{
//使能时钟
LU_RCU_AHB4EN |= (uint32_t)0x01<<5; //使能GPIOF时钟 Led1 PF10
LU_RCU_AHB4EN |= (uint32_t)0x01<<0; //使能GPIOA时钟 Led2 PA6
//配置LED1 PF10
//先清除位,因为复位后该位为0b11
LU_GPIOF_CTL &= ~((uint32_t)0x03 <<(10*2));
LU_GPIOF_CTL |= ((uint32_t)0x01<<10*2); //置21:20为0x01输出模式
LU_GPIOF_OMODE &= ~(0x01<<10); //输出推挽模式
LU_GPIOF_OSPD &= ~((uint32_t)0x03 <<(10*2));
LU_GPIOF_OSPD &= ((uint32_t)0x01 <<(10*2)); //01:输出最大速度60M
//初始化输出低电平:
LU_GPIOA_OCTL &= ~((uint32_t)0x01<<10);
//先清除位,因为复位后该位为0b11
LU_GPIOA_CTL &= ~((uint32_t)0x03 <<(6*2));
LU_GPIOA_CTL |= ((uint32_t)0x01<<6*2); //置21:20为0x01输出模式
LU_GPIOA_OMODE &= ~(0x01<<10); //输出推挽模式
LU_GPIOA_OSPD &= ~((uint32_t)0x03 <<(6*2));
LU_GPIOA_OSPD &= ((uint32_t)0x01 <<(6*2)); //01:输出最大速度60M
//初始化输出低电平:
LU_GPIOA_OCTL &= ~((uint32_t)0x01<<6);
}
复制代码#ifndef __KEY_H__
#define __KEY_H__
#include "lugl_gd32h7xx.h"
void key_config(void);
#endif
复制代码#include "lugl_gd32h7xx.h"
#include "gd32h7xx.h"
#include "led.h"
#include "key.h"
void key_config(void)
{
//使能时钟
LU_RCU_AHB4EN |= (uint32_t)0x01<<2; //使能GPIOF时钟 PC13
LU_RCU_APB4EN |= (uint32_t)0x01<<0; //1:开启 SYSCFG 时钟
/* 开启EXTI10-15线中断 */
nvic_irq_enable(EXTI10_15_IRQn, 2U, 0U);
//配置KEY2 PC13
//先清除位,因为复位后该位为
LU_GPIOC_CTL &= ~((uint32_t)0x03 <<(13*2)); //清除位为0b00,即为输入模式
LU_GPIOC_PUD &= ~((uint32_t)0x01<<(13*2)); //清除位为0b00,即为悬空
LU_SYSCFG_EXTISS3 &= ~((uint32_t)0xF<<4); //清除 EXTI 13 源选择
LU_SYSCFG_EXTISS3 |= ((uint32_t)0x02<<4); //0010:PC13 引脚
LU_EXTI_INTEN0 |= ((uint32_t)0x01<<13); //使能EXTI13 即INTEN13;
LU_EXTI_FTEN0 |= ((uint32_t)0x01<<13); //使能13线的下降沿触发
LU_EXTI_PD0 |= ((uint32_t)0x01<<13); //清除事件;
}
void EXTI10_15_IRQHandler(void)
{
//获取exti13 的事件标志位
if(RESET != ((LU_EXTI_PD0 >>13) &0x01))
{
//翻转LED2
TG_LED2;
LU_EXTI_PD0 |= ((uint32_t)0x01<<13); //清除事件;
}
}
复制代码按键处理,我这里没有加入消抖处理,因为开板按键电路加了电容,进行了硬件消抖处理,所以按建非常好用。
【总结】
使用寄存器编程,一来学习GD32H7xx的基础知识,二来代码量非常少,三来运行速度相比库函数要快。
全部回复 0
暂无评论,快来抢沙发吧