stm32外部中断exti

案例
LCD屏显示时间,按键动态调节时、分、秒

案例说明
为什么会想到采用中断?
时钟设有一个初始的时间,时钟在运行时肯定要对时间调整。调整时间用按键来实现,对按键的处理有两种方法,一种是查询法,另一种是中断方法。查询法耗用大量的CPU运行时间,还要与动态扫描程序进行融合,效率低,编程复杂。中断法很好地克服上述缺点,故采用外部中断进行按键处理,完成时间调节。

设计分析
在这里插入图片描述
所有中断配置写在exit.c文件中。

代码编写

exti.c

extern u8 hour,minute,second;

EXTI初始化函数

void EXIT_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct; 
	NVIC_InitTypeDef NVIC_InitStruct;
	EXTI_InitTypeDef EXTI_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);//打开时钟并复用
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
	//GPIO初始化
    //PC13
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_IPU;  //上拉输入模式
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_13;
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitStruct);
	//PB12,14
	GPIO_InitStruct.GPIO_Mode =GPIO_Mode_IPU;  //上拉输入模式
	GPIO_InitStruct.GPIO_Pin =GPIO_Pin_12|GPIO_Pin_14;
	GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);

	//给端口引脚加上中断线
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource12);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
	
	//中断初始化
	EXTI_InitStruct.EXTI_Line =EXTI_Line12|EXTI_Line13|EXTI_Line14;
	EXTI_InitStruct.EXTI_Mode =EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger =EXTI_Trigger_Falling;
	EXTI_InitStruct.EXTI_LineCmd =ENABLE;
	EXTI_Init(&EXTI_InitStruct);
	
	//NVIC初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	//中断线设置优先级
	NVIC_InitStruct.NVIC_IRQChannel =EXTI15_10_IRQn;//中断线10-15的中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =1;//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority =0;//响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;//使能
	NVIC_Init(&NVIC_InitStruct);//中断初始化
	
	NVIC_InitStruct.NVIC_IRQChannel =EXTI15_10_IRQn;//中断线10-15的中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority =0;
	NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;
	NVIC_Init(&NVIC_InitStruct);

	NVIC_InitStruct.NVIC_IRQChannel =EXTI15_10_IRQn;//中断线10-15的中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority =1;
	NVIC_InitStruct.NVIC_IRQChannelCmd =ENABLE;
	NVIC_Init(&NVIC_InitStruct);
	
}

问:pinN一定要连接中断线lineN,中断通道一定要是NIRQn吗?
答:pin0-4连接中断线line0-4,中断通道0-4IRQn
pin5-9连接中断线line5-9,中断通道5-9IRQn
pin10-15连接中断线line10-15,中断通道10-15IRQn
所以上面pin12,13,14分别连接中断线line12,13,14,中断通道为10-15IRQn。

问:那它们的中断通道都是exti15_10这咋办啊,中断函数要三个呢
答:在这个函数里面,用if去判断哪一个被触发。

中断函数

void EXTI15_10_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line12)==SET)  //获取中断标志
	{
		if(K_OK==0)
		{
			if(K_OK==0)
			{ 
				delay_ms(10);
				if(++hour==24) hour =0;
			}
	  }
		EXTI_ClearITPendingBit(EXTI_Line12);//清除中断
	}else if(EXTI_GetITStatus(EXTI_Line13)==SET){  //获取中断标志
		if(K_UP==0)
		{
			if(K_UP==0)
			{ 
				delay_ms(10);
				if(++minute==60) minute=0;
			}
	  }
		EXTI_ClearITPendingBit(EXTI_Line13);//清除中断
	}else if(EXTI_GetITStatus(EXTI_Line14)==SET){  //获取中断标志
		if(K_RIGHT==0)
		{
			if(K_RIGHT==0)
			{ 
				delay_ms(10);
				if(++second==60) second=0;
			}
	  }
		EXTI_ClearITPendingBit(EXTI_Line14);//清除中断
	}
	
}

main.c

u8 hour,minute,second;
int main()
{
  hour=9;
	minute=6;
	second=18;
	delay_init(72);
	Power_Init();		 //电源IO初始化
	LED_Init();			 //LED初始化
	LCD_Init();
	EXIT_Init();
	LCD_ClearGram();
  while(1)
	{	
	char dissbuff[25];
	LCD_ClearGram();
	sprintf(dissbuff,"time:%d:%d:%d",hour,minute,second);//组合字符和变量
	LCD_ShowAllString(0,20,(u8 *)dissbuff,16,1);
	LCD_RefreshGram();
	}
}

实现效果
在这里插入图片描述

参考
《ARM Cortex-M3嵌入式原理及应用》
我的学弟

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏小泡泡#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值