51开发板样例代码合集

学习51单片机开发板的代码样例备份一下。

1.LED相关控制

1.1点亮一个LED

先来看一下LED部分和51单片机的电路连接,这个影响到我们代码应该怎么写,比如LED是共阴极,那你LED控制亮的话,要输出高电平,如果你LED共阳极,则需要输出低电平,
c51_LED_image.png
可以看到,LED是共

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<8052.h>
// 0.01 * 100 = 1ms * 500
void delay_500ms(){
int us = 50000;
while(us--);
}
void main() {
// 1111 1110
P2 = 0xFE;
delay_500ms();
P2 = 0xFF;
delay_500ms();

}

1.2.单片机LED轮流闪烁

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
#include<8052.h>
// 0.01 * 100 = 1ms * 500
void delay_500ms(){
int us = 50000;
while(us--);
}
void main() {

P2 = 0xFE;// 1111 1110
delay_500ms();
P2 = 0xFD;// 1111 1101
delay_500ms();
P2 = 0xFB;// 1111 1011
delay_500ms();
P2 = 0xF7;// 1111 0111
delay_500ms();
P2 = 0xEF;// 1110 1111
delay_500ms();
P2 = 0xDF;// 1101 1111
delay_500ms();
P2 = 0xBF;// 1011 1111
delay_500ms();
P2 = 0x7F;// 0111 1111
delay_500ms();
}

2. 按键控制LED

2.1 单个独立按键控制LED,按下点亮,松开熄灭

这里主要是检测IO口的电平高低,上电后寄存器可以操作IO引脚电平高低,比如P1_0 = 1 输出高电平,那么同理,反过来 如果外围电路按键,参考电路图,c51_spilt_buttons_dianlu.png
这里的电路图,K1按键按下,P3_1 和 GND导通,那么P3_1 自然就是低电平,此时如果去检测P3_1 IO口的电平,那他就是低电平,IO口除了可以用来输出高低电平,还可以用作检测输入,那么这里,是把按键绑定到了LED亮灭来指示效果。

1
2
3
4
5
6
7
8
9
10
#include<8052.h>
void main() {
while(1) {
if(P3_1 == 0) {
P2_0 = 0;
} else {
P2_0 = 1;
}
}
}

2.2 两个按键一起绑定,控制LED亮灭,K1 & K2 一起按下LED点亮,松开其中一个熄灭

同样,中间的表达式改成 || 的话,就两个按键 都可以控制LED亮灭。再同样,左移,右移操作,可以玩LED灯的按位与,按位或,可以实现一个逻辑门电路的结果展示,以及LED左右移,来实现流水灯。

1
2
3
4
5
6
7
8
9
10
#include<8052.h>
void main() {
while(1) {
if(P3_1 == 0 && P3_0 == 0) {
P2_0 = 0;
} else {
P2_0 = 1;
}
}
}

2.3 按键控制LED长亮,或长灭

这里包含了按键消抖,按键因为是机械部件,设计不太会很精密,按下和松开的时候,不会直接就变高电平或低电平,他可能会有一部分抖动的时间,大概20ms左右才变稳定,所以要加按键消抖。
而代码上,P2_0 的取反,江科大他写的是 P2_0 = ~P2_0; 但是在我们这里不起作用,问了AI,建议是用 逻辑取反,因为AI说 具体运行的时候,P2_0会被当作int来处理,int是16位,也不知真假,估计是编译器的问题,可能用Keil就正常了,这个差异,AI说是我们编译器的问题,我们用的是 sdcc,这个本身没有什么问题,能够学到就ok了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<8052.h>
// 0.01 * 100 = 1ms * 500
void delay(int xms){
int us = xms * 100;
while(us--);
}

void main() {
while(1) {
if(P3_1 == 0) {
// 按键消抖
delay(20);
while(P3_1 ==0);
delay(20);
P2_0 = !P2_0;
}
}
}

2.4 LED展示二进制加法操作

P2++ 这个是核心的操作,最开始是1111 1111 8个全亮,++ 第一次全部熄灭,然后按一次D1亮,按第二次,D1灭,D2亮,第三次D1再亮,D2也亮,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<8052.h>
// 0.01 * 100 = 1ms * 500
void delay(int xms){
int us = xms * 100;
while(us--);
}

void main() {
while(1) {
if(P3_1 == 0) {
// 按键消抖
delay(20);
while(P3_1 ==0);
delay(20);
P2++;
}
}
}

2.5 LED显示二进制加法操作的另一种方式

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

// 0.01 * 100 = 1ms * 500
void delay(int xms){
int us = xms * 100;
while(us--);
}

void main() {
unsigned char LED = 0;
while(1) {
if(P3_1 == 0) {
// 按键消抖
delay(20);
while(P3_1 ==0);
delay(20);
LED++;
P2 = ~LED;
}
}
}

2.6 使用位移来实现LED流水灯

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<8052.h>
// 0.01 * 100 = 1ms * 500
void delay(int xms){
int us = xms * 100;
while(us--);
}

void main() {
unsigned char LED = 0;
P2 = ~0x01;
while(1) {
if(P3_1 == 0) {
// 按键消抖
delay(20);
while(P3_1 ==0);
delay(20);
LED++;
LED = LED%8;
P2 = ~(0x01<<LED);// 这里LED会是0-7,0x01是 0000 0001 然后取反, 只有一个灯高电平,但是这个LED输出低电平才会亮,所以

}
}
}

2.7 一个按键控制LED往左移,一个按键控制LED往右移

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
#include<8052.h>
// 0.01 * 100 = 1ms * 500
void delay(int xms){
int us = xms * 100;
while(us--);
}

void main() {
unsigned char LED = 0;
P2 = ~0x01;
while(1) {
if(P3_1 == 0) {
// 按键消抖
delay(20);
while(P3_1 ==0);
delay(20);
LED++;
LED = LED%8;
P2 = ~(0x01<<LED);
}
if(P3_0 == 0) {
// 按键消抖
delay(20);
while(P3_0 ==0);
delay(20);
LED--;
LED = LED%8;
P2 = ~(0x01<<LED);
}
}
}