注:学习STM32过程中的知识点记录,目前关于江科大STM32的学习笔记较少,因初学STM32,知识缺陷较多,故写下此笔记,记录在学习过程中自认为较为重要的知识点,分享给大家。希望本笔记能对大家有所帮助,大家共同学习进步!!!
纯手打,制作不易,不喜勿喷,谢谢大家!!!
持续更新中......
目录
一些知识点:
程序:对射式红外传感器计次、旋转编码器计次
‼️几乎所有模块都可以申请中断
AFIO也是APB2的外设。
两个中断通道时需要分别配置NVIC!!!
中断源很多:
中断函数建议:
1、中断函数不要太长,更不要加时间过长的延迟
2、不要在中断函数调用和主程序相同的硬件,如:同时调用OLED,OLED会显示错误,可以操作中断的变量和标志位,再在主程序里面操作显示(在主程序里OLED刚显示一半,就进中断了,中断里还是OLED的显示程序,再返回主程序时,原来显示的就到别的地方去了,保护现场和回复现场只能保证cpu程序正常运行,并不会对其他外部硬件保护现场)
‼️中断设计注意事项:多利用变量和标志位,减少代码间的耦合性!中断返回时再对这个变量进行操作,这样既能保证中断函数的简短快捷,又能保证不产生冲突的硬件操作。
1、中断系统介绍
中断,比如加减乘除在运行,oled显示程序执行了一半,delay函数正在等待时。
中断执行前会对程序的现场进行保护,中断执行后会再还原现场。
‼️中断触发条件:
对于外部中断来说,可以是引脚发生了电平跳变。对于定时器来说可以是定时时间到了。对于串口通信来说可以是接收到了数据。
中断优先级是自己设计的。
一般中断程序都是在一个子函数中,这个函数不需要我们调用,当中断来临时由硬件自动调用这个函数。
几乎所有模块都能申请中断。
‼️中断向量表:
中断抢占和响应优先级均相同时,按中断向量表小的优先
其中的中断地址是因为程序中的中断函数是由编译器分配的,是不固定的。但是中断跳转由于硬件限制只能跳到固定地址执行程序,所以为了让硬件跳转到一个不固定的中断函数中就需要在内存中定义一个地址列表,中断发生后就跳到这个固定位置。由编译器再加上一条跳转到中断函数的代码,这样中断就能跳转到任意位置了。用c语言不需要管中断向量表。
2、NVIC介绍(嵌套中断向量控制器)
用来统一分配中断优先级和管理中断的。EXTI只是NVIC的其中一个输入。
“叫号系统”
优先级由寄存器的四位(二进制)决定,即0-15,越小优先级越高。
分为高N位的抢占优先级,低4-N位的响应优先级。
cpu相当于医生,nvic相当于医院的叫号系统。
响应优先级:插队看病。
抢占优先级:不等屋里病人看完,直接进去看病。
3、EXTI介绍(外部中断)
“病人”
检测GPIO引脚电平,电平变化,申请中断。
想要获取的信号是外部驱动的很快的图发信号,单片机不知道什么时候会收到这些信号,有脉冲进来,stm32立即进入中断函数处理。(不推荐用外部中断读取按键,因为有按键抖动和松手检测的问题,可以考虑定时器中断。)
触发方式:上升沿/下降沿/双边沿/软件触发
所有的GPIO口都可以触发中断。
要有多个中断引脚,必须选择不同pin的引脚。
EXTI一共20个输入通道(信号):
主要是16个引脚的外部中断!
事件响应不会触发中断,而是触发别的外设操作,属于外设之间的联合操作。
外部中断可以从低功耗模式的停止模式下唤醒stm32。比如定闹钟后单片机进入停止模式,闹钟响的时候再唤醒。
AFIO为数据选择器,因为EXTI只有16个gpio通道,所以AFIO可以从前面三个GPIO外设里选择其中一个连接到后面的EXIT通道里。所以前面说相同的pin不能同时触发中断。
‼️外部中断的9-5,15-10被分配到了一个通道里。会触发同一个中断函数。需要再根据标志为区分到底是哪个中断进来的。
触发其它外设的是事件响应。
4、EXTI模块配置
程序:对射式红外传感器计次、旋转编码器计次
光敏传感器:光越强阻值越低,端口电压被下拉到低电平。遮挡阻值变高!
旋转编码器:
其中:
(1)对射式红外传感器计次
1、配置RCC
打开所有涉及时钟(EXTI和NVIC的时钟是一直打开着的,不需要再开启时钟了)
(NVIC是内核的外设,都不需要开启时钟)
2、配置GPIO
选择我们的端口为输入模式
3、配置AFIO
选择我们用的这一路GPIO,连接到后面的EXTI
4、配置EXTI
选择边沿触发方式,比如上升沿、下降沿或者双边沿。还有选择触发响应方式,可以选择中断响应(一般配置这个)和事件响应
5、配置NVIC
给我们这个中断选择一个合适的优先级(整个函数只能使用一种),通过NVIC,外部中断信号就能够进入CPU了,这样CPU能够接收到中断信号,才能跳转到中断函数执行中断程序
———这里涉及五个外设RCC、GPIO、AFIO、EXTI(寄存器里面没有EXTI时钟的控制位)、NVIC(内核的外设,不用RCC开启时钟,RCC管的是外设)
最后写中断函数,中断函数在start启动文件中,以IRQ结尾的函数。
(2)旋转编码器计次
❗️采用A、B相都触发中断,只有在B相下降沿和A相低电平时才判断为正转。A相下降沿和B相低电平时才判断为反转。这样就能保证正转反转都是到位了,才执行数字加减的操作。
外部中断的使用场景:
就是对于STM32来说,想要获取的信号是外部驱动的很快的突发信号。比如旋转编码器的输出信号,你可能很久都不会拧它,这时不需要STM32做任何事,但是我一拧它,就会有很多脉冲波形需要STM32接收。这个信号是突发的,STM32不知道什么时候会来,同时它是外部驱动的,STM32只能被动读取,最后这个信号非常快,STM32稍微晚一点来读取,就会错过很多波形。那对于这种情况来说,就可以考虑使用STM32的外部中断了。有脉冲过来,STM32立即进入中断函数处理,没有脉冲的时候,STM32就专心做其它事情。
另外还有,比如红外遥控接收头的输出,接收到遥控数据之后,它会输出一段波形,这个波形转瞬即逝,并且不会等你,所以就需要我们用外部中断来读取。
最后还有按键,虽然它的动作也是外部驱动的突发事件,但我并不推荐用外部中断来读取按键。因为用外部中断不好处理按键抖动和松手检测的问题,对于按键来说,它的输出波形也不是转瞬即逝的。所以要求不高的话可以在主程序中循环读取,如果不想用主循环读取的话,可以考虑一下定时器中断读取的方式。这样既可以做到后台读取按键值、不阻塞主程序,也可以很好地处理按键抖动和松手检测的问题。