04STM32外部中断
EXTI(Extern Interrupt)外部中断
EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序支持的触发方式:上升沿/下降沿/双边沿/软件触发支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒触发响应方式:中断响应/事件响应。
GPIO_Pin一样的不能同时用,只能选一个。如果有多个中断引脚,要选择不同的Pin的引脚。通道数16个GPIO_Pin 对应着GPIO_Pin0-15,加上外加的总共20个中断线路,16个GPIO_Pin是外部中断的主要功能,跟着的4个是来蹭网的。
蹭网原因:外部中断有一个功能:从低功耗模式的停止模式下唤醒STM32。本节主要学习引脚的外部中断,这4个蹭网先了解一下即可。
中断响应:申请中断,让CPU执行中断函数。
事件响应:外部中断的信号不通向CPU,而是通向其他外设,用来触发其他外设的操作,属于外设之间的联合工作。
EXTI的右边是20根输入线,输入线首先进入边沿检测电路,在上升沿触发选择寄存器和下降沿触发选择寄存器可以选择触发方式,接着触发信号进入或门的输入端,(数据选择器的符号是梯形,有多个输入一个输出,侧面有选择控制端,根据控制端的数据,从输入选择一个接到输出)。硬件触发或者软件中断寄存器的值接到了或门上。
触发信号通过或门后,分为两路,上一路触发中断,下一路触发事件。触发中断首先会置一个请求1挂起寄存器,这相当于一个中断标志位,我们可以读取这个寄存器判断是哪个通道触发的中断,如果请求挂起寄存器置1,他就会继续往前走,和中断屏蔽寄存器共同进入一个与门,然后是NVIC中断控制器。
下一路也是一个事件屏蔽寄存器进行开关控制,最后通过一个脉冲发生器到其他外设,脉冲发生器就是给一个电平脉冲,用来触发其他外设的动作。
NVIC的补充
因为是内核外设,所以的得在Cortex-M3编程手册里找,Cortex-M3编程手册是内核和内核外设的详细介绍,研究内核的转运细节,可以研究这个手册。中文版本会更加友好
中断编程的建议:
1.在中断函数里,最好不要执行耗时过长的代码,中断函数要简短快速。别刚进中断就执行一个Delay多少毫秒这样的代码,因为中断是处理一个突发的事情,如果为了一个突发的事情待在中断里出不来了,那主程序就会收到严重的阻塞
2.不要在中断函数和主函数调用相同的函数或者操作同一硬件,尤其是硬件相关函数。比如OLED显示函数,如果既在主函数里调用LED,又在中断调用OLED,OLED就会显示错误。因为可能在主程序中,OLED刚显示一半,进入中断后,还是OLED显示函数,那OLED就可能挪到其他地方显示了,当中断结束之后,需要继续原来的显示就出问题了。因为硬件的显示位置被挪到其他地方了,所以再回来时,继续显示的内容就会跟着跑到其他地方去。
虽然在中断进入和退出时,会有保护现场和恢复现场,但这只能保证CPU程序能正常返回不出问题,对于外部硬件的话,并没有在进入中断时进行现场保护。为了避免这样可能存在的问题,就最好不要在主程序和中断程序里,操作可能产生冲突的硬件。
可以在中断里操作变量或者标志位,当中断返回时,再对这个变量进行显示和操作,这样既能保证中断函数的简短快捷,又能保证不产生冲突的硬件操作。这就是中断程序设计的注意事项。
其他地方也可以多用变量或者标志位,来减少代码之间的耦合性,让各部分代码相互独立,仅使用变量、标志位或者函数作为接口,这样让程序更加清晰、代码更加强健。