提前声明——我只是写的详细其实非常简单,不要看着多就放弃学习!
阻塞:执行某段程序时,CPU因为需要等待延时或者等待某个信号而被迫处于暂停状态一段时间,程序执行时间较长或者时间不定
非阻塞:执行某段程序时,CPU不会等待,程序很快执行结束
常规delay方法按键控制LED
uint8_t Key_GetNum(void)
{
uint8_t KeyNum = 0;
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
Delay_ms(20);
KeyNum = 1;
}
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
{
Delay_ms(20);
while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
Delay_ms(20);
KeyNum = 2;
}
return KeyNum;
}
这种方法通过外部中断来实现。会响应阻塞
mian()里面本想通过按键按下控制LED的慢闪和熄灭。但是因为Delay_ms(500);所以熄灭时会很不灵敏,得长按才能熄灭。并且在LED亮时i这个变量要1ms才增加1
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "kEY.h"
#include "LED.h"
uint8_t key1_flag = 0 ;
uint8_t keyNum ;
uint8_t i;
int main(void)
{
OLED_Init();
Key_Init();
LED_Init();
while (1)
{
keyNum = Key_GetNum();
if(keyNum == 1)
{
key1_flag = !key1_flag;
}
if(key1_flag)
{
LED1_ON();
Delay_ms(500);
LED1_OFF();
Delay_ms(500);
}
else
{
LED1_OFF();
}
OLED_ShowNum(2,2,i++,5);
}
}
这种程序不仅仅效果非常差,而且很占CPU
为了让主程序不被阻塞,也就是主程序可以快速刷新,但是按键消抖和LED闪烁是很常见的,就必须要让我们的程序有类似于多线程的操作了,单片机最长用的多线程是定时器定时中断
我们有两个Delay 1:按键消抖Delay_ms(20);LED闪烁Delay_ms(500);
一.定时器中断解决按键消抖Delay的问题,
解决办法就是定时器扫描按键,不要用外部中断检测
先归纳:
1.在Key.c写获取按键状态函数:PB1按下返回1,