抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

点亮第一个led灯

  1. 新建工程

    image-20210821203338653

  2. 选择固件

    image-20210821203543242

    image-20210821203717166

  3. 新建代码源文件

    image-20210821203932209

    image-20210821204130367

    image-20210821204227781

  4. 添加如下代码

    1
    2
    3
    4
    5
    6
    7
    8
    #include <reg52.h> //引用51头文件

    sbit LED = P1^1;

    void main()
    {
    LED = 0; //点亮LED2
    }
  5. 编译前要先配置,让编译器在编译完成后输出hex文件,hex文件用来烧录进单片机里面

    image-20210821204723747

  6. 编译

    image-20210821205109242

  7. 上传(烧录)

    image-20210821205434569

到此第一个点灯小程序结束

流水灯

按照之前的步骤再建立一个新工程,写下如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <reg52.h>	 //包含51头文件
#include <intrins.h> //包含移位标准库函数头文件

#define uint unsigned int
#define uchar unsigned char

uchar temp; //LED灯相关变量

//延时函数
void delay(uint z)
{
uint x, y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}

void main()
{
temp = 0xfe;
P1 = temp; //1111 1110 初值LED1亮
delay(1000);//毫秒级延时 100毫秒
while(1)
{
temp = _cror_(temp, 1);//循环左移
P1 = temp;//移位完成后赋值给P1 每个一个灯点亮
delay(1000);//毫秒级延时 100毫秒
}
}

说明:

  • intrins.h 头文件包含移位函数 :右移_cror_()左移_corl_()

蜂鸣器

蜂鸣器分有源与无源蜂鸣器

  • 有源指内部自带震荡源,只要提供电压即可响,但由于其震荡源震动频率固定,因此只能产生一种频率的声音
  • 无源蜂鸣器指内部没有震荡源,需要提供变化的电压(方波)才能让其响

一个蜂鸣器的简单驱动电路:

image-20210821210804064

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <reg52.h>	//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件

#define uint unsigned int

sbit beep = P2^3;//蜂鸣器

void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}

void main()
{
while(1)
{
beep = ~beep;// 蜂鸣器发出滴滴声
delay(100);
}
}

数码管

原理

单个数码管结构原理:

image-20210821211542277

多个数码管:

image-20210821211818619

说明:

74HC573是个锁存器,原理如下:

image-20210821212211630

当控制端LE为高电平时,输出端Q的数据随输入端D的数据变化而变化

当控制端LE为低电平时,输入端D的数据变化,Q端会保持之前的状态

在这幅图

image-20210821211818619

用到2片74HC573模块,上面一片是用来控制哪一个数码管使用,下面那一片用来控制显示的字符

在这8个数码管中,左边是低位,右边是高位,这是共阴极数码管,比如位选输入“0xFE”(即1111 1110),最左边这个数码管就被选中了。

数码管的每一段都接到地,给对应的段提供高电平就能点亮它,其数码表如下

1
2
3
4
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
// 0 1 2 3 4 5 6 7 8 9
0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x76, 0x38, 0x40, 0x00
//A B C D E F H L - 熄灭

数码管静态显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管位选

void main()//main函数自身会循环
{
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110 选通最左边的数码管
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = 0X5b;//1101 1011 显示“1”
DU = 0;//锁存段选数据

while(1);
}

数码管动态显示

要让多个数码管同时显示,如果用静态显示的方式,每个数码管都要8根线连接,n个数码管就要 n*8根线,比较耗费资源,因此使用动态扫描的方式进行显示,即快速扫描每一个数码管,分别让它们进行显示,只要足够快,由于视觉暂留效应,人的大脑会以为这是同时显示,实际上每个时刻只有一个数码管进行了显示

这个代码用来控制3个数码管来显示一个三位数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选

//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};

void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}

//设计一个函数用于显示三位的数字number
void display(uchar number)
{
uchar bai, shi, ge;
bai = number / 100; //百位
shi = number % 100 / 10; //十位
ge = number % 10; //个位

P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = tabel[bai];//
DU = 0;//锁存段选数据
delay(5);

//第二位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFD; //1111 1101
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = tabel[shi];//
DU = 0;//锁存段选数据
delay(5);

//第三位数码管
P0 = 0XFF;//清除断码
WE = 1;//打开位选锁存器
P0 = 0XFB; //1111 1011
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
P0 = tabel[ge];//
DU = 0;//锁存段选数据
delay(5);
}

void main()//main函数自身会循环
{
while(1)
{
display(185); //数码管显示185
}
}

键盘

非编码键盘分为独立键盘和矩阵键盘

独立键盘

image-20210821222715524

对于独立键盘而言,例如,当S2按键按下时,P30被拉低,变为低电平,因此要判断S2是否被按下,只需要不断检测

P30是否为低电平即可

【注意】

  1. 按键消抖,最简单的是延时10~20ms后再检查其状态是否变化
  2. 松手检测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*********************************************************************************
按下开发板S2按键数码管值+1,最大到9
按下S3按下,值-1,最小减到0
**********************************************************************************/
#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
uchar num;//数码管显示的值

//共阴数码管段选表0-9
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};


//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}

void main()//main函数自身会循环
{
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据

while(1)
{
if(key_s2 == 0)//判断S2是否被按下
{
delay(20);//按键消抖
if(key_s2 == 0)
{
if(num != 9)//如果值不等于9则+1,功能把值限定为小于9
num++;
while(!key_s2);//松手检测
}
}
if(key_s3 == 0)//判断S3是否被按下
{
delay(20);//按键消抖
if(key_s3 == 0)
{
if(num > 0) //如果大于0则执行减一
num--;
while(!key_s3);//松手检测
}
}
//松手之后刷新显示
DU = 1;//打开段选锁存器
P0 = tabel[num];//
DU = 0;//锁存段选数据
}
}

矩阵键盘

判断矩阵按键中某个按键是否按下可采用先列扫描再行扫描的方式

  1. 列扫描:先给P37, P36, P35, P34高电平,同时给P33,P32,P31,P30低电平,即传送 “0xF0”(11110000)过去,如果【S6】(或S10/S14/S18)按下,则P34就会被拉低,P3的引脚数据变为“0xE0”(1110 0000),S7按下,P35被拉低,变为“0xD1”(1101 0000),因此只要判断P3这一变量的数据变化即可判断是哪一列被按下了;
  2. 行扫描:给P3发送“0x0F”(0000 1111),如果是【S6】按下,则P30被拉低,P3数据变为“0x0E”(0000 1110),如果是【S10】按下,P3数据变为“0x0D”(0000 1101),这样就可以判断出是哪个按键按下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*********************************************************************************
* 【程序功能】: 4*4矩阵键盘与4位独立键盘识别
* 【使用说明】: 按下矩阵键盘和独立键盘任意键,数码管显示相应数值
初始显示“-”横
**********************************************************************************/
#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar KeyValue = 20;//按键值 显示-

//共阴数码管段选表
uchar code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x76, 0x38, 0x37, 0x3E, 0x40, 0x00 };
//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,H,L,,n,u,-,熄灭


void delay(uint z)
{
uint x,y;
for(x = z; x > 0; x--)
for(y = 114; y > 0 ; y--);
}

void KeyScan()
{
//4*4矩阵键盘扫描
P3 = 0XF0;//列扫描
if(P3 != 0XF0)//判断按键是否被按下
{
delay(10);//软件消抖10ms
if(P3 != 0XF0)//判断按键是否被按下
{
switch(P3) //判断那一列被按下
{
case 0xe0: KeyValue = 0; break;//第一列被按下
case 0xd0: KeyValue = 1; break;//第二列被按下
case 0xb0: KeyValue = 2; break;//第三列被按下
case 0x70: KeyValue = 3; break;//第四列被按下
}
P3 = 0X0F;//行扫描
switch(P3) //判断那一行被按下
{
case 0x0e: KeyValue = KeyValue; break;//第一行被按下
case 0x0d: KeyValue = KeyValue + 4; break;//第二行被按下
case 0x0b: KeyValue = KeyValue + 8; break;//第三行被按下
case 0x07: KeyValue = KeyValue + 12; break;//第四行被按下
}
while(P3 != 0X0F);//松手检测
}
}

P3 = 0XFF;//独立按键扫描
if(P3 != 0XFF)
{
delay(10);//软件消抖10ms
if(P3 != 0XFF)
{
switch(P3) //判断那一行被按下
{
case 0xfe: KeyValue = 16; break;//S2被按下
case 0xfd: KeyValue = 17; break;//S3被按下
case 0xfb: KeyValue = 18; break;//S4被按下
case 0xf7: KeyValue = 19; break;//S5被按下
}
while(P3 != 0XFF);//松手检测
}
}

}

void main()//main函数自身会循环
{
WE = 1;//打开位选锁存器
P0 = 0XFE; //1111 1110
WE = 0;//锁存位选数据

DU = 1;//打开段选锁存器
while(1)
{
KeyScan();//20个按键键盘扫描
P0 = tabel[KeyValue];//显示按键值
}
}

总结:先列扫描,再行扫描;或者先行扫描,再列扫描

评论