目录
0.实物接线图
1.定时器实现非阻塞式程序
程序功能:
程序要求:
2.阻塞和非阻塞
阻塞:
非阻塞:
示例
按键扫描函数
LED闪烁函数
LED开关函数
3.定时器实现非阻塞式程序实现
第一步:在江科大STM32入门教程中复制OLED显示屏工程代码,命名为定时器实现非阻塞式程序
第二步:将定时器模块(江科大STM32入门中有)加入本工程,修改为1ms进入一次中断
Timer.c
第三步:解决按键扫描,松手检测时阻塞的问题,解决办法,用定时器扫描按键;不推荐使用外部中断扫描按键,因为外部中断很难处理按键抖动和松手检测的问题
在Key.h中头文件声明
定时器扫描按键-单按键
定时器扫描按键-多按键
第四步:实现LED闪灯的非阻塞
在LED.h中头文件声明
定时器实现LED闪烁
第五步:主函数调用
定时器实现非阻塞式按键完整程序
4.定时器实现非阻塞式程序注意事项
判断中断重叠的方法
出现中断重叠的改进方法
0.实物接线图
1.定时器实现非阻塞式程序
程序功能:
两个按键分别控制两个LED,使其切换不同的点亮模式
程序要求:
按键灵敏,每次按键按下都能准确切换模式
模块要高度封装,主程序调用要简洁
在任何时候模块代码都不能阻塞主程序
2.阻塞和非阻塞
阻塞:
执行某段程序时,CPU因为需要等待延时或者等待某个信号而被迫处于暂停状态一段时间,程序执行时间较长或者时间不定
非阻塞:
执行某段程序时,CPU不会等待,程序很快执行结束
示例
按键扫描函数
阻塞点:等待按键松手代码部分,在第一个if内的while中,如果按键一直按着,程序就会卡死在这个while里面
LED闪烁函数
阻塞点:两个Delay函数的调用,在等待时,整个程序都无法运行了
LED开关函数
这个是非阻塞程序,因为这里每段代码的运行时间<=1ms
可以使用RTOS操作系统,实现多线程的效果,但是RTOS的多线程还是稍微复杂一些的,如果没有RTOS,只用裸机程序,使用定时器,在配合一些程序思维,也可以很好的解决程序阻塞的问题
3.定时器实现非阻塞式程序实现
第一步:在江科大STM32入门教程中复制OLED显示屏工程代码,命名为定时器实现非阻塞式程序
第二步:将定时器模块(江科大STM32入门中有)加入本工程,修改为1ms进入一次中断
Timer.c
第三步:解决按键扫描,松手检测时阻塞的问题,解决办法,用定时器扫描按键;不推荐使用外部中断扫描按键,因为外部中断很难处理按键抖动和松手检测的问题
在Key.h中头文件声明
定时器扫描按键-单按键
第一步:定时中断,每隔20ms读取一次本次引脚值和上次引脚值
第二步:判断,如果本次是1,上次是0,则表示按键按下且当前处于刚松手的状态
第三步:置键码标志位,向主程序报告此事件
定时器扫描按键-多按键
第一步:先写一个获取键码值的子函数(非阻塞式)
获取此时按键的状态,不用进行松手检测,按键1按下就返回1,按键2按下就返回2,没有按下就返回0
第二步:定时中断,每隔20ms读取一次本次键码值和上次键码值
第三步:判断,如果本次是0,上次非0,则表示按键按下且当前处于刚松手的状态
第四步:置键码标志位,向主程序报告此事件
第四步:实现LED闪灯的非阻塞
在LED.h中头文件声明
定时器实现LED闪烁
第一步:定时中断,每隔1ms计次变量自增
第二步:计次变量计到周期值时,归零
第三步:判断,如果计次变量小于一个比较值,开灯,否则,关灯
第五步:主函数调用
定时器实现非阻塞式按键完整程序
4.定时器实现非阻塞式程序注意事项
主函数中的中断函数,被多个模块复用,要确保这些模块的代码的中断函数执行时间不要过久,不要出现一个中断还没执行结束,下一个中断就到来了,也就是中断重叠的现象
判断中断重叠的方法
进入中断函数的最开始,就清除中断标志位,然后等中断推出之前,再检查一下这个标志位,如果还没置1,说明中断没有重叠,反之中断重叠
出现中断重叠的改进方法
1.减小模块内中断函数的内容,减小运行时间
2.增加定时器的基础时间
当前代码每1ms进入一次中断,主程序被频繁的被中断打断,会不会有问题
实际上这样的问题不大,因为1ms的中断,对于72MHz的主频而已,还是很久
当前的方法不一定能解决很多阻塞问题,实践中改进