基于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)
|