標(biāo)題:
單片機(jī)電梯控制器代碼
[打印本頁]
作者:
csqzhang
時(shí)間:
2018-10-31 17:17
標(biāo)題:
單片機(jī)電梯控制器代碼
單片機(jī)電梯控制器電路原理圖如下:
圖片1.png
(146.13 KB, 下載次數(shù): 46)
下載附件
仿真電路圖
2018-10-31 17:16 上傳
單片機(jī)源程序如下:
#include <REG52.H>
#include <INTRINS.H>
unsigned char ucMotorDrvPuls; //電機(jī)運(yùn)轉(zhuǎn)時(shí)初始值
unsigned char FORREV=1; //1表示上行,0表示下行
unsigned char STOPCUR=0;//1電梯停留在當(dāng)前層,0不停留
unsigned char CURFLR=1; //當(dāng)前所在樓層
unsigned char count=0; //累計(jì)到COUNT即表示運(yùn)行過一層
#define UCTIMES 8 //設(shè)置電機(jī)轉(zhuǎn)速
#define OUTPUT P2 //電機(jī)驅(qū)動信號口
#define COUNT 8 //電機(jī)每循環(huán)8次表示電梯經(jīng)過一層樓
sbit UP1=P3^4;
sbit DOWN2=P3^3;
sbit UP2=P3^2;
sbit DOWN3=P3^1;
sbit UP3=P3^0;
sbit DOWN4=P1^7;
sbit FLOOR1=P1^0;
sbit FLOOR2=P1^1;
sbit FLOOR3=P1^2;
sbit FLOOR4=P1^3;
sbit START=P1^4;
sbit STOP=P1^5;
sbit ALARM=P1^6;
//報(bào)警位
sbit alarmBit=P0^4;
sbit upLight=P0^5;
sbit downLight=P0^6;
void time(unsigned int ucMs);//延時(shí)單位:ms
void outPress();//按下電梯外按鈕
unsigned char inPress();//按下電梯內(nèi)樓層按鈕
unsigned char elevator();//到達(dá)某一層返回1,否則返回0
void storeUP(unsigned char);//存儲當(dāng)前所有上行請求
void storeDOWN(unsigned char);//存儲當(dāng)前所有下行請求
//延時(shí)函數(shù)
void time(unsigned int ucMs);
//初始化所有燈
void initLights(void);
//設(shè)置當(dāng)前樓層
void setFloor(int floor);
//設(shè)置電梯向上運(yùn)行燈
void setUpLight();
//設(shè)置電梯向下運(yùn)行燈
void setDownLight();
//設(shè)置電梯停止運(yùn)行燈
void setStopLight();
//設(shè)置電梯向上運(yùn)行燈
void setAlarmLight();
//設(shè)置電梯報(bào)警燈和喇叭
void setAlarmLight();
//關(guān)閉電梯報(bào)警燈和喇叭
void offAlarmLight();
//報(bào)警開關(guān)
int alarmSwitch=1;
unsigned char UP_req[5]={0,0,0,0,0}; //上行請求
unsigned char DOWN_req[5]={0,0,0,0,0}; //下行請求
//電機(jī)定位
void position(void)
{
OUTPUT=0x01|(P2&0xf0);time(200);
OUTPUT=0x02|(P2&0xf0);time(200);
OUTPUT=0x04|(P2&0xf0);time(200);
OUTPUT=0x08|(P2&0xf0);time(200);
ucMotorDrvPuls=0x11;
OUTPUT=0x01|(P2&0xf0);
}
/****************************************/
/* 主函數(shù) */
/****************************************/
void main(void)
{
time(100);
initLights();
position();//電機(jī)定位
ucMotorDrvPuls=0x11;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
setFloor(CURFLR);
setUpLight();
time(100);
while(1)//主循環(huán)
{
outPress();//按下電梯外按鈕
while(STOPCUR==1)//電梯在當(dāng)前層,電梯不動,可以繼續(xù)接受請求
{
outPress();
inPress();
}
if(inPress())//按下電梯內(nèi)樓層按鈕
{
while(START)//等待啟動按鍵按下,電梯不動,可以繼續(xù)接受請求
{
outPress();
inPress();
}
}
while(1)//電機(jī)運(yùn)轉(zhuǎn)循環(huán)
{
if(UP_req[1]==0&&UP_req[2]==0&&UP_req[3]==0&&
DOWN_req[2]==0&&DOWN_req[3]==0&&DOWN_req[4]==0)
{
break;//沒有請求,跳出電機(jī)運(yùn)轉(zhuǎn)循環(huán),電梯不動
}
if(FORREV)//上行
{
setUpLight();//上行燈亮
if(STOPCUR==1){break;}//
if(elevator())//往上到達(dá)某一層
{
if(CURFLR==4) {setDownLight();break;}//到達(dá)四樓
}
OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
ucMotorDrvPuls=_crol_(ucMotorDrvPuls,1);
}
if(!FORREV)//下行
{
setDownLight();//下行燈亮
;
if(STOPCUR==1){break;}
if(elevator())//往下到達(dá)某一層
{
if(CURFLR==1) {setUpLight();break;}//到達(dá)一樓
}
OUTPUT=(ucMotorDrvPuls&0x0f)|(P2&0xf0);
ucMotorDrvPuls=_cror_(ucMotorDrvPuls,1);
}
outPress();//按下電梯外按鈕
//if(inPress())//按下電梯內(nèi)樓層按鈕
//{
// while(START)//等待啟動按鍵按下
//{
// outPress();
inPress();//電梯運(yùn)行時(shí),內(nèi)部按鈕按下,無需按啟動按鈕
// }
//}
time(380-UCTIMES*16); //////////
}//end while-電機(jī)運(yùn)轉(zhuǎn)循環(huán)
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止,有請求時(shí)按下啟動按鈕啟動
}//end while-主循環(huán)
}
/****************************************/
/* 按鈕事件 */
/****************************************/
//按下電梯外按鈕
void outPress()
{
//FORREV=1;
if(!UP1)//1樓上
{
storeUP(1);
if(CURFLR>1&&STOPCUR==1)//電梯不在一樓,且當(dāng)前沒其他請求,電梯馬上自動啟動
{
FORREV=0;//向下運(yùn)行
STOPCUR=0;
}
if(CURFLR==1)
{
STOPCUR=1;//電梯停留在當(dāng)前層
}
}
if(!UP2)//2樓上
{
storeUP(2);
if(CURFLR>2&&STOPCUR==1)//電梯在二樓以上
{
FORREV=0;
STOPCUR=0;
}
if(CURFLR<2&&STOPCUR==1)
{
FORREV=1;
STOPCUR=0;
}
if(CURFLR==2)
{
STOPCUR=1;
}
}
if(!UP3)//3樓上
{
storeUP(3);
if(CURFLR>3&&STOPCUR==1)//電梯在三樓以上
{
FORREV=0;
STOPCUR=0;
}
if(CURFLR<3&&STOPCUR==1)
{
FORREV=1;
STOPCUR=0;
}
if(CURFLR==3)
{
STOPCUR=1;
}
}
if(!DOWN2)//2樓下
{
storeDOWN(2);
if(CURFLR>2&&STOPCUR==1)//電梯在二樓以上
{
FORREV=0;
STOPCUR=0;
}
if(CURFLR<2&&STOPCUR==1)
{
FORREV=1;
STOPCUR=0;
}
if(CURFLR==2)
{
STOPCUR=1;
}
}
if(!DOWN3)//3樓下
{
storeDOWN(3);
if(CURFLR>3&&STOPCUR==1)//電梯在三樓以上
{
FORREV=0;
STOPCUR=0;
}
if(CURFLR<3&&STOPCUR==1)
{
FORREV=1;
STOPCUR=0;
}
if(CURFLR==3)
{
STOPCUR=1;
}
}
if(!DOWN4)//4樓下
{
storeDOWN(4);
if(CURFLR<4&&STOPCUR==1)
{
FORREV=1;
STOPCUR=0;
}
if(CURFLR==4)
{
STOPCUR=1;
}
}
}
//按下電梯內(nèi)樓層按鈕
unsigned char inPress()
{
int i;
int flag=0;
if(!FLOOR1)
{
if(1<CURFLR)
{
STOPCUR=0;
UP_req[1]=1;
}
if(1==CURFLR)
{
STOPCUR=1;
}
return 1;
}
if(!FLOOR2)
{
if(2>CURFLR)//請求層大于當(dāng)前層
{
UP_req[2]=1;
STOPCUR=0;
}
if(2<CURFLR)
{
DOWN_req[2]=1;
STOPCUR=0;
}
if(2==CURFLR)
{
STOPCUR=1;
}
return 1;
}
if(!FLOOR3)
{
if(3>CURFLR)//請求層大于當(dāng)前層
{
UP_req[3]=1;
STOPCUR=0;
}
if(3<CURFLR)
{
DOWN_req[3]=1;
STOPCUR=0;
}
if(3==CURFLR)
{
STOPCUR=1;
}
return 1;
}
if(!FLOOR4)
{
if(4>CURFLR)
{
DOWN_req[4]=1;
STOPCUR=0;
}
if(4==CURFLR)
{
STOPCUR=1;
}
return 1;
}
if(!START)
{
STOPCUR=0;
return 1;
}
if(!STOP)//緊急停止
{
while(START)//不響應(yīng)其他按鍵
{
//亮燈
setStopLight();
}
return 1;
}
if(!ALARM)
{
//while(START)
//{
//亮燈
setAlarmLight();
//time(800);
//滅燈
//offAlarmLight();
//}
return 1;
}
if(FORREV==1)
{
//請求上行而進(jìn)去電梯內(nèi)選擇的是下層
for(i=CURFLR+1;i<=4;i++)
{
if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
}
if(flag==0)//上層沒請求
{
FORREV=0;
}
}
if(FORREV==0)
{
//請求下行而進(jìn)去電梯內(nèi)選擇的是上層
for(i=CURFLR-1;i>=1;i--)
{
if(UP_req[i]==1||DOWN_req[i]==1){flag=1;}
}
if(flag==0)//上層沒請求
{
FORREV=1;
}
}
return 0;
}
/*******************************************************************/
/* 到達(dá)某一層返回1,否則返回0, */
/* 亮燈、顯示數(shù)字、請求清零、電機(jī)停止、確定接下去電機(jī)方向 */
/*******************************************************************/
unsigned char elevator()
{
count++;
if(count==COUNT)
{
//正常情況
if(FORREV==1)//判斷上行是否到達(dá)請求樓層,上行請求優(yōu)先處理
{
CURFLR++;
setUpLight();//上行燈亮
if(CURFLR==2)//到達(dá)二樓
{
count=0;
setFloor(2);//顯示數(shù)字
if(UP_req[2]==1)//二樓有上行請求,優(yōu)先處理
{
setUpLight();
UP_req[2]=0;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
STOPCUR=1;
return 1;
}
if(DOWN_req[2]==1&&UP_req[3]==0&&DOWN_req[3]==0
&&DOWN_req[4]==0)//二樓有下行請求,上面兩層沒有請求,不再往上
{
setDownLight();
DOWN_req[2]=0;
STOPCUR=1;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
FORREV=0;
return 1;
}
}
if(CURFLR==3)//到達(dá)三樓
{
setFloor(3);//顯示數(shù)字
count=0;
if(UP_req[3]==1)//三樓有上行請求,優(yōu)先處理
{
setUpLight();
UP_req[3]=0;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
STOPCUR=1;
return 1;
}
if(DOWN_req[3]==1&&DOWN_req[4]==0)//三樓有下行請求,四樓無請求,不再往上
{
setDownLight();
FORREV=0;
DOWN_req[3]=0;
STOPCUR=1;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
return 1;
}
}
if(CURFLR==4)//到達(dá)四樓
{
setFloor(4);//顯示數(shù)字
setDownLight();
count=0;
if(DOWN_req[4]==1)//四樓有請求,四樓的請求只用向下的情況
{
DOWN_req[4]=0;
FORREV=0;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
STOPCUR=1;
}
}
}
else//判斷下行是否到達(dá)請求層,下行請求優(yōu)先處理
{
CURFLR--;
setDownLight();//下行等亮
if(CURFLR==1)//到達(dá)一樓
{
setFloor(1);//顯示數(shù)字
count=0;
if(UP_req[1]==1)//一樓有請求,一樓的請求只有向上的情況
{
setUpLight();
UP_req[1]=0;
FORREV=1;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
STOPCUR=1;
}
}
if(CURFLR==2)//到達(dá)二樓
{
setFloor(2);//顯示數(shù)字
count=0;
if(DOWN_req[2]==1)//二樓有下行請求,優(yōu)先處理
{
setDownLight();
DOWN_req[2]=0;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
STOPCUR=1;
return 1;
}
if(UP_req[2]==1&&UP_req[1]==0)//一樓無請求,不再往下
{
setUpLight();
FORREV=1;
UP_req[2]=0;
STOPCUR=1;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
}
}
if(CURFLR==3)//到達(dá)三樓
{
setFloor(3);//顯示數(shù)字
count=0;
if(DOWN_req[3]==1)//三樓有下行請求,優(yōu)先處理
{
setDownLight();
DOWN_req[3]=0;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
STOPCUR=1;
return 1;
}
if(UP_req[1]==0&&DOWN_req[2]==0&&UP_req[2]==0&&UP_req[3]==1)
{
setUpLight();
FORREV=1;
UP_req[3]=0;
STOPCUR=1;
OUTPUT=0x00|(P2&0xf0);//電機(jī)停止
}
}
}//end if-FORREV
return 1;
}
else
{
return 0;
}//end if-count
}
/****************************************/
/* 保存請求 */
/****************************************/
void storeUP(unsigned char x)
{
UP_req[x]=1;
}
void storeDOWN(unsigned char x)
{
DOWN_req[x]=1;
}
/****************************************/
/* 功能函數(shù) */
/****************************************/
//初始化所有燈
void initLights()
{
P0=0x11;
}
//設(shè)置樓層顯示
void setFloor(int floor)
{
switch (floor)
{
case 1:
{
P0&=0xf0;//清零
P0|=0x01;break;
}
case 2:
{
P0&=0xf0;//清零
P0|=0x02;break;
}
case 3:
{
P0&=0xf0;//清零
P0|=0x03;break;
}
case 4:
{
P0&=0xf0;//清零
P0|=0x04;break;
}
default:
{
P0=0x06;break;
}
}
}
//設(shè)置電梯向上運(yùn)行燈
void setUpLight()
{
upLight=1;
downLight=0;
}
//設(shè)置電梯向下運(yùn)行燈
void setDownLight()
{
upLight=0;
downLight=1;
}
//設(shè)置電梯停止運(yùn)行燈
void setStopLight()
{
upLight=0;
downLight=0;
}
//設(shè)置電梯報(bào)警燈和喇叭
void setAlarmLight()
{
//TMOD=0x01;
//TH0=0xDC;TL0=0x00;/*設(shè)置計(jì)時(shí)器的初值DC00H,定時(shí)時(shí)長為10ms*/
//IE=0x82;
//TR0=1;/*開啟定時(shí)器0*/
//EA=1;/*開總中斷*/
int num=0;//循環(huán)次數(shù)
//設(shè)置警告燈亮
//while(num<50&&alarmSwitch)
while(START)
{
num++;
if(!alarmBit)
{
alarmBit=1;
}
else//熄滅警告燈
{
alarmBit=0;
}
time(400);
}
offAlarmLight();
}
//停止報(bào)警燈和喇叭
void offAlarmLight()
{
//alarmSwitch=0;
//time(100);
//EA=0;
//TR0=0;
alarmBit=1;
//alarmSwitch=1;
}
/******************************************/
/* 延時(shí)函數(shù) */
/******************************************/
void delay_5us(void)
{
_nop_();
_nop_();
}
void delay_50us(void)
{
unsigned char i;
for(i=0;i<4;i++)
{
delay_5us();
}
}
void delay_100us(void)
{
delay_50us();
delay_50us();
}
void time(unsigned ucMs)
{
unsigned char j;
while(ucMs>0)
{
for(j=0;j<10;j++)
delay_100us();
ucMs--;
}
}
復(fù)制代碼
所有資料51hei提供下載:
單片機(jī)電梯控制器源文件.rar
(40.88 KB, 下載次數(shù): 142)
2018-10-31 17:13 上傳
點(diǎn)擊文件名下載附件
源代碼
下載積分: 黑幣 -5
作者:
admin
時(shí)間:
2018-10-31 17:29
好東東,仿真工程詳見:
http://www.torrancerestoration.com/bbs/dpj-140197-1.html
作者:
feiji666
時(shí)間:
2018-10-31 17:53
真的好
作者:
wulusai
時(shí)間:
2019-12-9 19:30
太強(qiáng)了
作者:
LDM251621778
時(shí)間:
2020-1-28 15:22
圖很清晰,程序注釋詳細(xì),贊一個(gè)
作者:
4574535565869
時(shí)間:
2024-9-28 14:15
感覺挺不錯
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1