stm32——hal库学习笔记(外部中断)

news2024/12/30 0:52:09

一、什么是中断?(了解)
打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断
在这里插入图片描述
中断的作用和意义
在这里插入图片描述
中断的意义:高效处理紧急程序,不会一直占用CPU资源

STM32 GPIO外部中断简图
在这里插入图片描述

二、NVIC(熟悉)
2.1,NVIC基本概念
2.2,NVIC相关寄存器介绍
2.3,NVIC工作原理
2.4,STM32中断优先级基本概念
2.5,STM32中断优先级分组
2.6,STM32 NVIC的使用

2.1、NVIC基本概念
Nested vectored interrupt controller,嵌套向量中断控制器,属于内核(M3/4/7)
NVIC支持:256个中断(16内核 + 240外部),支持:256个优先级,允许裁剪!
在这里插入图片描述
什么是中断向量表?
定义一块固定的内存,以4字节对齐,存放各个中断服务函数程序的首地址
中断向量表定义在启动文件,当发生中断,CPU会自动执行对应的中断服务函数
在这里插入图片描述
2.2、NVIC相关寄存器介绍
在这里插入图片描述
NVIC还有:中断挂起,解挂,激活标志等非常用功能,不做介绍!

2.3、NVIC工作原理
在这里插入图片描述

2.4、STM32中断优先级基本概念
1,抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断
2,响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断
3,抢占和响应都相同的情况下,自然优先级越高的,先执行
4,自然优先级:中断向量表的优先级
5,数值越小,表示优先级越高

2.5、 STM32中断优先级分组
在这里插入图片描述

STM32中断优先级举例(假设分组是2)
在这里插入图片描述
EXTI1和RTC可以打断:EXTI0和Systick的中断,获得优先执行!

2.6、 STM32 NVIC的使用
在这里插入图片描述

三、EXTI(熟悉)
3.1,EXTI基本概念
3.2,EXTI主要特性
3.3,EXTI工作原理(F1/F4/F7)

3.1、EXTI基本概念
External(Extended) interrupt/event Controller,外部(扩展)中断事件控制器
包含20个产生事件/中断请求的边沿检测器,即总共:20条EXTI线(F1)
中断和事件的理解:
中断:要进入NVIC,有相应的中断服务函数,需要CPU处理
事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC

EXTI支持的外部中断/事件请求
在这里插入图片描述

3.2、EXTI主要特性
F1/F4/F7系列
每条EXTI线都可以单独配置:选择类型(中断或者事件)、触发方式(上升沿,下降沿或者双边沿触发)、支持软件触发、开启/屏蔽、有挂起状态位

3.3、EXTI工作原理(F1/F4/F7系列)
①,边沿检测
②,软件触发
③,中断屏蔽/清除
④,事件屏蔽
在这里插入图片描述

四、EXTI和IO映射关系(熟悉)
4.1,AFIO简介(F1)
Alternate Function IO,即复用功能IO,主要用于重映射和外部中断映射配置
在这里插入图片描述

4.2,SYSCFG简介(F4/F7/H7)
System configuration controller,即系统配置控制器,用于外部中断映射配置等
在这里插入图片描述
4.3,EXTI 与 IO对应关系
在这里插入图片描述
五、如何使用中断(掌握)
在这里插入图片描述
在这里插入图片描述
STM32 EXTI的HAL库设置步骤(外部中断)
在这里插入图片描述

__HAL_RCC_GPIOx_CLK_ENABLE

在这里插入图片描述

HAL_GPIO_Init

在这里插入图片描述

HAL_NVIC_SetPriorityGrouping

在这里插入图片描述

HAL_NVIC_SetPriority

在这里插入图片描述

 HAL_NVIC_EnableIRQ

在这里插入图片描述

EXTIx_IRQHandler

STM32仅有:EXTI0~4、EXTI9_5、EXTI15_10,7个外部中断服务函数

六、HAL库中断回调处理机制介绍(掌握)

在这里插入图片描述

七、demo程序——通过外部中断控制一个灯亮灭(掌握)

exit.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/KEY/key.h"
#include "./BSP/EXTI/exti.h"
/**
 * @brief       外部中断初始化程序
 * @param       无
 * @retval      无
 */
void extix_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;

    KEY0_GPIO_CLK_ENABLE();                                  /* KEY0时钟使能 */
    KEY1_GPIO_CLK_ENABLE();                                  /* KEY1时钟使能 */
    KEY2_GPIO_CLK_ENABLE();                                  /* KEY2时钟使能 */
    WKUP_GPIO_CLK_ENABLE();                                  /* WKUP时钟使能 */

    gpio_init_struct.Pin = KEY0_INT_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下降沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY0_INT_GPIO_PORT, &gpio_init_struct);    /* KEY0配置为下降沿触发中断 */

    gpio_init_struct.Pin = KEY1_INT_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下降沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY1_INT_GPIO_PORT, &gpio_init_struct);    /* KEY1配置为下降沿触发中断 */
    
    gpio_init_struct.Pin = KEY2_INT_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;            /* 下降沿触发 */
    gpio_init_struct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(KEY2_INT_GPIO_PORT, &gpio_init_struct);    /* KEY2配置为下降沿触发中断 */
    
    gpio_init_struct.Pin = WKUP_INT_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_IT_RISING;             /* 上升沿触发 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(WKUP_GPIO_PORT, &gpio_init_struct);        /* WKUP配置为上升沿触发中断 */

    HAL_NVIC_SetPriority(KEY0_INT_IRQn, 0, 2);               /* 抢占0,子优先级2 */
    HAL_NVIC_EnableIRQ(KEY0_INT_IRQn);                       /* 使能中断线1 */

    HAL_NVIC_SetPriority(KEY1_INT_IRQn, 1, 2);               /* 抢占1,子优先级2 */
    HAL_NVIC_EnableIRQ(KEY1_INT_IRQn);                       /* 使能中断线15 */
    
    HAL_NVIC_SetPriority(KEY2_INT_IRQn, 2, 2);               /* 抢占2,子优先级2 */
    HAL_NVIC_EnableIRQ(KEY2_INT_IRQn);                       /* 使能中断线15 */

    HAL_NVIC_SetPriority(WKUP_INT_IRQn, 3, 2);               /* 抢占3,子优先级2 */
    HAL_NVIC_EnableIRQ(WKUP_INT_IRQn);                       /* 使能中断线0 */
}


/**
 * @brief       KEY0 外部中断服务程序
 * @param       无
 * @retval      无
 */
void KEY0_INT_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(KEY0_INT_GPIO_PIN);         /* 调用中断处理公用函数 清除KEY0所在中断线 的中断标志位 */
    __HAL_GPIO_EXTI_CLEAR_IT(KEY0_INT_GPIO_PIN);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

/**
 * @brief       KEY1 外部中断服务程序
 * @param       无
 * @retval      无
 */
void KEY1_INT_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(KEY1_INT_GPIO_PIN);         /* 调用中断处理公用函数 清除KEY1所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
    __HAL_GPIO_EXTI_CLEAR_IT(KEY1_INT_GPIO_PIN);         /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

/**
 * @brief       KEY2 外部中断服务程序
 * @param       无
 * @retval      无
 */
void KEY2_INT_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(KEY2_INT_GPIO_PIN);        /* 调用中断处理公用函数 清除KEY2所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
    __HAL_GPIO_EXTI_CLEAR_IT(KEY2_INT_GPIO_PIN);        /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}

/**
 * @brief       WK_UP 外部中断服务程序
 * @param       无
 * @retval      无
 */
void WKUP_INT_IRQHandler(void)
{ 
    HAL_GPIO_EXTI_IRQHandler(WKUP_INT_GPIO_PIN);        /* 调用中断处理公用函数 清除KEY_UP所在中断线 的中断标志位,中断下半部在HAL_GPIO_EXTI_Callback执行 */
    __HAL_GPIO_EXTI_CLEAR_IT(WKUP_INT_GPIO_PIN);        /* HAL库默认先清中断再处理回调,退出时再清一次中断,避免按键抖动误触发 */
}
/**
 * @brief       中断服务程序中需要做的事情
                在HAL库中所有的外部中断服务函数都会调用此函数
 * @param       GPIO_Pin:中断引脚号
 * @retval      无
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(20);      /* 消抖 */
    switch(GPIO_Pin)
    {
        case KEY0_INT_GPIO_PIN:
            if (KEY0 == 0)
            {
                LED0_TOGGLE();  /* LED0 状态取反 */ 
                LED1_TOGGLE();  /* LED1 状态取反 */ 
            }
            break;
        case KEY1_INT_GPIO_PIN:
            if (KEY1 == 0)
            {
                LED0_TOGGLE();  /* LED0 状态取反 */ 
            }
            break;
        case KEY2_INT_GPIO_PIN:
            if (KEY2 == 0)
            {
                LED1_TOGGLE();  /* LED1 状态取反 */ 
            }
            break;
        case WKUP_INT_GPIO_PIN:
            if (WK_UP == 1)
            {
                BEEP_TOGGLE();  /* 蜂鸣器状态取反 */ 
            }
            break;
    }
}

exti.h

#ifndef __EXTI_H
#define __EXTI_H

#include "./SYSTEM/sys/sys.h"

/******************************************************************************************/
/* 引脚 和 中断编号 & 中断服务函数 定义 */ 
#define KEY0_INT_GPIO_PORT              GPIOA
#define KEY0_INT_GPIO_PIN               GPIO_PIN_4
#define KEY0_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */
#define KEY0_INT_IRQn                   EXTI4_IRQn
#define KEY0_INT_IRQHandler             EXTI4_IRQHandler

#define KEY1_INT_GPIO_PORT              GPIOA
#define KEY1_INT_GPIO_PIN               GPIO_PIN_3
#define KEY1_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */
#define KEY1_INT_IRQn                   EXTI3_IRQn
#define KEY1_INT_IRQHandler             EXTI3_IRQHandler

#define KEY2_INT_GPIO_PORT              GPIOA
#define KEY2_INT_GPIO_PIN               GPIO_PIN_2
#define KEY2_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */
#define KEY2_INT_IRQn                   EXTI2_IRQn
#define KEY2_INT_IRQHandler             EXTI2_IRQHandler

#define WKUP_INT_GPIO_PORT              GPIOA
#define WKUP_INT_GPIO_PIN               GPIO_PIN_0
#define WKUP_INT_GPIO_CLK_ENABLE()      do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */
#define WKUP_INT_IRQn                   EXTI0_IRQn
#define WKUP_INT_IRQHandler             EXTI0_IRQHandler

/******************************************************************************************/
void extix_init(void);  /* 外部中断初始化 */

#endif


led.c

#include "./BSP/LED/led.h"


/**
 * @brief       初始化LED相关IO口, 并使能时钟
 * @param       无
 * @retval      无
 */
void led_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    LED0_GPIO_CLK_ENABLE();                                 /* LED0时钟使能 */
    LED1_GPIO_CLK_ENABLE();                                 /* LED1时钟使能 */

    gpio_init_struct.Pin = LED0_GPIO_PIN;                   /* LED0引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */
    HAL_GPIO_Init(LED0_GPIO_PORT, &gpio_init_struct);       /* 初始化LED0引脚 */

    gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */
    HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */
    

    LED0(1);                                                /* 关闭 LED0 */
    LED1(1);                                                /* 关闭 LED1 */
}

led.h

#ifndef _LED_H
#define _LED_H
#include "./SYSTEM/sys/sys.h"


/******************************************************************************************/
/* 引脚 定义 */

#define LED0_GPIO_PORT                  GPIOB
#define LED0_GPIO_PIN                   GPIO_PIN_5
#define LED0_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)             /* PB口时钟使能 */

#define LED1_GPIO_PORT                  GPIOB
#define LED1_GPIO_PIN                   GPIO_PIN_6
#define LED1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)             /* PE口时钟使能 */

/******************************************************************************************/
/* LED端口定义 */
#define LED0(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED0_GPIO_PORT, LED0_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)      /* LED0翻转 */

#define LED1(x)   do{ x ? \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
                  }while(0)      /* LED1翻转 */

/* LED取反定义 */
#define LED0_TOGGLE()   do{ HAL_GPIO_TogglePin(LED0_GPIO_PORT, LED0_GPIO_PIN); }while(0)        /* 翻转LED0 */
#define LED1_TOGGLE()   do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0)        /* 翻转LED1 */

/******************************************************************************************/
/* 外部接口函数*/
void led_init(void);                                                                            /* 初始化 */

#endif

beep.c

#include "./BSP/BEEP/beep.h"


/**
 * @brief       初始化BEEP相关IO口, 并使能时钟
 * @param       无
 * @retval      无
 */
void beep_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    BEEP_GPIO_CLK_ENABLE();                             /* BEEP时钟使能 */

    gpio_init_struct.Pin = BEEP_GPIO_PIN;               /* 蜂鸣器引脚 */
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;        /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;      /* 高速 */
    HAL_GPIO_Init(BEEP_GPIO_PORT, &gpio_init_struct);   /* 初始化蜂鸣器引脚 */

    BEEP(0);                                            /* 关闭蜂鸣器 */
}



beep.h

#ifndef __BEEP_H
#define __BEEP_H

#include "./SYSTEM/sys/sys.h"

/******************************************************************************************/
/* 引脚 定义 */

#define BEEP_GPIO_PORT                  GPIOB
#define BEEP_GPIO_PIN                   GPIO_PIN_8
#define BEEP_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

/******************************************************************************************/

/* 蜂鸣器控制 */
#define BEEP(x)         do{ x ? \
                            HAL_GPIO_WritePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN, GPIO_PIN_SET) : \
                            HAL_GPIO_WritePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN, GPIO_PIN_RESET); \
                        }while(0)

/* BEEP状态翻转 */
#define BEEP_TOGGLE()   do{ HAL_GPIO_TogglePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN); }while(0)     /* BEEP = !BEEP */

void beep_init(void);   /* 初始化蜂鸣器 */

#endif



key.c

#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"


/**
 * @brief       按键初始化函数
 * @param       无
 * @retval      无
 */
void key_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    KEY0_GPIO_CLK_ENABLE();                                     /* KEY0时钟使能 */
    KEY1_GPIO_CLK_ENABLE();                                     /* KEY1时钟使能 */
    KEY2_GPIO_CLK_ENABLE();                                     /* KEY2时钟使能 */
    WKUP_GPIO_CLK_ENABLE();                                     /* WKUP时钟使能 */

    gpio_init_struct.Pin = KEY0_GPIO_PIN;                       /* KEY0引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY0_GPIO_PORT, &gpio_init_struct);           /* KEY0引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = KEY1_GPIO_PIN;                       /* KEY1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY1_GPIO_PORT, &gpio_init_struct);           /* KEY1引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = KEY2_GPIO_PIN;                       /* KEY2引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY2_GPIO_PORT, &gpio_init_struct);           /* KEY2引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = WKUP_GPIO_PIN;                       /* WKUP引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLDOWN;                      /* 下拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(WKUP_GPIO_PORT, &gpio_init_struct);           /* WKUP引脚模式设置,下拉输入 */

}

/**
 * @brief       按键扫描函数
 * @note        该函数有响应优先级(同时按下多个按键): WK_UP > KEY2 > KEY1 > KEY0!!
 * @param       mode:0 / 1, 具体含义如下:
 *   @arg       0,  不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,
 *                  必须松开以后, 再次按下才会返回其他键值)
 *   @arg       1,  支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)
 * @retval      键值, 定义如下:
 *              KEY0_PRES, 1, KEY0按下
 *              KEY1_PRES, 2, KEY1按下
 *              KEY2_PRES, 3, KEY2按下
 *              WKUP_PRES, 4, WKUP按下
 */
uint8_t key_scan(uint8_t mode)
{
    static uint8_t key_up = 1;  /* 按键按松开标志 */
    uint8_t keyval = 0;

    if (mode) key_up = 1;       /* 支持连按 */

    if (key_up && (KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1))  /* 按键松开标志为1, 且有任意一个按键按下了 */
    {
        delay_ms(10);           /* 去抖动 */
        key_up = 0;

        if (KEY0 == 0)  keyval = KEY0_PRES;

        if (KEY1 == 0)  keyval = KEY1_PRES;

        if (KEY2 == 0)  keyval = KEY2_PRES;

        if (WK_UP == 1) keyval = WKUP_PRES;
    }
    else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0) /* 没有任何按键按下, 标记按键松开 */
    {
        key_up = 1;
    }

    return keyval;              /* 返回键值 */
}

key.h

#ifndef __KEY_H
#define __KEY_H

#include "./SYSTEM/sys/sys.h"

/******************************************************************************************/
/* 引脚 定义 */

#define KEY0_GPIO_PORT                  GPIOA
#define KEY0_GPIO_PIN                   GPIO_PIN_4
#define KEY0_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

#define KEY1_GPIO_PORT                  GPIOA
#define KEY1_GPIO_PIN                   GPIO_PIN_3
#define KEY1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

#define KEY2_GPIO_PORT                  GPIOE
#define KEY2_GPIO_PIN                   GPIO_PIN_2
#define KEY2_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PE口时钟使能 */

#define WKUP_GPIO_PORT                  GPIOA
#define WKUP_GPIO_PIN                   GPIO_PIN_0
#define WKUP_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PA口时钟使能 */

/******************************************************************************************/

#define KEY0        HAL_GPIO_ReadPin(KEY0_GPIO_PORT, KEY0_GPIO_PIN)     /* 读取KEY0引脚 */
#define KEY1        HAL_GPIO_ReadPin(KEY1_GPIO_PORT, KEY1_GPIO_PIN)     /* 读取KEY1引脚 */
#define KEY2        HAL_GPIO_ReadPin(KEY2_GPIO_PORT, KEY2_GPIO_PIN)     /* 读取KEY2引脚 */
#define WK_UP       HAL_GPIO_ReadPin(WKUP_GPIO_PORT, WKUP_GPIO_PIN)     /* 读取WKUP引脚 */


#define KEY0_PRES    1              /* KEY0按下 */
#define KEY1_PRES    2              /* KEY1按下 */
#define KEY2_PRES    3              /* KEY2按下 */
#define WKUP_PRES    4              /* KEY_UP按下(即WK_UP) */

void key_init(void);                /* 按键初始化函数 */
uint8_t key_scan(uint8_t mode);     /* 按键扫描函数 */

#endif

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/BEEP/beep.h"
#include "./BSP/EXTI/exti.h"


int main(void)
{
    HAL_Init();                            /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);    /* 设置时钟, 72Mhz */
    delay_init(72);                        /* 延时初始化 */
   
    led_init();                            /* 初始化LED */
    beep_init();                           /* 初始化蜂鸣器 */
    extix_init();                          /* 初始化外部中断输入 */
    LED0(0);                               /* 先点亮红灯 */

    while (1)
    {
      
        delay_ms(1000);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1461575.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android14 InputManager-InputManagerService环境的构造

IMS分为Java层与Native层两个部分,其启动过程是从Java部分的初始化开始,进而完成Native部分的初始化。 □创建新的IMS对象。 □调用IMS对象的start()函数完成启动 同其他系统服务一样,IMS在SystemServer中的ServerT…

浅谈加密算法(对称加密、非对称加密、混合加密、数字签名、哈希函数)

1、对称加密 对称加密只有一个密钥,直接使用这一个密钥对信息进行加密或解密。这样子就使得对称加密解密十分高效,计算量也相较于非对称加密小很多,适合有大量数据的场合。 密钥只有一个且他一定不能泄漏。由此分发密钥,讲这个密钥…

聚合支付,聚合系统,聚合程序或将成为主流

支付市场的变化对用户、代理商和运营商产生了重大影响。 随着政策监管的日益严格,支付行业逐渐朝着标准化和合理化的方向发展,日益增强其安全性。在这个背景下,聚合平台已经成为未来支付行业发展的重要趋势。特别是在“一机一码”政策实施后&…

三防平板丨平板终端丨加固平板丨户外勘测应用

随着科技的不断发展,现代勘测业也在不断升级。相较于传统的勘测设备,三防平板在户外勘测中有着广泛的应用。那么,三防平板在户外勘测中究竟有哪些优势呢? 首先,三防平板具备极强的防水、防尘、防摔能力。在野外勘测中&…

MyBatis---初阶

一、MyBatis作用 是一种更简单的操作和读取数据库的工具。 二、MyBatis准备工作 1、引入依赖 2、配置Mybatis(数据库连接信息) 3、定义接口 Mapper注解是MyBatis中用来标识接口为Mapper接口的注解。在MyBatis中,Mapper接口是用来定义SQL映射的接口,通…

十分钟利用springboot写电商支持多种优惠券规则,使用策略模式替代大量的if-else

前言 在开发电商折扣模块的时候经常会碰到各种优惠规则,那么就会碰到很多条件判断,冗余各种if-else的代码使得维护困难,此时就可以用策略模式来解决,替代大量的冗余判断条件代码,精简代码结构。 策…

建筑行业的重要工具—— 智慧工地管理平台(java源码)

系统定义: 智慧工地管理平台系统是一种集成了先进的信息技术、物联网技术、移动互联网技术等多种技术的工地管理系统。它能够对工地的整个生命周期进行全面的管理,包括工地的规划、设计、施工、监控、验收等各个环节。通过信息化手段,提高了工…

拯救者Legion Y9000K 2021H(82K6)原厂oem预装Win11系统镜像

lenovo联想拯救者Y9000K(82K6)原装出厂Windows11系统安装包下载,恢复出厂开箱状态 链接:https://pan.baidu.com/s/1DGWU7gctJerff6LJrgHD5w?pwdrbs5 提取码:rbs5 原装出厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office…

C++从入门到精通 第十四章(STL容器)【下】

写在前面: 本系列专栏主要介绍C的相关知识,思路以下面的参考链接教程为主,大部分笔记也出自该教程,笔者的原创部分主要在示例代码的注释部分。除了参考下面的链接教程以外,笔者还参考了其它的一些C教材(比…

基础数据结构与相关C++ STL容器

文章目录 数组arrayvector 栈和队列dequestackqueue 堆heappriority_queue 链表listforward_list 树setmapmultisetmultimap 哈希表unordered_setunordered_mapunordered_multisetunordered_multimap 图 数组 array 不开口的连续线性空间,支持随机访问。 array是…

【C->Cpp】由C迈向Cpp(4)

目录 (一)内联函数 (二)关键字auto (三)范围for (四)nullptr 正文开始: (一)内联函数 宏定义: C的内联函数是在C语言宏的基础上提出…

怎样开发Apple Vision Pro应用?以应用开发者角度体验苹果的开发文档

▲ 搜索“大龙谈智能内容”关注公众号▲ 最近,苹果公司推出了革命性的产品Apple Vision Pro,全世界震惊。下边这个视频在社交网络上得到了大量转发: 在大家兴奋的围观之际,已经有人在规划能做些什么了。 有朋友问大龙有什么Vi…

妨碍做出正确决策的5种认知谬误

人类的大脑在极端情况下会呈现出不可理喻的一面,从而妨碍我们做出正确的决策。本文介绍了5种常见的认知谬误,识别并克服这些认知谬误,可以帮助我们更好的决策。原文: Want to Make Better Decisions? Avoid These 5 Cognitive Distortions 我…

Python中类创建和实例化过程

嗨喽,大家好呀~这里是爱看美女的茜茜呐 一、 type() 1、创建类的两种方式 方式一 class MyClass(object):def func(self,name):print(name)myc MyClass()print(MyClass, type(MyClass)) print(myc, type(myc))我们创建了一个名为MyClass的类,并实例化…

书生·浦语大模型实战营-第四课笔记

期待已久的微调课 一、Finetune 增量预训练和指令跟随是两种微调模式,即两种微调策略。 1)增量预训练 投喂新的领域知识即可,例如书籍、文章、代码 2)指令跟随 采用高质量对话和问答数据进行训练 二、LoRA与QLoRA 两…

35、IO进程线程/多线程实现文件读写20240221

一、使用多线程完成两个文件的拷贝&#xff0c;第一个线程拷贝前一半&#xff0c;第二个线程拷贝后一半&#xff0c;主线程回收两个线程的资源。 代码&#xff1a; #include<myhead.h> typedef struct //类型重定义结构体 {const char *src;const char *dest;int start…

vue3总结

1 setup 概述 setup是Vue3中一个新的配置项个函数, 包含数据、方法等&#xff0c;是组合api的“舞台”。 特点如下&#xff1a; setup函数返回的对象中的内容&#xff0c;可直接在模板中使用。setup中访问this是undefined。setup函数会在beforeCreate之前调用&#xff0c;它…

人工智能深度学习

目录 人工智能 深度学习 机器学习 神经网络 机器学习的范围 模式识别 数据挖掘 统计学习 计算机视觉 语音识别 自然语言处理 机器学习的方法 回归算法 神经网络 SVM&#xff08;支持向量机&#xff09; 聚类算法 降维算法 推荐算法 其他 机器学习的分类 机器…

Spring Cloud Gateway 中文文档

Spring Cloud Gateway 中文文档 官方文档 该项目提供了一个建立在Spring Ecosystem之上的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。 Spring Cloud Gateway旨在提供一种简单而有效的方式来对API进行路由&#xff0c;并为他们提…

奇异递归模板模式应用5-静态多态

动态多态&#xff1a;C动态多态是利用虚函数特性实现的&#xff0c;即基类指针(引用&#xff09;指向派生类指针(引用)。由于虚函数的实现是在运行期进行的&#xff0c;因而会产生运行期开销&#xff08;虚表指针偏移&#xff0c;与分支预测器和CPU指令流水线相关&#xff09;。…