|
本帖最后由 epoch 于 2020-5-1 19:46 編輯
網(wǎng)上可查閱的資料不多且大多是匯編,沒辦法 。
程序取之與51黑,問題也歸于此,感謝
仿真可以正常運(yùn)行,是一個(gè)模擬4層電梯運(yùn)行的程序。
一旦對(duì)P2口進(jìn)行操作程序會(huì)出錯(cuò)(會(huì)卡住),仿真無(wú)法正常運(yùn)行
仿真如下:
160.008.jpg (75.24 KB, 下載次數(shù): 40)
下載附件
2020-4-30 21:12 上傳
程序如下:
/****************程序轉(zhuǎn)自51黑論壇***********************/
#include "reg52.h"
#include "absacc.h"
#define uint unsigned int
#define uchar unsigned char
#define COM XBYTE[0xFF20] //定義8155地址
#define PA XBYTE[0xFF21]
#define PB XBYTE[0xFF22]
#define PC XBYTE[0xFF23]
sbit lup1=P1^0; //L1 //定義led控制端口
sbit lup2=P1^1; //L2
sbit ldown2=P1^2; //L3
sbit lup3=P1^3; //L4
sbit ldown3=P1^4; //L5
sbit ldown4=P1^5; //L6
sbit lopen=P1^7; //L8
sbit IN1=P2^1; //motor
sbit IN2=P2^2;
sbit ENA=P2^3;
uchar state; //當(dāng)前電梯狀態(tài)
uchar statepre; //之前電梯狀態(tài)
uchar flag; //電梯上下標(biāo)志,0下,1上
bit flag1; //定時(shí)時(shí)間到標(biāo)志
uchar counter; //計(jì)數(shù)器
bit in1=0, in2=0, in3=0, in4=0, up1=0, up2=0, up3=0, down2=0, down3=0, down4=0; //KEY
uchar code table[]={0xf9, 0xa4,0xb0,0x99, 0xa1, 0xc1, 0xff}; //樓層顯示碼表,一共是四層 0xc1=u
void delay(uint xms) //簡(jiǎn)單延時(shí)0.1ms
{
uint o,j;
for(o=xms;o>0;o--)
for(j=11;j>0;j--);
}
/***********************************************************/
void Positive_Rotation()
{
IN1 = 0;
IN2 = 1;
}
void Reverse_Rotation()
{
IN1 = 1;
IN2 = 0;
}
void Stop_Rotation()
{
IN1 = 1;
IN2 = 1;
}
void display(){
PB=0xff;
PA=0xfe;
PB=table[state-1];
delay(2);
PB=0xff;
PA=0xfd;
PB=table[flag+4];
delay(2);
}
void keyscan(){ //掃描鍵盤
uchar pctemp;
PB=0xff;
PA=~0x01; //PA0口輸出低電平
pctemp=PC;
switch(pctemp&0x0f){ //PC高位置0
case(0x0e):{
in1=1; //被按下后標(biāo)記,亮燈,下同
break;
}
case(0x0d):{
in2=1;
break;
}
case(0x0b):{
in3=1;
break;
}
case(0x07):{
in4=1;
break;
}
default: break;
}
PA=~0x02; //PA1口低電平掃描第二行
delay(1);
pctemp=PC;
switch(pctemp&0x0f){
case(0x0e):{
up1=1;
lup1=0;
break;
}
case(0x0d):{
up2=1;
lup2=0;
break;
}
case(0x0b):{
up3=1;
lup3=0;
break;
}
default: break;
}
PA=~0x04;
delay(1); //PA2口低電平掃描第三行
pctemp=PC;
switch(pctemp&0x0f){
case(0x0d):{
down2=1;
ldown2=0;
break;
}
case(0x0b):{
down3=1;
ldown3=0;
break;
}
case(0x07):{
down4=1;
ldown4=0;
break;
}
default: break;
}
}
void iniclock() //start clock
{
TH0=60; //TH0=(65536-50000)/256 TL0=(65536-50000)%256 50ms初值
TL0=176;
ET0=1; //T0中斷允許
TR0=1; //啟動(dòng)定時(shí)器T0
}
void run(){
iniclock(); //開定時(shí)
while(~flag1){ //時(shí)間未到掃描鍵盤
keyscan();
display();
}
flag1=0; //時(shí)間到了,清標(biāo)志位,關(guān)定時(shí)器
TR0=0;
ET0=0;
}
void main()
{
state=1;
statepre=1;
flag=1;
flag1=0;
COM=0x43; //intialize 8155
TMOD=0x01; //定義定時(shí)器0/1為定時(shí)器模式
EA=1; //開總中斷
while(1){
switch(state){ //掃描電梯所在位置
case(1):{
if(state!=statepre){ //上次的狀態(tài)和本次不一樣說(shuō)明電梯 需要開門
lopen=0;
run(); //按鍵掃描三秒鐘
lopen=1;
in1=0; //如果in1和up1被按下則無(wú)效
up1=0;
lup1=1;
}
else{
if(up1){
up1=0;
lup1=1;
lopen=0;
run();
lopen=1;
}
}
in1=0;
if(up2|down2|up3|down3|down4|in2|in3|in4){
flag=1; //說(shuō)明上行
run(); //按鍵掃描三秒鐘
state=2; //更新狀態(tài)
statepre=1;
}
else{
statepre=state;
flag=2;
keyscan();
display();
}
break;
}
case(2):{ //電梯到2樓
if(state!=statepre)
{ //如果前后兩次狀態(tài)不一樣則可能需要開門
if(!(
((flag==1)&&(in3|up3|down3)&&(~up2)&&(~in2)) //去三樓
||((flag==1)&&(in4|down4)&&(~up2)&&(~in2)) //去四樓
||((flag==0)&&(in1||up1)&&(~down2)&&(~in2)) //去一樓
)
)
{
lopen=0;
run(); //按鍵掃描三秒鐘
lopen=1;
in2=0; //如果in2被按下則無(wú)效
if(flag==1){ //如果上行,電梯外上行指示燈按下無(wú)效
up2=0;
lup2=1;
}
else{ //如果下行,電梯外下行指示燈按下無(wú)效
down2=0;
ldown2=1;
}
}
}
else{ //在二樓停
if(down2|up2){
down2=0;
up2=0;
lopen=0;
run();
lopen=1;
ldown2=1;
lup2=1;
}
}
in2=0;
if(flag)
up2=0;
else
down2=0;
if(flag==1){
if(down3|in3|up3|down4|in4){
flag=1;
run();
state=3;
statepre=2;
}
else if(in1|up1){
flag=0;
run();
state=1;
statepre=2;
}
else{
statepre=state;
flag=2;
keyscan();
display();
Stop_Rotation();
}
}
else {
if(up1|in1){
flag=0;
run();
state=1;
statepre=2;
}
else if(in3|down3|up3|in4|down4){
flag=1;
run();
state=3;
statepre=2;
}
else{
statepre=state;
flag=2;
keyscan();
display();
}
}
break;
}
case(3):{ //電梯到3樓
if(state!=statepre)
{ //如果前后兩次狀態(tài)不一樣則可能需要開門
if(!(
((flag==0)&&(in2|up2|down2)&&(~up3)&&(~in3)) //去二樓
||((flag==1)&&(in4|down4)&&(~up3)&&(~in3)) //去四樓
||((flag==0)&&(in1||up1)&&(~down3)&&(~in2)) //去一樓
)
)
{
lopen=0;
run(); //按鍵掃描三秒鐘
lopen=1;
in3=0; //如果in3被按下則無(wú)效
if(flag==1){ //如果上行,電梯外上行指示燈按下無(wú)效
up3=0;
lup3=1;
}
else{ //如果下行,電梯外下行指示燈按下無(wú)效
down3=0;
ldown2=1;
}
}
}
else{ //在三樓停
if(down3|up3){
down3=0;
up3=0;
lopen=0;
run();
lopen=1;
ldown3=1;
lup3=1;
}
}
in3=0;
if(flag)
up3=0;
else
down3=0;
if(flag==1){
if(down4|in4){
flag=1;
run();
state=4;
statepre=3;
}
else if(in1|up1|in2|up2|down2){
flag=0;
run();
state=2;
statepre=3;
}
else{
statepre=state;
flag=2;
keyscan();
display();
}
}
else {
if(up1|in1|up2|in2|down2){
flag=0;
run();
state=2;
statepre=3;
}
else if(in4|down4){
flag=1;
run();
state=4;
statepre=3;
}
else{
statepre=state;
flag=2;
keyscan();
display();
}
}
break;
}
case(4):{ //case4和case1類似
keyscan();
display();
if(state!=statepre){
lopen=0;
run();
lopen=1;
in4=0; //如果in4和down4被按下則無(wú)效
down4=0;
ldown4=1;
}
else{
if(down4){
down4=0;
ldown4=1;
lopen=0;
run();
lopen=1;
}
}
in4=0;
if(in1|up1|up2|down2|in2|in3|up3|down3){
flag=0; //說(shuō)明下行
run();
state=3; //更新狀態(tài)
statepre=4;
}
else{
statepre=state;
flag=2;
keyscan();
display();
}
break;
}
default: break;
}
}
}
void T0_time()interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //重賦初值
counter++; //定時(shí)器中斷次數(shù)加1
if(counter==60) //三秒鐘執(zhí)行一次
{
counter=0;
flag1=1; //三秒鐘定時(shí)到標(biāo)志
}
}
|
|