直接对STM32的寄存器操作来实现外部中断配置

        STM32F103在上课的时候只学习了基础的知识,可以通过老师给的例程来修改一些简单的功能,比如修改定时器的频率、修改ADC通道等;但是后面自己买了一块STM32F103C8T6的开发板,刚拿到手没有模板,发现自己点亮一个灯都很困难,后面又看了数据手册,对于以前用过的功能,如何去配置还是不太懂,以前学习的东西只是知其然而不知其所以然。

        现在有空闲时间了所以从头学习一下,希望可以从寄存器开始学习,今天学习了通过直接配置寄存器来配置外部中断,通过CSDN记录下来,加深自己印象,也方便以后回忆,要是里面有错误请多多指正。


        首先要了解的是ISER寄存器(Interrupt Set-Enable Registers),这是一个中断使能寄存器组,这个寄存器组可以在core_cm3.h这个文件中找到,下面这个是我在Keil中的截图:        

        CM3 内核支持 256 个中断,这里用 8 个 32 位寄存器来控制,每个位控制一个中断。

        STM32 的可屏蔽中断最多只有 68 个,这里有用的就是三个(ISER[0~2]),总共可以表示 96 个中断。而 STM32 只用了其中的前 68 位。

        ISER[0]的 bit0~31 分别对应中断0~31ISER[1]的 bit0~32 对应中断 32~63ISER[2]的 bit0~3 对应中断 64~67;这样总共 68 个可屏蔽中断就分别对应上了。要使能某个中断,必须设置相应的 ISER 位为 1。

        在STM32的头文件stm32f10x.h中可以查看每一个中断对应的中断号,在170行左右,如下图:         要想设置外部中断,就要先使能对应的中断,比如我要设置PA0外部中断,PA0这个中断源产生的外部中断是EXTI0,中断序号是6,也就是说ISER[0]的第6位控制着EXTI0_IRQn是否使能,往该位写1使能中断,如图:

就可以使能EXTI0这个外部中断了。

        前面已经完成了大的中断的使能,接下来还有一系列的操作,STM32F103有19个外部中断,通过中断屏蔽寄存器(EXTI_IMR)就可以看出来,如下图:

        其中,位0到位15对应16根中断线的使能,这16根中断线可以连接到Px0~Px15(x位A、B、C、D....)的外部引脚上,比如要想配置PA1为外部中断,那么要把中断屏蔽寄存器(EXTI_IMR)的位0置1,当然这只是第一步。

        从数据手册里面可以看到配置中断的过程,如下:

        前面通过EXTI_IMR寄存器使能对应的中断线,然后要设置上升沿触发和下降沿触发通过

EXTI_RTSR(Rising Trigger)和EXTI_FTSR( Falling Trigger)两个寄存器来设置,如下图:

         往对应寄存器的对应位写1就可以了,可以同时允许上升沿和下降沿触发。

        一根中断线只能选择一个外部输入引脚作为中断源,比如EXTI0这个中断线,它的外部中断源只能从Px0(PA0、PB0、PC0.....)等引脚中选择一个,通过往AFIO_EXTICRx(x=0、1、2、3)这个寄存器里面写入数据来选择具体哪一个引脚作为外部中断输入源。

        具体写什么数据可以看下面的表:        

         由4个位来决定一个中断线的中断源,比如往最低四位写入0,那么PA0就是中断线EXTI0的中断输入源,写往最低四位写入0001,那么PB0就是中断线EXTI0的中断输入源。写程序的时候要注意的是,在keil里面这样的寄存器一共有4个AFIO->EXTICR[0]AFIO->EXTICR[3]对应AFIO_EXTICR1到AFIO_EXTICR4.

        设置了外部中断源之后,然后通过SCB->AIRCR寄存器设置中断优先级分组,然后通过NVIC->IP设置中断优先级就可以了。

        

        上面就是配置STM32的外部中断的一个大致的流程,需要注意的是,在配置外部中断的时候,需要使能对应端口的时钟,把对应的引脚设置为输入模式,同时还要使能IO复用功能的时钟,即APB2 外设时钟使能寄存器(RCC_APB2ENR)的第一位AFIOEN然后再进行外部中断寄存器的配置。

        以配置PA0为外部中断为例,总的代码如下:

   //配置PA0为外部中断
    
    RCC->APB2ENR |= 1<<2 | 1<<0; //使能PA口时钟和AFIO复用功能时钟
    GPIOA->CRL &= 0xFFFFFFF0;
    GPIOA->CRL |= 0x00000008;     //配置PA0为上下拉输入
    GPIOA->ODR |= 1<<0;             //通过往ODR寄存器写1配置PA0为上拉输入

    
    
    NVIC->ISER[0] |= 1<<6;  //使能EXTI0这个外部中断
    EXTI->IMR |= 1<<0;      //使能EXTI0外部中断线
    EXTI->FTSR |= 1<<0;        //下降沿触发
    
    AFIO->EXTICR[0] |= 0x00; //配置PA0位外部中断输入源
    
    
    /*
    接下来是配置中断分组和中断优先级,中断分组配置一次之后会一直有效。

    就算不进行下面的配置,使用默认的也是可以的,这两个寄存器对应其他知识,以后再添加。
    配置中断分组 ------->>   SCB->AIRCR寄存器。
    配置中断优先级 ------->> NVIC->IP[x]寄存器,x为对应中断号。
    
    然后就完成了对中断的配置
    */
    

        然后到启动文件startup_stm32f10x_hd.s去找到中断服务函数的名称,从下面可以看到EXTI0的中断服务函数为EXTI0_IRQHandler。

         然后就可以写外部服务函数,触发中断后就会自动执行里面的代码。

void EXTI0_IRQHandler(void)
{
	delay_ms(15);//按键消抖

	/*
	这里面写入要执行的代码
	*/
	
	EXTI->PR |= 1<<0;//软件清除中断标志位
}

        这里提到EXTI->PR寄存器,它是中断挂起寄存器。当外部中断线上发生了选择的边沿事件,该寄存器的对应位会被置为1,需要用软件置0。和前面的EXTI->IMR中断屏蔽寄存器一样的。

         以上就是配置外部中断的大致思路了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值