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);
}
}