玩具:HC6800-ES开发版

这里记录一些我的新玩具:51单片机的基础常识,作为初学者,下文必然是错误百出。

很久没更新博客了,毕竟很久没写程序了。数学类的嵌套的定义又太多,很不好写。

新玩具

这次淘宝买的新玩具是:HC6800-ES V2.0 开发版,内部单片机是STC89C52。见下图
开发版
作为小白看了一下视频,但是呢,感觉视频什么的太慢,还是看书看手册来的爽。安装好单片机版C语言的IDE Keil4 以及烧录软件之后,装一下开发版驱动,就可以在不知道单片机原理的情况下轻松的控制单片机了。例如什么 LED灯闪烁,跑马灯,等等很基础的程序。

下面是单片机的管脚图和说明:
管脚图
说明1
说明2

从图上看知道P0,P1,P2,P3是重要的I/O口,例如我们把P2接到LED灯,那么给低电平0,就可以使灯亮。还有P0,P1不仅可以作为I/O口,还可以作为地址,计时器、计数器来用。还有P3,等等。由于我用的是开发版,每个口接什么基本上已经固定了,用的时候查相应的官方资料就行了。它也提供了很多程序例子,因此还是很好掌握的,只是要记点东西才能灵活操作它。

HC6800-ES-VS2.0 常见管脚接法。

  1. P2口8个位接了8个LED灯,至0灯亮。
  2. P1.5接了蜂鸣器。循环至0至1发声。
  3. P3.0 ~ P3.3 接了独立键盘(不过开发版上竟然接反了K1和K2),使用按键的时候要软件消除抖动,一般延迟10ms来完成。
  4. 通过P1的数据,来判断矩阵键盘按的键。(见下图)
    矩阵键盘原理图
  5. 数码管使用P0, 通过 LSA=P2.2, LSB=P2.3, LSB=P2.4 的0-1指来控制显示的地方。
  6. 常用定时器中断标程。

1602 液晶显示

这个虽然很复杂,但是生产该显示屏的会提供lcd.hlcd.c然后我们只要先初始化LCD:LcdInit()再执行字节输出函数:LcdWriteData(char c)即可。

程序示例

程序功能: 按下k1键LED跑马灯,K2蜂鸣器发生,K3数码管显示1-8。由于不会中断,所以跑马灯写的很挫。

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
90
91
92
93
#include <reg52.h>
#include <intrins.h>

typedef unsigned int u16;
typedef unsigned char u8;
#define led P2
sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit beep=P1^5;
u8 beepS,i,ledState = 0,DigState = 0;
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //显示0~F的值
void delay(u16 t){ // 每次约10us
while(t--);
}
void ledStart(){
ledState = 1;
led=0xfe;
for(i=0;i!=7;++i){
led = _crol_(led,1);
delay(50000);
}
}
void ledStop(){
ledState = 0;
led = 0xff;
}
void DigDisplay(){
DigState = 1;
for(i=0;i<8;i++){
switch(i){ //位选,选择点亮的数码管
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=smgduan[i]; //发送段码
delay(50000); //间隔一段时间扫描
}
}
void DigStop(){
DigState = 0;
P0 = 0x00;
}
void keyPress(){
if(k1==0){ // 检测k1是否按下
delay(1000);//消除抖动 一般大约10ms
if(k1==0){ //再次判断按键是否按下
if(ledState==0) ledStart();
else ledStop();
}
while(!k1); //检测按键是否松开
}
if(k2==0){
delay(10);
if(k2==0){
beepS=10;
while(beepS<200){
beep=~beep;
delay(beepS);
++beepS;
}
}
while(!k2);
}
if(k3==0){
delay(10);
if(k3==0){
if(DigState == 0) DigDisplay();
else DigStop();
}
while(!k3);
}
}
void main(){
while(1) keyPress();
}