STM32L152中断控制拓展实验代码及原理详解

附上次实验链接
https://blog.csdn.net/weixin_43401987/article/details/103003647
本文主要讲解用keil软件实现中断控制,默认读者keil环境已经配好,且头文件已正确引入,如出现编译错误以及st-link下载问题,请自行百度解决。

前面我们讲了中断控制的简单应用,下面就让我们结合键盘输入和七色灯的知识,看看怎么实现按键优先级屏蔽吧!

功能四:按键优先级屏蔽

具体:使用主板蓝色按键作为一个低优先级中断源,键盘阵列选择其中的一个按键作为
高优先级中断源,当蓝色按键按下一次时,亮红灯,红灯亮 5 秒后自动灭;键盘阵列
的一个按键按下一次时亮绿灯,绿灯亮 10 秒后灭;尝试以下操作:
⚫ 按下键盘阵列的按键,绿灯亮,此时再按蓝色按键,观察红灯是否亮灭
⚫ 按下蓝色按键,红灯亮,此时再按键盘阵列按键,观察绿灯是否亮灭

默认大家已经完成前面的实验,头文件等引用不再赘述,这里主要修改了几个函数里的参数。

1.GPIO初始化函数

由于用到了键盘输入,新激活了两个管脚PB9和PC5,分别代表键盘阵列的第一行和第一列,由于本实验只用到了键盘上的一个键,因此只激活这两个就够了。
另外由于用到了七色灯,还需要激活七色灯的三个管脚,(其实只用到了两个)这里我用的是PA5,PA6,PA7。LED注意四个管脚的连线,有一个管脚要接GND。
行输出低电平,列上拉并读取,未按键时会一直读高电平,按键按下之后将读到低电平。

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB|RCC_AHBPeriph_GPIOC,ENABLE);

	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_40MHz;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOC,&GPIO_InitStructure);
	GPIO_ResetBits(GPIOC,GPIO_Pin_5);
}
2.NVIC初始化函数

这里两个按键需要激活两个通道,第二行设置了优先级组别,我们给主优先级和次优先级分别分配两个bit的储存空间。给蓝色按键分配的优先级为3,给键盘第一个按键的优先级为2,故键盘优先级靠前,有抢占的权利。(由于是列在读取,故中断通道判断的是PB9的电平)

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x03;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
}
3.EXTI初始化函数

为两个按键配置外部中断参数

void EXTI_Configuration(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,EXTI_PinSource13);
	EXTI_InitStructure.EXTI_Line=EXTI_Line13;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB,EXTI_PinSource9);
	EXTI_InitStructure.EXTI_Line=EXTI_Line9;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_Init(&EXTI_InitStructure);
}
4.main函数
int main(void)
{
	GPIO_Configuration();
	EXTI_Configuration();
	NVIC_Configuration();
	while(1);
}
5.stm32l1xx_it.c文件里的代码

为了方便,将控制七色灯的管脚define一下

#define PA5 GPIOA,GPIO_Pin_5
#define PA6 GPIOA,GPIO_Pin_6
#define PA7 GPIOA,GPIO_Pin_7

下面是两个中断响应函数,分别响应键盘和蓝色按键,都是SetBits一个管脚delay一段时间再ResetBits,PB9控制绿灯,PC13控制红灯.
如果按下蓝色按键,红灯亮5秒灭,如果按下键盘第一个键,绿灯亮10秒灭。
如果按下蓝色按键紧接着按键盘,红灯变成黄灯(红灯绿灯同时亮)10秒后绿灯灭,灯又变为红色,经过不到5秒,红灯也灭了。
如果先按键盘紧接着按蓝色按键,绿灯不变,10秒后,自动变成红灯,5秒后红灯灭。
更多操作请大家自行实验。

void EXTI9_5_IRQHandler(void)
 {
	 if(EXTI_GetITStatus(EXTI_Line9) != RESET)
   {
		 GPIO_SetBits(PA6);
		 delay(20000000);
		 GPIO_ResetBits(PA6);
     EXTI_ClearITPendingBit(EXTI_Line9);
   }
 }
 void EXTI15_10_IRQHandler(void)
 {
	 if(EXTI_GetITStatus(EXTI_Line13) != RESET)
   {
		 GPIO_SetBits(PA5);
		 delay(10000000);
		 GPIO_ResetBits(PA5);
     EXTI_ClearITPendingBit(EXTI_Line13);
   }
 }

别忘了写上次用过的delay()函数啊!

至此,拓展实验已经全部完成,如果代码或者讲解有错误欢迎指出,大家也可以讨论自己的思路,由于鄙人时间有限,细节的疑问请大家认真思考,自力更生

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值