单片机作业:期中


title: 单片机作业:期中
date: 2020-04-04 13:24:30
tags:
- 单片机作业
- C语言
categories:
- 单片机作业
summary: 控制某运动工作台沿轴向运动,有前进和后退两个方向。


功能要求:

1.控制某运动工作台沿轴向运动,有前进和后退两个方向。

2.控制系统设计有三个按钮:一个是模式切换按钮,一个是“foward”按键,一个是“backward”按键。

3.工作台两端设计各设计安排一个限位传感器。

4.系统有2种控制模式:

一种是点动控制,即“foward”按键按下时工作台前进动作,放手即停;“backward”按键按下时工作台后退动作,放手即停。

第二种是自动动控制,即“foward”工作台前进/停止复用按键;“backward”工作台后退/停止复用按键。

第三种是往复循环模式,即自动在两限位之间循环动作,“foward”按键作为启动按键,按下后工作台前进动作,遇到右侧限位自动反转运行,直到遇到左侧限位,然后又反向运行,如此往复运动,“backward”按键作为停止按键,按下后循环运动停止。

5.液晶显示系统工作状态,界面自拟。

6.电机在运动时不得切换控制模式。

思考

这题的主要难点就是怎么将一颗按钮用于三种用途?
目前的想法是将原有的一颗键上的flag用一个循环,使之有三种功能:例如flag=0时干什么;flag=1时做什么;flag=2时做什么;这样就需要一个num来做循环,num++来实现,0到2的循环;
这就有两种方式了,如下:

第一种:for(num==0 ;num<3;num++)

第二种:while(1)
        {
            num++;
            if(num=3)
            num=0;
        }
    

按照上面的两种方式就可以解决掉所有问题了,其余的就自己看代码吧!

具体过程代码:

#include<reg51.h>
#include<1602lcd.h>
sbit signal1=P1^0; 
sbit signal2=P1^1;  // control port
sbit forward=P1^2;
sbit backward=P1^3;  //  two keys
sbit control_mode=P1^4;
sbit limit_l=P3^2;
sbit limit_r=P3^3;

unsigned char md[]={"mode:"};      //mode
unsigned char st[]={"status:"};    //状态
unsigned char au[]={"auto"};
unsigned char ma[]={"manu"};
unsigned char fd[]={"fowd"};
unsigned char stp[]={"stop"};
unsigned char bk[]={"back"};
unsigned char lp[]={"loop"};

int num;

bit status=0;      //status=1 表示在动   =0  停止
bit mode_flag;
bit fwd_flag;
bit bak_flag;
bit limit_l_flag;
bit limit_r_flag;
bit limit_flag;

void scan_key();
void out_put();
void check_limit();
void check_limit1();

void main()
{
    lcd_init();
    lcd_pos(1,1);
    lcdwrite_string(md);
    lcd_pos(1,7);    
    lcdwrite_string(ma);
    lcd_pos(2,1);
    lcdwrite_string(st);
    lcd_pos(2,9);
    lcdwrite_string(stp);

    while(1)
    {
      scan_key();
      out_put();
      
    }
}

void scan_key()     //z单键复用
{   
    if(control_mode==0 && status==0)
    {
        num++;
        if(num==3)      
            num=0;   
        while(control_mode==0);

        if(num==0)       //手动
        {
            lcd_pos(1,7);
            lcdwrite_string(ma);        
        }
        if(num==1)       //自动
        {
            lcd_pos(1,7);
            lcdwrite_string(au);        
        }
        if(num==2)          //循环
        {       
            lcd_pos(1,7);
            lcdwrite_string(lp);        
        }
        
    }
}

void out_put()
{
     if(num==1)  //auto
     {
          if(forward==0 && bak_flag==0 && limit_r_flag==0 )
          {
            fwd_flag=~fwd_flag;
            if(fwd_flag==1)
            {
                lcd_pos(1,16);
                lcdwrite_zm(' ');
                lcd_pos(2,9);
                lcdwrite_string(fd);
                signal1=1;
                signal2=0;
                status=1;
                limit_l_flag=0;
            }
            else
            {
                lcd_pos(1,16);
                lcdwrite_zm(' ');
                lcd_pos(2,9);
                lcdwrite_string(stp);
                signal1=1;
                signal2=1;
                status=0;                             
            } 
            while(forward==0);
          }
         else if(backward==0 && fwd_flag==0 && limit_l_flag==0 )
          {
            bak_flag=~bak_flag;
            if(bak_flag==1)
            {
                lcd_pos(1,16);
                lcdwrite_zm(' ');
                lcd_pos(2,9);
                lcdwrite_string(bk);
                signal1=0;
                signal2=1;
                status=1;
                limit_r_flag=0;
            }
            else
            {
                lcd_pos(1,16);
                lcdwrite_zm(' ');
                lcd_pos(2,9);
                lcdwrite_string(stp);
                signal1=1;
                signal2=1;
                status=0;                             
            } 
          while(backward==0);
          }
          check_limit();    
     }
  else if(num==0)        //manu
    {
          if(forward==0 && limit_r_flag==0)
          {
            lcd_pos(1,16);
            lcdwrite_zm(' ');

            lcd_pos(2,9);
            lcdwrite_string(fd);
            signal1=1;
            signal2=0;
            status=1;
            limit_l_flag=0;         
          }
         else if(backward==0 && limit_l_flag==0)
          {
            lcd_pos(1,16);
            lcdwrite_zm(' ');

            lcd_pos(2,9);
            lcdwrite_string(bk);
            signal1=0;
            signal2=1;
            status=1;
            limit_r_flag=0;
          }
          else
          {
            lcd_pos(1,16);
            lcdwrite_zm(' ');

            lcd_pos(2,9);
            lcdwrite_string(stp);
            signal1=1;
            signal2=1;
            status=0;
          }
          check_limit();
    }
    else if(num==2)
    {   
        if(forward==0 && status==0)
        {
            lcd_pos(1,16);
            lcdwrite_zm(' ');
            lcd_pos(2,9);
            lcdwrite_string(fd);

            signal1=1;
            signal2=0;
            status=1;

            if(limit_r==0)
            {
                limit_flag=1;
                signal1=0;
                signal2=1;
                status=1;
            //有极限,触发后退
                lcd_pos(1,16);
                lcdwrite_zm('r');
                lcd_pos(2,9);
                lcdwrite_string(bk);
                if(limit_l==0)
                {
                    limit_flag=1;
                    signal1=1;
                    signal2=0;
                    status=1;
                //左极限,触发前进
                    lcd_pos(1,16);
                    lcdwrite_zm('l');
                    lcd_pos(2,9);
                    lcdwrite_string(fd);
                }
            }
        }
        else if(backward==0)
        {
            lcd_pos(1,16);
            lcdwrite_zm(' ');
            lcd_pos(2,9);
            lcdwrite_string(stp);
            
            signal1=1;
            signal2=1;
            status=0;
        }
        check_limit1();
    }
}

void check_limit()
{
    if(limit_l==0)
    {
        limit_l_flag=1; //左限制
        signal1=1;
        signal2=1;
        status=0;
        fwd_flag=0;
        bak_flag=0;

        lcd_pos(1,16);
        lcdwrite_zm('l');
        lcd_pos(2,9);
        lcdwrite_string(stp);
        
    }
    if(limit_r==0)
    {
        limit_r_flag=1;  //右限制
        signal1=1;
        signal2=1;
        status=0;
        fwd_flag=0;
        bak_flag=0;

        lcd_pos(1,16);
        lcdwrite_zm('r');
        lcd_pos(2,9);
        lcdwrite_string(stp);       
    }
}

void check_limit1()
{
    if(limit_l==0)
    {
        signal1=1;
        signal2=0;
        status=1;
    //左极限,触发前进
        lcd_pos(1,16);
        lcdwrite_zm('l');
        lcd_pos(2,9);
        lcdwrite_string(fd);
        
    }
    if(limit_r==0)
    {
        signal1=0;
        signal2=1;
        status=1;
    //右极限,触发后退
        lcd_pos(1,16);
        lcdwrite_zm('r');
        lcd_pos(2,9);
        lcdwrite_string(bk);        
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容