STM32中断分析(按键进入)

中断分析(标准库)

        这篇文章主要是通过标准库进行一下分析中断的配置,通过四个按键进入中断,(在文章的末尾也会写一下寄存器版本的中断如何配置,感兴趣的也可以看一下)。这篇文章中没有怎么对中断进行讲解,在后续等我真正搞明白了会再写一期讲解的文章,这里主要是配置是其运行。

        目前来说已经学过了中断,定时器,和串口。因为也是一直在学习,所以抽空才开写了第二篇的中断分析。后面在周末也会进行补上这一周的学习。

中断函数分析

        中断是什么呢,按我的理解(一个小白的理解)就是跟在主函数里写if条件判断有些相似,只不过中断对于单片机主程序来说相当于是一个非阻塞的判断,(只是相当于),因为中断要求的是快进快出,人眼看不出来主程序被打断了。就是主程序在运行然后给你一个中断信号,接收到后就去执行中断服务函数里的内容,执行完毕后立刻重新返回主函数进行。(这个想法可以作为一个参考,个人想法)。

        在STM32ZET6中一共有ABCDEFG7个端口,EXTI0输入线可以与该7个端口的0引脚的联系起来,EXTI1输入线可以与该7个端口的1引脚的联系起来,以此类推。然后需要配置EXTI输入线的初始化,选择中断模式,选择触发方式,使能该输入线,最后完成初始化。
        接下来开始对NVIC的配置,需要配置其中断通道,优先级,使能该通道,完成初始化。
        最后是写中断服务函数

        

  EXTI_InitTypeDef EXTI_InitStructure={0};
  NVIC_InitTypeDef NVIC_InitStructure={0};
	
  /* Enable AFIO clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);            //开启时钟
	
  /*选择EXTI0输入线跟哪个GPIO联系起来*/
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);     //按键1
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);   //按键2
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);   //按键3
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource6);   //按键4
	
  /* Configure EXTI0 456 line */
  //初始化四个按键的中断线
  EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line4|EXTI_Line5|EXTI_Line6;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;            //EXTI为中断模式
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;         //上升沿触发
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;                      //使能输入线
  EXTI_Init(&EXTI_InitStructure);

	
  /* Enable and set EXTI0 Interrupt to the lowest priority */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;               //配置中断通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;   //抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;          //响应优先级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能通道
  NVIC_Init(&NVIC_InitStructure);	
	
	
  NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                //配置中断通道	
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //响应优先级
  NVIC_Init(&NVIC_InitStructure);	
	
	
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;                //配置中断通道	
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;      //抢占优先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;             //响应优先级
  NVIC_Init(&NVIC_InitStructure);	

        按键3和4共用了一个中断通道EXTI9_5_IRQn,这里是芯片定义的,我们调用。需要记住。所以就是使能了三个中断。

        接下来就是对中断服务函数的分析了,这里又有一个小坑,中断服务函数在STM32的启动文件了有一一对应的,我们写的函数必须写在启动文件的函数名里。不然的话无法使用。这里我写一个EXTI9_5_IRQHandler()的服务函数,另外的EXTI4_IRQHandler()和EXTI0_IRQHandler()就比较简单了,不在举例了。为什么写这个就是因为他是5-9集成在一起的函数,要想分开使用就需要加入if条件判断了。

if(EXTI_GetITStatus(EXTI_Line5) != RESET)        //按键3触发中断
  {
    /* Toggle LED1 */
		G_Toggle();                            //亮起RGB灯绿灯(宏定义)可以换位自己想要的操作
    /* Clear the  EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line5);
  }	
  if(EXTI_GetITStatus(EXTI_Line6) != RESET)
  {
    /* Toggle LED1 */
		B_Toggle();                            //蜂鸣器开关(宏定义)可以加入自己想做的操作
    /* Clear the  EXTI line 0 pending bit */
    EXTI_ClearITPendingBit(EXTI_Line6);        //按键4触发中断
  }	    

其实到这里,中断配置就已经结束了。然后再根据上一期写的按键就可以完成对中断的配置。可以按照自己的想法去实现自己想要的功能。

备注:寄存器编写中断

EXTI初始化

    //1,开启AFIO时钟
	RCC->APB2ENR |= 1;
	//2,选择PA0 作为EXTI0的输入引脚  PC456
	AFIO->EXTICR[0] &= ~0xF; //注意不要写错
	AFIO->EXTICR[1] |= 0x222;//选择PC为EXTI456输入线的引脚
	//3,配置EXTI0的触发边沿为上升沿
	EXTI->RTSR |= 1;
	EXTI->RTSR |= 7<<4;//配置EXTI输入线456为上升沿触发
	//4,开启EXTI0中断屏蔽寄存器
	EXTI->IMR |= 1;
	EXTI->IMR |= 7<<4;//配置EXTI开启中断请求
	//5,先清除一下PR寄存器
	EXTI->PR |= 1;
	EXTI->PR |= 7<<4;//清除EXTI输入线456上的挂起寄存器
	//6,开启中断通道,配置中断通道优先级
	NVIC_SetPriority(EXTI0_IRQn,0);//抢占0 响应0 
	NVIC_EnableIRQ(EXTI0_IRQn);
	NVIC_SetPriority(EXTI4_IRQn,5);//抢占1 响应1
	NVIC_EnableIRQ(EXTI4_IRQn);
	NVIC_SetPriority(EXTI9_5_IRQn,4);//抢占1 响应0
	NVIC_EnableIRQ(EXTI9_5_IRQn);

中断服务函数,同样以9_5为例
 

    if((EXTI->PR & (1<<5)) != 0)//EXTI5触发中断
	{
		G_Toggle();
	//	Delay_nms(3000);
	//	BEEP_OFF();
		//清除一下PR寄存器
		EXTI->PR |= 1<<5;	
	}
	if((EXTI->PR & (1<<6)) != 0)//EXTI6触发中断
	{
		B_ON();
		Delay_nms(3000);
		B_OFF();
		//清除一下PR寄存器
		EXTI->PR |= 1<<6;	
	}

对比寄存器和库函数来讲,但从这里看寄存器确实比库函数配置简单。但是库函数对于移植操作的方便就远远不是寄存器能比的了。

时间比较紧急,本次分析就先到这里,后面对于中断的分析讲解可能会过二十天左右,等在来复习的时候才会进行更加细致的讲解,肯定比现在理解要深刻。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值