找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1737|回复: 1
收起左侧

新人求助,STC89C52单片机与8155拓展程序

[复制链接]
ID:423814 发表于 2020-4-30 21:24 | 显示全部楼层 |阅读模式
本帖最后由 epoch 于 2020-5-1 19:46 编辑

网上可查阅的资料不多且大多是汇编,没办法
程序取之与51黑,问题也归于此,感谢
仿真可以正常运行,是一个模拟4层电梯运行的程序。
一旦对P2口进行操作程序会出错(会卡住),仿真无法正常运行
仿真如下:
160.008.jpg

程序如下:
/****************程序转自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;                //当前电梯状态
uchar statepre;                //之前电梯状态
uchar flag;                //电梯上下标志,0下,1上
bit flag1;                //定时时间到标志
uchar counter;                //计数器
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)           //简单延时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;                        //被按下后标记,亮灯,下同
                                

                                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;          //启动定时器T0
}
void run(){
                iniclock();                        //开定时
                while(~flag1){                //时间未到扫描键盘
                        keyscan();
                        display();
                }
                flag1=0;                        //时间到了,清标志位,关定时器
                TR0=0;
                ET0=0;
}
void main()
{
                 state=1;
                statepre=1;
                flag=1;
                flag1=0;
                COM=0x43;                        //intialize 8155
                TMOD=0x01;                   //定义定时器0/1为定时器模式
                EA=1;                                  //开总中断


                while(1){
                        switch(state){                                //扫描电梯所在位置
                                case(1):{
        
                                        if(state!=statepre){        //上次的状态和本次不一样说明电梯 需要开门
                                                lopen=0;
                                                run();                        //按键扫描三秒钟
                                                lopen=1;
                                                in1=0;                //如果in1和up1被按下则无效
                                       
                                                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;                        //说明上行
                                                run();                                //按键扫描三秒钟
                                                state=2;                        //更新状态
                                                statepre=1;

                                                
                                        }
                                        else{
                                                statepre=state;
                        flag=2;
                                                keyscan();
                                                display();
                                        }
                                        break;
                                }
                                case(2):{                                          //电梯到2楼
               
                                        if(state!=statepre)
                    {                          //如果前后两次状态不一样则可能需要开门
                             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被按下则无效
                                                
                                                                if(flag==1){                        //如果上行,电梯外上行指示灯按下无效
                                                                up2=0;
                                                                lup2=1;
                                                                }
                                                                else{                                //如果下行,电梯外下行指示灯按下无效
                                                                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)
                    {                          //如果前后两次状态不一样则可能需要开门
                             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被按下则无效
                                                
                                                                if(flag==1){                        //如果上行,电梯外上行指示灯按下无效
                                                                up3=0;
                                                                lup3=1;
                                                                }
                                                                else{                                //如果下行,电梯外下行指示灯按下无效
                                                                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被按下则无效
                                       
                                                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;                                //说明下行
                                                run();
                                                state=3;                        //更新状态
                                                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++;                   //定时器中断次数加1

        if(counter==60)         //三秒钟执行一次
        {
                counter=0;
                        flag1=1;          //三秒钟定时到标志
        }
}
回复

使用道具 举报

ID:423814 发表于 2020-5-1 19:44 | 显示全部楼层
更正P3口功能正常,只有单片机P2口有问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表