標題:
51單片機的8層電梯程序設計
[打印本頁]
作者:
oneday_008
時間:
2019-6-6 08:31
標題:
51單片機的8層電梯程序設計
基于51單片機的電梯設計;可控制上下8層電梯
單片機源程序如下:
#include <reg52.h> //調(diào)用單片機頭文件
#define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
#define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
//數(shù)碼管段選
uchar code smg_du[]={0xde,0x90,0xcd,0xd9,0x93,0x5b,0x5f,0xd0,0xdf};//數(shù)碼管段碼 共陰
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為逆時史上轉(zhuǎn)
uchar value2; //計數(shù)幾個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;
}
}
/***********************正轉(zhuǎn)****************************/
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;
}
}
/***********************正轉(zhuǎn)****************************/
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延時函數(shù)*****************************/
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; //電平轉(zhuǎn)換
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;
}
}
}
}
/****************電梯向上、做最后的判斷是否還要繼續(xù)向上****************/
void dt_shang_guan()
{
uchar value;
if(dt_s_x == 1) //電梯向上 做最后的判斷是否還要繼續(xù)向上
{
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; //有人按鍵先讓其?浚笥胻d_due函數(shù)判斷是否真需要?
}
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;
}
}
}
/****************電梯向下、做最后的判斷是否還要繼續(xù)向下****************/
void dt_xia_guan()
{
uchar value;
if(dt_s_x == 2) //電梯向下 做最后的判斷是否還要繼續(xù)向下
{
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 ; //停下
}
/***********************電梯處理函數(shù)************************/
void td_due() //100ms執(zhí)行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) //當?shù)搅说谝粚拥臅r候
{
if(dt_1 == 1)
{
dt_1 = 0; //清零標志
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 2) //當?shù)搅说诙䦟拥臅r候
{
if(dt_2 == 1)
{
dt_2 = 0;
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 3) //當?shù)搅说?層的時候
{
if(dt_3 == 1)
{
dt_3 = 0;
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 4) //當?shù)搅说?層的時候
{
if(dt_4 == 1)
{
dt_4 = 0;
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 5) //當?shù)搅说?層的時候
{
if(dt_5 == 1)
{
dt_5 = 0;
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 6) //當?shù)搅说?層的時候
{
if(dt_6 == 1)
{
dt_6 = 0;
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 7) //當?shù)搅说?層的時候
{
if(dt_7 == 1)
{
dt_7 = 0;
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
else if(dt_value == 8) //當?shù)搅说?層的時候
{
if(dt_8 == 1)
{
dt_8 = 0; //清零在的標志
flag_stop = 0; //到停下
beep = 0; //打開蜂鳴器
}
}
}
}
}
}
if(flag_stop == 0) //開始?块W爍
{
value2 ++; //計數(shù)幾個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; //計數(shù)幾個100ms
led_open = 1; //關門指示燈
led_close = 0; //關門指示燈
dianji(2); //電機關門
dianji_lock = 1; //解鎖電機判斷
dt_shang_guan(); //電梯向上 做最后的判斷是否還要繼續(xù)向上
dt_xia_guan(); //電梯向下 做最后的判斷是否還要繼續(xù)向下
}
}
}
/*************定時器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; //計數(shù)幾個100ms
flag_stop = 1; //1:需要?繕酥
}
key_with();
}
if(key_left == 0) //關門鍵按下
{
delay_ms(10);
key1_flag = 1; //關門鍵標志
}
tiandi_shang_xia(); //當電梯?繒r(stop=1)、判斷是向上、還是向下,并開關電機
dianji_open_lock(); //電機開關判斷是否有效函數(shù)
P0 = smg_du[dt_value]; //顯示
if(flag_100ms == 1)
{
flag_100ms = 0;
num++; //用于開門計數(shù)
td_due(); //電梯處理函數(shù)
}
//////////////////////////////////
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); //電機正轉(zhuǎn)
}
else
{
fan(i); //電機反轉(zhuǎn)
}
Delay(100); //改變這個參數(shù)可以調(diào)整電機轉(zhuǎn)速
}
}
}
}
/*************定時器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, 下載次數(shù): 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.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1