ST32学习笔记之按键控制LED(NVIC、EXTI)

本文介绍了一个STM32实验,通过配置NVIC和EXTI,使用外部中断检测PA1引脚电平变化来控制PA2上的LED亮灭。实验中,PA1的下降沿触发中断,当电平拉低时,LED熄灭;电平升高时,LED应亮起。实际操作中,由于引脚默认输出高电平,需通过接地或接电源来改变电平状态,从而触发中断。
摘要由CSDN通过智能技术生成

本次实验目的:掌握NVIC、EXTI的配置与使用,这里使用杜邦线来模拟按键。

总体思路:

利用EXTI外部中断结合NVIC配置检测PA1引脚的电平,如果PA1是高电平,led亮(PA2);如果PA1是低电平,led灭(PA2)。

1-EXTI_NVIC.c(这里的文件命名不要误会了)
#include "stm32f10x.h"
#include "EXTI_NVIC.h"
//#include "led.h"
/**********************************
作用:NVIC配置及EXTI配置
***********************************/
//不能命名为EXTI_Init否则命名重复冲突
void My_EXTI_Init(void)
{  
     //开启时钟,EXTI 和 NVIC已经默认开启时钟,不需要再开启
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIO时钟
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //打开AFIO时钟
    
     GPIO_InitTypeDef GPIO_InitStruct;     //声明GPIO结构体
     NVIC_InitTypeDef NVIC_InitStructure;//声明NVIC结构体
     EXTI_InitTypeDef EXTI_InitStructure;//声明EXTI结构体
       
     //选择GPIO中断、优先级分组
     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);//配置AFIO,选择GPIO连接到EXTI
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置优先级分组
    
     //GPIO成员配置,速度不用设置???
     GPIO_InitStruct.GPIO_Pin =GPIO_Pin_1;//引脚设置
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入,不工作时电平由外部电路决定
     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
     GPIO_Init(GPIOA,&GPIO_InitStruct);    
     //GPIO_ResetBits(GPIOA,GPIO_Pin_1);//A1电平
    
     //NVIC NVIC成员配置
     NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn;//中断源(EXTI中断通道)
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
     NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级
     NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//中断使能
     NVIC_Init(&NVIC_InitStructure);//初始化NVIC寄存器
  
     //EXTI1配置
     EXTI_InitStructure.EXTI_Line=EXTI_Line1;//选择中断线
     EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;//设置EXTI模式为中断模式(另一个模式是事件模式)
     EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;//设置下降沿触发
     EXTI_InitStructure.EXTI_LineCmd=ENABLE;//EXT使能
     EXTI_Init(&EXTI_InitStructure);//初始化EXTI寄存器 
}
/*******************************************************************************
* 函 数 名         : EXTI_IRQHandler
* 函数功能             : 外部中断1函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void EXTI1_IRQHandler(void)
{
    //是否产生EXTI中断
    if(EXTI_GetITStatus(EXTI_Line1)==1)
    {
            //判断现在是低电平还是高电平,对应开关等
            if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==1)   //电平,灭
            {        
                 GPIO_SetBits(GPIOA,GPIO_Pin_2);              
            }
            else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)==0)//电平,亮
            {
                 GPIO_ResetBits(GPIOA,GPIO_Pin_2);
            }    
    }
    //清除中断标志位
    EXTI_ClearITPendingBit(EXTI_Line1);
}
2-EXTI_NVIC.h
#ifndef _EXTI_NVIC_H
#define _EXTI_NVIC_H

void My_EXTI_Init(void);
void EXTI1_IRQHandler(void);

#endif 


3-led.c
#include "stm32f10x.h"
#include "led.h"
/**
led初始化:使能时钟、定义结构体变量、设置工作模式
、选择端口、输出速度、初始化GPIO
**/
void LED_Init(void)
{
     //使能GPIOA时钟
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
      
     //GPIO结构体成员配置
     GPIO_InitTypeDef GPIO_InitStructure;//定义结构体变量
     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出模式
     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//输出端口A2
     GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出速度
     GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIO
      
     //端口默认电平
     GPIO_ResetBits(GPIOA,GPIO_Pin_2);//A1电平
}
4-led.h
#ifndef _LED_H
#define _LED_H
void LED_Init(void);
#endif 
5-main.c
#include "stm32f10x.h"
#include "led.h"
//#include "Delay.h"//引入延时
#include "NVIC.h"

int main(void)
{
      LED_Init();//初始化LED
      My_EXTI_Init();//初始化EXTI、NVIC
      while(1);    
}
注意事项

这里我设置了,PA1为高电平时,点亮LED;PA1为低电平时,熄灭LED。

我的小发现:(下降沿触发,即电平拉低时触发中断)

当我把PA1接3.3V时,led是不亮的,按理说PA1是高电平时,PA2点亮led,但实际现象却是相反的。原因是其引脚默认输出高电平(要接一条杜邦线在PA1),当我们接地时,将电平拉低,led灭;当我们接3.3v时,此时PA1电压比3.3伏低形成下降沿,led灭。

引脚悬空检测PA1为高电平时,使能PA2点亮led。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值