|
零基础单片机系统化学习教程(51+STM32完整版) 初识51单片机51单片机相对还是容易上手的,语言也相对容易理解,无非就是指令和指令的使用方法。什么是指令?指令就好比你对一只狗说让它蹲下,它就要蹲下,这就是给它发送指令。单片机也是一样的,你给它发送什么指令,它才能做什么工作。 学习单片机没有捷径,不管学习C语言还是汇编语言,指令是需要要死记硬背的。不可能在写程序的时候,每用到一条指令都要临时去翻查资料。 本教程的学习以STC的51系列里面经典的STC32G12K128作为学习载体。它可以完成各类8位、16位、32位51的实验示例,并且程序编写对传统8位51单片机兼容性非常好。 接下来,我们先从按键控制LED亮灭开始实操学习,后面再引申出LED闪烁效果,循序渐进。 方法一:按键直接控制LED亮灭硬件约定:按键接在P3.0引脚,按键按下为低电平,松开为高电平;LED接在P1.0引脚,低电平点亮LED,高电平熄灭LED。 逻辑思路:不断循环读取按键引脚电平,如果按键按下,就点亮LED;按键松开,就熄灭LED。 #include "STC32G.h"
void Delay(unsigned int t) { unsigned int i,j; for(i = t; i > 0; i--) { for(j = 110; j > 0; j--); } }
void main(void) { while(1) { if(P3_0 == 0) // 判断按键是否按下 { Delay(10); // 简单软件消抖 if(P3_0 == 0) { P1_0 = 0; // 按键按下,点亮LED } } else { P1_0 = 1; // 按键松开,熄灭LED } } } 重点:按键消抖说明当按键按下的时候,因为接触不良或按键内部氧化、机械触点弹簧震动等原因,按键并不会直接稳定变成低电平。在按下和松开的一瞬间,触点会反复通断,引脚电平会在高电平、低电平之间来回跳动,这个现象叫做按键抖动。 单片机运行速度非常快,微秒级别就会读取一次IO电平。如果不加消抖处理,按键只是按了一下,单片机会误认为多次按下、松开,就会出现LED乱闪、误触发、反应不稳定的现象。 软件消抖的思路很简单:第一次检测到按键电平变化,不立刻判定按键动作;先延时一小段时间,跳过抖动的时间段,等触点电平稳定之后,再重新读取一次引脚电平。如果两次读取的状态保持一致,才认为是真实有效的按键动作。 上面代码里的Delay(10)就是做这个用途,用来跳过机械抖动时间,之后再二次判断引脚电平,过滤掉抖动带来的虚假信号。 硬件注意点: · LED必须串联限流电阻,禁止直接接IO口,防止电流过大烧毁IO; · · 按键可以外接上拉,STC32G内部自带上拉,也可以直接外部接上拉电阻; · · 按键机械触点会产生抖动,不加消抖程序会出现灯乱闪现象。 · 方法二:LED自动定时闪烁现在我们可以让一个LED亮和灭了,如果想让它自己按一定的时间来闪烁该怎么办呢,先让它亮一段时间,比如500MS,再让它灭500MS,一直这样循环,是的就是这样,下面是代码: #include "STC32G.h"
void Delay(unsigned int t) { unsigned int i,j; for(i = t; i > 0; i--) { for(j = 110; j > 0; j--); } }
void main(void) { while(1) { P1_0 = 0; // LED点亮 Delay(500); // 维持点亮500ms P1_0 = 1; // LED熄灭 Delay(500); // 维持熄灭500ms } } 程序说明:程序进入main函数,直接进入while(1)死循环。先把P1.0拉低点亮LED,调用延时函数保持500毫秒;再把P1.0拉高熄灭LED,再延时500毫秒,不断往复,实现LED周期闪烁。 提示:这里复用了前面写好的Delay延时函数,同一个延时函数,既可以给按键消抖使用,也可以用来做灯光定时。 方法三:使用!= 取反指令实现LED翻转闪烁在学习指令的过程中,您有没有注意到有一条指令是!,这个是什么意思呢,如果我们把它运用到上面的程序中该怎么做。 在C语言里面,!是逻辑取反运算符。真就变成假,假就变成真;1变成0,0变成1。我们LED需要的就是不断在0和1之间来回切换,利用这条指令,就不用我们手动分别写P1_0=0、P1_0=1两句赋值。 #include "STC32G.h"
void Delay(unsigned int t) { unsigned int i,j; for(i = t; i > 0; i--) { for(j = 110; j > 0; j--); } }
void main(void) { while(1) { P1_0 = !P1_0; // 将P1.0当前状态取反 Delay(500); // 延时500ms } } 程序说明:程序进入死循环,每一次循环直接对P1_0引脚状态做取反。原来为0,执行之后就变成1;原来为1,执行之后就变成0。延时500ms之后再次取反,同样实现500ms亮、500ms灭的闪烁效果。 对比上一段代码,代码变得更加简短。不需要分别写点亮、熄灭两行赋值语句,一条取反语句就完成状态切换。 |