标题:
51单片机的8层电梯程序设计
[打印本页]
作者:
oneday_008
时间:
2019-6-6 08:31
标题:
51单片机的8层电梯程序设计
基于51单片机的电梯设计;可控制上下8层电梯
单片机源程序如下:
#include <reg52.h> //调用单片机头文件
#define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
#define uint unsigned int //无符号整型 宏定义 变量范围0~65535
//数码管段选
uchar code smg_du[]={0xde,0x90,0xcd,0xd9,0x93,0x5b,0x5f,0xd0,0xdf};//数码管段码 共阴
uchar code key_table[]={0xee,0xde,0xbe,0x7e, //键盘扫描
0xed,0xdd,0xbd,0x7d,
0xeb,0xdb,0xbb,0x7b,
0xe7,0xd7,0xb7,0x77};
uchar code table[]={1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8};
bit flag_100ms,flag_1s;
bit flag_stop = 1; //要不要在相应的楼停下 1:需要停靠标志 0:开始停靠
bit dianji_lock = 1;
bit key1_flag = 0;//关门标志位
bit key2_flag = 0;//开门标志位
sbit beep = P2^6;
sbit xia = P2^0; //LED
sbit zhong = P2^1; //LED
sbit shang = P2^2; //LED
sbit dj_right = P1^0;
sbit dj_left = P1^1;
sbit hongwai = P1^2;
sbit key_right= P1^3;
sbit key_left = P1^4;
sbit led_open = P1^5;
sbit led_close= P1^6;
uchar flag_start ; //启动标志位 1为起动步进电机 否则关闭电机
uchar flag_z_f; //正反标志位 0为顺时钟 1为逆时史上转
uchar value2; //计数几个100ms
uchar key_can; //按键值接收
sbit dj1 = P2^7; //电机IO口定义
sbit dj2 = P2^5;
sbit dj3 = P2^4;
sbit dj4 = P2^3;
uchar dt_1; //1楼电梯标志位
uchar dt_2;
uchar dt_3;
uchar dt_4;
uchar dt_5;
uchar dt_6;
uchar dt_7;
uchar dt_8;
uchar dt_value = 1; //电梯到哪一层的变量
uchar dt_s_x ; //电梯上下的标志位 0停 1上 2下
void delay_ms(uchar t) //ms
{
uchar a,b;
for(;t>0;t--)
for(a=142;a>0;a--)
for(b=2;b>0;b--);
}
void Delay(unsigned int i)//延时
{
while(--i);
}
/////////////////////直流电机////////////////////////////////
void dianji(uchar s)
{
if(s == 0) //关电机
{
dj_right = 0;
dj_left = 0;
}
if(s == 1) //开门
{
dj_right = 1;
dj_left = 0;
}
if(s == 2) //关门
{
dj_right = 0;
dj_left = 1;
}
}
/***********************正转****************************/
void zheng(uchar dat)
{
switch(dat)
{
case 0: dj1=1;dj2=0;dj3=0;dj4=0; break;
case 1: dj1=0;dj2=1;dj3=0;dj4=0; break;
case 2: dj1=0;dj2=0;dj3=1;dj4=0; break;
case 3: dj1=0;dj2=0;dj3=0;dj4=1; break;
}
}
/***********************正转****************************/
void fan(uchar dat)
{
switch(dat)
{
case 0: dj1=0;dj2=0;dj3=0;dj4=1; break;
case 1: dj1=0;dj2=0;dj3=1;dj4=0; break;
case 2: dj1=0;dj2=1;dj3=0;dj4=0; break;
case 3: dj1=1;dj2=0;dj3=0;dj4=0; break;
}
}
/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
uint i,j;
for(i=0;i<q;i++)
for(j=0;j<120;j++);
}
/********************独立按键程序*****************/
void key() //键盘扫描程序
{
uchar i,temp,temp1,temp2,num;
key_can = 20; //按键值还原
P3=0xf0;
if(P3!=0xf0)
{
delay_ms(20);
if(P3!=0xf0)
{
temp1 = P3; //记录高四位的列号
P3 = 0x0f; //电平转换
temp2 = P3; //记录低四位的行号
temp = temp1|temp2; //行列定位
for(i=0;i<16;i++)
if(temp==key_table[i])
{
num =i;
break;
}
}
key_can = table[num];
delay_ms(1);
}
}
void key_with() //电梯楼层标志位
{
if(key_can == 1)
{
dt_1 = 1; //
}
if(key_can == 2)
{
dt_2 = 1;
}
if(key_can == 3)
{
dt_3 = 1;
}
if(key_can == 4)
{
dt_4 = 1;
}
if(key_can == 5)
{
dt_5 = 1;
}
if(key_can == 6)
{
dt_6 = 1;
}
if(key_can == 7)
{
dt_7 = 1;
}
if(key_can == 8)
{
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; //有人按键先让其停靠,后用td_due函数判断是否真需要停靠
}
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_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 == 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_1 + 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_3+ + 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_3 + 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_1 + dt_2 + 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 dianji_open_lock()
{
if(dianji_lock == 1)
{
if(dt_s_x == 1)
{
flag_start = 1 ; //运行
flag_z_f = 0; //向上
}
if(dt_s_x == 2)
{
flag_start = 1 ; //运行
flag_z_f = 1; //向下
}
if(dt_s_x == 0)
{
flag_start = 0 ; //停下
flag_z_f = 1; //
}
}
else flag_start = 0 ; //停下
}
/***********************电梯处理函数************************/
void td_due() //100ms执行1次
{
uchar value,value1;
value = dt_1 + dt_2 + dt_3 + dt_4 + dt_5 + dt_6 + dt_7 + dt_8;
if(value != 0) //有人按下
{
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)
{
dt_1 = 0; //清零标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 2) //当到了第二层的时候
{
if(dt_2 == 1)
{
dt_2 = 0;
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 3) //当到了第3层的时候
{
if(dt_3 == 1)
{
dt_3 = 0;
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 4) //当到了第4层的时候
{
if(dt_4 == 1)
{
dt_4 = 0;
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 5) //当到了第5层的时候
{
if(dt_5 == 1)
{
dt_5 = 0;
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 6) //当到了第6层的时候
{
if(dt_6 == 1)
{
dt_6 = 0;
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 7) //当到了第7层的时候
{
if(dt_7 == 1)
{
dt_7 = 0;
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
else if(dt_value == 8) //当到了第8层的时候
{
if(dt_8 == 1)
{
dt_8 = 0; //清零在的标志
flag_stop = 0; //到停下
beep = 0; //打开蜂鸣器
}
}
}
}
}
}
if(flag_stop == 0) //开始停靠闪烁
{
value2 ++; //计数几个100ms
dianji_lock = 0;//给电机判断加锁
///////////////////////////////////
dianji(1); //电机开门
led_open = 0; //开门指示灯
led_close = 1; //开门指示灯
////////////////////////////////////
if(key1_flag == 1) //关门键
{
key1_flag = 0;
if(hongwai==0)//没人
{
value2 = 10;
led_open = 1; //关门指示灯
led_close = 0; //关门指示灯
dianji(2); //电机关门
}
}
if(value2 >= 20) //2.0s
{
dianji(0); //关闭电机
}
if(hongwai==1)//红外有人则一直停靠
{
value2 = 0; //重新一轮
dianji(0);
led_open = 0; //开门指示灯
led_close = 1; //开门指示灯
}
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 >= 50)//停靠5s,然后判断是否需要上下
{
value2 = 0; //计数几个100ms
led_open = 1; //关门指示灯
led_close = 0; //关门指示灯
dianji(2); //电机关门
dianji_lock = 1; //解锁电机判断
dt_shang_guan(); //电梯向上 做最后的判断是否还要继续向上
dt_xia_guan(); //电梯向下 做最后的判断是否还要继续向下
}
}
}
/*************定时器0初始化程序***************/
void time_init()
{
EA = 1; //开总中断
TMOD = 0X01; //定时器0、工作方式1
ET0 = 1; //开定时器0中断
TR0 = 1; //允许定时器0定时
}
/******************主程序**********************/
void main()
{
uchar i,num;
P1 = 0x00;
P0 = 0X00; //单片机IO口初始化
time_init(); //定时器初始化
led_open = 1; //关门指示灯
led_close = 0; //关门指示灯
dianji(0); //电机关闭
while(1)
{
key(); //按键扫描程序
if(key_can < 20)
{
if(dt_s_x == 0)
{
value2 = 0; //计数几个100ms
flag_stop = 1; //1:需要停靠标志
}
key_with();
}
if(key_left == 0) //关门键按下
{
delay_ms(10);
key1_flag = 1; //关门键标志
}
tiandi_shang_xia(); //当电梯停靠时(stop=1)、判断是向上、还是向下,并开关电机
dianji_open_lock(); //电机开关判断是否有效函数
P0 = smg_du[dt_value]; //显示
if(flag_100ms == 1)
{
flag_100ms = 0;
num++; //用于开门计数
td_due(); //电梯处理函数
}
//////////////////////////////////
if(key_right==0)//开门键
{
delay_ms(5);
if(key_right==0)//开门键
{
key2_flag = 1;//开门标志位
}
}
if(key2_flag==1)
{
num = 0;
key2_flag = 0;//开门标志位
if(dt_s_x == 0)
{
dianji(1);
led_open = 0; //开门指示灯
led_close = 1; //开门指示灯
}
}
if(num>=20) //2s关电机
{
dianji(0);
}
if(num>=50)
{
led_open = 1; //关门指示灯
led_close = 0; //关门指示灯
}
//////////////////////////////////////
if(flag_start == 1)
{
for(i=0;i<4;i++) //4相
{
if(flag_z_f == 0)
{
zheng(i); //电机正转
}
else
{
fan(i); //电机反转
}
Delay(100); //改变这个参数可以调整电机转速
}
}
}
}
/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{
static uchar value;
TH0 = 0x3c;
TL0 = 0xb0; // 50ms
value ++;
if(value % 2 == 0)
{
flag_100ms = 1 ;
}
}
复制代码
所有资料51hei提供下载:
电梯程序keil.zip
(59.87 KB, 下载次数: 34)
2019-6-6 08:30 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
admin
时间:
2019-6-6 20:05
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
作者:
1106833140@qq.c
时间:
2020-2-18 19:36
请问楼主大神有Proteus仿真图吗
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1