前言:作者想要帮助一些童鞋和爱好者进行项目构建,但自知能力有限,不喜可论,创作不易,勿喷。

系统采用STC89C52芯片进行的电梯模拟控制系统,设计模拟了电梯控制系统基本功能,通过按键选择楼层,数码管显示实时楼层数,LED灯组成的箭头指示上下方向。

如​​项目一​​ 思路,对于这个系统来说:

第一,我们需要干什么?

从设计要求来看,就是利用按键来控制数码管显示和彩灯。

现在我们就有一个很简单的一个模型。

按键输入 (检测电信号) ==> STC89C51单片机(控制) ==>数码管和指示灯;

第二,我们需要用到什么?

软件方面

编程软件 keil4

烧录软件 stc-isp-15xx-v6.86q.exe

链接:https://pan.baidu.com/s/1hsGnfBAvfWlGXgPjhYXsyg

提取码:6666

画图软件 AD20

链接:https://pan.baidu.com/s/1Fyxh-PHZftNI1HIAMSTZPw

提取码:6666

仿真软件

protues 8.8安装包

链接:https://pan.baidu.com/s/1kAa5mwQl7cMc1DK84Rj6-g

提取码:6666

硬件方面

项目二 基于单片机的八层电梯_嵌入式


打板子

可以在嘉立创或捷配。(两家都行,仁者见仁)

第三 遇到了问题可以参考csdn、51黑电子论坛等。当然如果在学校老师是不二之选。

第一步树立思路已经好了,第二步就是画图,刚刚说了,画图用AD20,但是有一些库我们是没有的,除了自己构建库之外,以下两个网站也是很好的途径。
​​​PCBlib​​​​AD官网​

项目二 基于单片机的八层电梯_嵌入式_02


项目二 基于单片机的八层电梯_d3_03

第二步图已经画好了,送去打板焊接之后实物图如下。

项目二 基于单片机的八层电梯_d3_04


那么第三步就开始要写程序了。

#include <reg52.h>           //调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535

//数码管段选定义 0 1 2 3 4 5 6 7 8 9
uchar code smg_du[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0xdf,0xdb
// A B C D E F 不显示
}; //断码


bit flag_100ms,flag_1s;
bit flag_stop ; //用做到了相应的楼停下

sbit beep = P2^3;
sbit xia = P2^0;
sbit zhong = P2^1;
sbit shang = P2^2;

uchar value2;

sbit led1 = P1^7; //8个发光二极管定义
sbit led2 = P1^6;
sbit led3 = P1^5;
sbit led4 = P1^4;
sbit led5 = P1^3;
sbit led6 = P1^2;
sbit led7 = P1^1;
sbit led8 = P1^0;

uchar dt_1; //1楼电梯标志位
uchar dt_2; //2楼电梯标志位
uchar dt_3; //3楼电梯标志位
uchar dt_4; //4楼电梯标志位
uchar dt_5; //5楼电梯标志位
uchar dt_6; //6楼电梯标志位
uchar dt_7; //7楼电梯标志位
uchar dt_8; //8楼电梯标志位

uchar dt_value = 1; //电梯到哪一层的变量
uchar dt_s_x ; //电梯上下的标志位

/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}


/********************独立按键程序*****************/
uchar key_can; //按键值

void key() //独立按键程序
{
static uchar key_new;
key_can = 20; //按键值还原
P3 |= 0xff;
if(P3 != 0xff) //按键按下
{
delay_1ms(1); //按键消抖动
if((P3 != 0xff) && (key_new == 1))
{ //确认是按键按下
key_new = 0;
switch(P3)
{
case 0xfe: key_can = 1; break; //得到按键值
case 0xfd: key_can = 2; break; //得到按键值
case 0xfb: key_can = 3; break; //得到按键值
case 0xf7: key_can = 4; break; //得到按键值
case 0xef: key_can = 5; break; //得到按键值
case 0xdf: key_can = 6; break; //得到按键值
case 0xbf: key_can = 7; break; //得到按键值
case 0x7f: key_can = 8; break; //得到按键值
}
}
}
else
key_new = 1;
}

void key_with()
{
if(key_can == 1)
{
led1 = 1; //点亮发光二极管
dt_1 = 1; //
}
if(key_can == 2)
{
led2 = 1; //点亮发光二极管
dt_2 = 1;
}
if(key_can == 3)
{
led3 = 1; //点亮发光二极管
dt_3 = 1;
}
if(key_can == 4)
{
led4 = 1; //点亮发光二极管
dt_4 = 1;
}
if(key_can == 5)
{
led5 = 1; //点亮发光二极管
dt_5 = 1;
}
if(key_can == 6)
{
led6 = 1; //点亮发光二极管
dt_6 = 1;
}
if(key_can == 7)
{
led7 = 1;
dt_7 = 1;
}
if(key_can == 8)
{
led8 = 1;
dt_8 = 1;
}
}
/*********************当电梯不动时、判断是向上、还是向下**********************/
void tiandi_shang_xia()
{
static uchar value;
if(dt_s_x == 0)
{

flag_stop = 1;
if(dt_value == 1) //电梯在第1层停下不走了
{
value = dt_2 + dt_3 + dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上
shang = 0; //显示上
zhong = 0;
xia = 1;
}
}
if(dt_value == 2) //电梯在第2层停下不走了
{
value = dt_3 + dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;
}
}
if(dt_value == 3) //电梯在第3层停下不走了
{
value = dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1 + dt_2;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;

}
}
if(dt_value == 4) //电梯在第4层停下不走了
{
value = + dt_5 + dt_6 + dt_7 + dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1 + dt_2 + dt_3;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;
}
}
if(dt_value == 5) //电梯在第5层停下不走了
{
value = dt_6 + dt_7 + dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1 + dt_2 + dt_3 + dt_4;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;
}
}
if(dt_value == 6) //电梯在第6层停下不走了
{
value = dt_7 + dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1 + dt_2 + dt_3 + dt_4 + dt_5;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;
}
}
if(dt_value == 7) //电梯在第7层停下不走了
{
value = dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1 + dt_2 + dt_3 + dt_4 + dt_5 + dt_6;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;
}
}
if(dt_value == 8) //电梯在第8层停下不走了
{
value = dt_8;
if(value != 0)
{
dt_s_x = 1; //电梯向上走
shang = 0; //显示上
zhong = 0;
xia = 1;
}
value = dt_1 + dt_2 + dt_3 + dt_4 + dt_5 + dt_6;
if(value != 0)
{
dt_s_x = 2; //电梯向下走
xia = 0; //显示下
zhong = 0;
shang = 1;
}
}
}
}

/****************电梯向上、做最后的判断是否还要继续向上****************/
void dt_shang_guan()
{
uchar value;
if(dt_s_x == 1) //电梯向上 做最后的判断是否还要继续向上
{
if(dt_value == 1) //在第1层
{
value = dt_2 + dt_3 + dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 2) //在第2层
{
value = dt_3 + dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 3) //在第3层
{
value = + dt_6 + dt_7 + dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 4) //在第4层
{
value = dt_5 + dt_6 + dt_7 + dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 5) //在第5层
{
value = dt_6 + dt_7 + dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 6) //在第6层
{
value = dt_7 + dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 7) //在第7层
{
value = dt_8;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 8) //在第8层
{
dt_s_x = 0; //电梯停下不动了
shang = 1; //关闭上字
zhong = 1;
}
}
}

/****************电梯向下、做最后的判断是否还要继续向下****************/
void dt_xia_guan()
{
uchar value;
if(dt_s_x == 2) //电梯向下 做最后的判断是否还要继续向下
{
if(dt_value == 1) //在第1层
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
flag_stop = 1;
}
else if(dt_value == 2) //在第2层
{
value = dt_1;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 3) //在第3层
{
value = dt_1 + dt_2;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 4) //在第4层
{
value = dt_2 + dt_3;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 5) //在第5层
{
value = dt_1 + dt_2 + dt_4;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 6) //在第6层
{
value = dt_1 + dt_2 + dt_3 + dt_4 + dt_5;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 7) //在第7层
{
value = dt_1 + dt_2 + dt_4 + dt_5+ dt_6;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;
}
else if(dt_value == 8) //在第8层
{
value = dt_3 + dt_4 + dt_5 + dt_6 + dt_7;
if(value == 0) //说明上面没有人按下
{
dt_s_x = 0; //电梯停下不动了
xia = 1; //关闭上字
zhong = 1;
}else
flag_stop = 1;


}
}
}

/***********************电梯处理函数************************/
void td_dis()
{
uchar value,value1;
value = dt_1 + dt_2 + dt_3 + dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value != 0)
{ //100ms
if(flag_stop == 1) //到相应的楼了 要停下
{
/***************************向上走电梯***********************************/
if(dt_s_x != 0) //向上走电梯
{
value1 ++;
if(value1 >= 10) //1s
{
value1 = 0;
if(dt_s_x == 1) //向上走电梯
{
dt_value ++;
shang = 0; //显示上字
zhong = 0;
}
if(dt_s_x == 2) //向下走电梯
{
dt_value --;
xia = 0; //显示下字
zhong = 0;
}
if(dt_value == 1) //当到了第一层的时候
{
if(dt_1 == 1)
{
led1 = 0; //关闭第一层发光二极管
dt_1 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 2) //当到了第二层的时候
{
if(dt_2 == 1)
{
led2 = 0; //关闭第二层发光二极管
dt_2 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 3) //当到了第3层的时候
{
if(dt_3 == 1)
{
led3 = 0; //关闭第3层发光二极管
dt_3 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 4) //当到了第4层的时候
{
if(dt_4 == 1)
{
led4 = 0; //关闭第4层发光二极管
dt_4 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 5) //当到了第5层的时候
{
if(dt_5 == 1)
{
led5 = 0; //关闭第5层发光二极管
dt_5 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 6) //当到了第6层的时候
{
if(dt_6 == 1)
{
led6 = 0; //关闭第6层发光二极管
dt_6 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 7) //当到了第7层的时候
{
if(dt_7 == 1)
{
led7 = 0; //关闭第7层发光二极管
dt_7 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 8) //当到了第8层的时候
{
if(dt_8 == 1)
{
led8 = 0; //关闭第8层发光二极管
dt_8 = 0; //清零电机在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
}
}
}
}
if(flag_stop == 0)
{
value2 ++;
if(value2 % 5 == 0)
{
if(dt_s_x == 1) //上
{
shang = ~shang;
zhong = ~zhong;
}
if(dt_s_x == 2) //下
{
zhong = ~zhong;
xia = ~xia;
}
}
if(value2 >= 10) //1.0s
{
beep = 1; //关闭蜂鸣器
}
if(value2 >= 20) //100ms*20 = 2秒
{
value2 = 0;
dt_shang_guan(); //电梯向上 做最后的判断是否还要继续向上
dt_xia_guan(); //电梯向下 做最后的判断是否还要继续向下

}
}
}


/*************定时器0初始化程序***************/
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0、工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
}

void delay(int x)
{

while (x--);

}
/******************主程序**********************/
void main()
{
P1 = 0x00;
P0 = 0X00; //单片机IO口初始化
time_init(); //定时器初始化
P0 = 0xf1;
while(1)
{

dt_value++;
if(dt_value >=10)dt_value = 0;
key(); //按键程序
if(key_can < 20)
{
if(dt_s_x == 0)
{
value2 = 0;
flag_stop = 1;
}
key_with();
}
tiandi_shang_xia(); //当电梯不动时、判断是向上、还是向下
P0 = ~smg_du[dt_value]; //显示
if(flag_100ms == 1)
{
flag_100ms = 0;
td_dis(); //电梯处理函数
}
}
}

/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c;
TL0 = 0xb0; // 50ms
value ++;
if(value % 2 == 0)
{
flag_100ms = 1 ;
}
}

代码书写完成后,通过烧录软件烧录hex文件,可以进行板子运行。