本次实验目的:掌握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。
本文介绍了一个STM32实验,通过配置NVIC和EXTI,使用外部中断检测PA1引脚电平变化来控制PA2上的LED亮灭。实验中,PA1的下降沿触发中断,当电平拉低时,LED熄灭;电平升高时,LED应亮起。实际操作中,由于引脚默认输出高电平,需通过接地或接电源来改变电平状态,从而触发中断。
393

被折叠的 条评论
为什么被折叠?



