本笔记默认学习者已拥有:
1.Keil5和stc烧写工具 等各种软件、驱动、环境;
2.有一个属于自己的 51单片机开发板及相关零件 ;
3.认识C语言的语法;
本人使用的51开发板为 郭天祥C51 TX-1C增强版开发板 ;
本笔记根据B站up主:江科大自化协的教学视频 整理得到ヾ(•ω•)
3-1 独立按键控制LED亮灭
原理分析
上图为TX-1C的 独立按键及矩阵按键 原理图 ,注意到寄存器位置与视频 有所不同
1.GND为接地线,可以视为电源的负极;
2.独立按键一头 接地 ,另一头接到了 IO口上,单片机通电时,所有IO口默认都是高电平;
3.所以当没有按下 独立按键时,IO口为高电平,按下 独立按键时,IO口为低电平;
上一节,我们介绍了寄存器,介绍了寄存器可以赋值给IO口。
4.寄存器可以检测IO口的电平,读回到寄存器中,
如果 按键 松开,直接读取寄存器,它应该为 1(高电平的状态);如果按下 按键,那它的值应该为 0(低电平状态);
通过此现象,可以检测按键是否被按下;
实践代码
上一节 学习了 直接给整个P2寄存器赋值,来达到让LED亮灭的效果,但如果只控制独立的单个位,而不影响其他位呢?
1.打开头文件 #include<reg51.h>
,其中sfr
是用来定义 整个8位寄存器 的;
2.其中 sbit
是用来定义 位寄存器 的,操作这些变量,就可以单独操作每一位;
独立按键控制LED亮灭.c
#include<reg51.h>
sbit led1=P1^0;
//sfr P1=0x90; 但#include<reg51.h>中并未定义其 位寄存器
//这里选择 自主定义
void main(){
while(1){
//根据#include<reg51.h>的定义,s2按键对应的端口为P3^4,即为 T0
if(T0==0) led1=0;
else led1=1;
}
}
运行结果如下:
3-2 独立按键控制LED状态
消抖的两种方法:
(1)硬件消抖:增加电路,通过电路中的触发器等 电路操作,将抖动进行过滤,此方法比较麻烦,且需要硬件支持;
(2)软件消抖:检测按键是否按下时,前后各延时20ms,抖动时间就过去了;
如下是完整的 检测按键是否按下 的代码
if(T0==0){
Delayms(20);
while(T0==0);//检测松手,只要不松手,就一直保持循环
Delayms(20);
//do sth.
}
独立开关控制LED状态.c
#include<reg51.h>
#define uint unsigned int
sbit led1=P1^0;
void Delayms(uint x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main(){
while(1){
Delayms(20);
if(T0==0){
Delayms(20);
while(T0==0);
Delayms(20);
led1=~led1;
}
Delayms(20);
}
}
运行结果如下:
3-3 独立按键控制LED显示二进制.c
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
void Delayms(uint x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main(){
uchar LEDnum=0;
//uchar 刚好表示 0~255,符合 8位寄存器的大小
while(1)
if(T0==0){
Delayms(20);
while(T0==0);
Delayms(20);
//P1口上电默认给高电平,即P1= 1111 1111
//直接让P1 +1 ,则P1=0000 0000
//不符合预期,故使用 变量 LEDnum 来表示 寄存器
++LEDnum;
P1=LEDnum;
}
}
运行结果如下:
3-4 独立按键控制LED移位.c
此代码写法与视频不同
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
void Delayms(uint x) //@11.0592MHz
{
unsigned char i, j;
while(x--){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main(){
uchar LEDnum=0;
while(1){
if(T0==0){
Delayms(20);
while(T0==0);
Delayms(20);
LEDnum<<=1;
if(LEDnum==0) LEDnum=1;
P1=~LEDnum;
}
if(T1==0){
Delayms(20);
while(T1==0);
Delayms(20);
LEDnum>>=1;
if(LEDnum==0) LEDnum=0x80;
P1=~LEDnum;
}
}
}
运行结果如下:
相关知识
此为 复位按键,按下 复位按键,相当于 电源重新打开,单片机程序会从头开始。