按键输入控制LED灯、蜂鸣器外部中断方式-基于STM32F103ZET6_开发板

 使用外部中断的好处:

  1. 提高实时性:外部中断允许STM32单片机在特定事件发生时立即响应,而无需持续轮询。这使得系统能够更快速地响应外部事件,如按键按下、定时器溢出等,从而提高了系统的实时性和效率。
  2. 节省系统开销:外部中断具有相对低的响应时间和占用资源,这有助于减少系统的开销。在实时性要求相对较高的单片机应用中,外部中断作为一种硬件触发方式,可以有效地降低系统的功耗和复杂度。
  3. 优化程序运行效率:通过中断系统,STM32单片机可以在处理主程序的同时,处理中断请求。当中断发生时,CPU可以暂停当前的主程序,转而执行中断服务程序,待中断处理完成后,再回到原来的主程序继续执行。这种机制使得程序的运行更加高效,能够充分利用处理器的资源。
#include "stm32f10x.h"                  // Device header
#include "delay.h"

                                                                                                                   

uint8_t choice_0, choice_1, choice_2, choice_3 = 0;		//更改按键按下不同的行为
//uint8_t Circulate;		//跳出循环


void initialize_Init(void)					
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//GPIOB使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);//GPIOE使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIOA使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//AFIO使能时钟
	
	//蜂鸣器
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//设置I/O输出为推挽输出
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;		//设置端口	按位控制
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置输出速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_8);
		
	/*初始化蜂鸣器的电平为低电平(防止一调用蜂鸣器就响)*/
	GPIO_ResetBits(GPIOB, GPIO_Pin_8);
	
	//LED0、LED1
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//设置I/O输出为推挽输出
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;		//设置端口	
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置输出速度为50MHz
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//设置I/O输出为推挽输出
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;		//设置端口	
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//设置输出速度为50MHz
	GPIO_Init(GPIOE,&GPIO_InitStructure);
	GPIO_SetBits(GPIOE,GPIO_Pin_5);
	
	/*初始化LED灯的电平为高电平(防止一调用LED灯就亮)*/
	GPIO_SetBits(GPIOB, GPIO_Pin_5);
	GPIO_SetBits(GPIOE, GPIO_Pin_5);
	
	//按键
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	//设置成上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2;		//选取端口引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOE,&GPIO_InitStructure);
	
	//初始化 WK_UP-->GPIOA.0	  下拉输入
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉	  
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);		//配置外部中断线4
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);		//配置外部中断线3
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);		//配置外部中断线2
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);		//配置外部中断线0
	
	EXTI_InitTypeDef EXTI_InitStructure;
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;					//外部中断线0
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//外部中断触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;		//下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line4;					//外部中断线4
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//外部中断触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;		//下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line3;					//外部中断线3
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//外部中断触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;		//下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line2;					//外部中断线2
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;					//使能
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;			//外部中断触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;		//下降沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);		//配置优先级分组
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;		//选择外部中断的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;			//响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;		//选择外部中断的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;		//选择外部中断的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;			//响应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;		//选择外部中断的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;	//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;			//响应优先级
	NVIC_Init(&NVIC_InitStructure);
}



int main(void)
{
	initialize_Init();		//初始化函数
	while(1)
	{
		/*		使用外部中断可以更快响应不用以下方式
		if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)		//读取GPIOE端口4的电平
		{
			delay_ms(20);		//消抖
			while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0);		
			delay_ms(20);
			choice_0 ++;
			if(choice_0 == 1)
			{
				GPIO_ResetBits(GPIOB,GPIO_Pin_5);		//给GPIOB_Pin_5端口低电平
			}
			if(choice_0 == 2)
			{
				GPIO_SetBits(GPIOB,GPIO_Pin_5);		//给GPIOB_Pin_5端口高电平
				choice_0 = 0;
			}
		}
		
		if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)		//读取GPIOE端口3的电平
		{
			delay_ms(20);
			while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0);		
			delay_ms(20);
			choice_1 ++;
			if(choice_1 == 1)
			{
				GPIO_ResetBits(GPIOE,GPIO_Pin_5);		//给GPIOE_Pin_5端口低电平
			}
			if(choice_1 == 2)
			{
				GPIO_SetBits(GPIOE,GPIO_Pin_5);		//给GPIOE_Pin_5端口高电平
				choice_1 = 0;
			}
		}
		
		if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) == 0)		//读取GPIOE端口2的电平
		{
			delay_ms(20);
			while(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) == 0);
			delay_ms(20);
			choice_2 ++;
			if(choice_2 == 1)
			{
				GPIO_ResetBits(GPIOB,GPIO_Pin_8);		//给GPIOB_Pin_8端口低电平
			}
			if(choice_2 == 2)
			{
				GPIO_SetBits(GPIOB,GPIO_Pin_8);		//给GPIOB_Pin_8端口高电平
				choice_2 = 0;
			}
		}
		
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)		//读取GPIOA端口0的电平
		{
			delay_ms(20);
			while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1);
			delay_ms(20);
			choice_3 ++;
			if(choice_3 == 1)
			{
				
			}
			if(choice_3 == 2)
			{
				
				choice_3 = 0;
			}
		}
		*/
	}
	
}

void EXTI0_IRQHandler()			//外部中断0
{
	if (EXTI_GetITStatus(EXTI_Line0) == SET)		//判断外部中断标志位是否置1
	{

		EXTI_ClearITPendingBit(EXTI_Line0);			//清除外部中断标志位,为了能进行下一次中断
	}
}

void EXTI2_IRQHandler()			//外部中断2
{
	if (EXTI_GetITStatus(EXTI_Line2) == SET)		//判断外部中断标志位是否置1
	{
		
		EXTI_ClearITPendingBit(EXTI_Line2);			//清除外部中断标志位,为了能进行下一次中断
	}
}

void EXTI3_IRQHandler()			//外部中断3
{
	if (EXTI_GetITStatus(EXTI_Line3) == SET)		//判断外部中断标志位是否置1
	{
		
		EXTI_ClearITPendingBit(EXTI_Line3);			//清除外部中断标志位,为了能进行下一次中断
	}
}

void EXTI4_IRQHandler()			//外部中断4
{
	if (EXTI_GetITStatus(EXTI_Line4) == SET)		//判断外部中断标志位是否置1
	{
		
		EXTI_ClearITPendingBit(EXTI_Line4);			//清除外部中断标志位,为了能进行下一次中断
	}
}

你可能感兴趣的:(单片机,stm32,嵌入式硬件)