电梯演示系统设计
文章目录
背景
本次设计采用 Ubuntu18.04.4-x64 +GEC6818开发板设计开发
学习步骤如下:
所需的linux的基本知识:
命令:https://blog.csdn.net/weixin_51165960/article/details/126781536
函数:https://blog.csdn.net/weixin_51165960/article/details/126916855
bmp文件和开发板上显示图片的学习:
https://blog.csdn.net/weixin_51165960/article/details/126917209
电梯界面设计和触摸屏的学习:
https://blog.csdn.net/weixin_51165960/article/details/126917828
创建广告循环播放线程的学习:
https://blog.csdn.net/weixin_51165960/article/details/126918074
总体设计
1.设备初始化
2.显示初始化界面
3.创建一个线程循环播放广告
4.创建一个线程获取按下的楼层
5.分析按下某一楼层后,当前所在楼层上下合剩下多少楼层需要到达
6.电梯运行,显示当前到达的楼层和向上向下运行箭头
7.每到达一层楼,暂停一秒,表示乘客进出电梯
8.分析到达后,当前所在楼层上下合剩下多少楼层需要到达,若没有需要到达的楼层,则运行箭头小时,电梯运行停止。
9.设备解除初始化
详细设计:
0.设计中所用的bmp.h bmp.c touch.h touch.c main.c介绍
bmp.h:定义一个bmp图片信息相关的结构体类型和所需有关屏幕初始化和其他有关图片显示的函数。
//定义一个bmp图片信息相关的结构体类型
typedef struct BMP
{
char* bmpname; //保存bmp图片的名称
int size; //文件的总大小
int width; //文件的宽
int height; //文件的高
short bpp; //色深
char* data; //像素数组的首地址
}BMP;
//屏幕初始化
void lcd_init();
//解除屏幕初始化
void lcd_uninit();
//画点
void lcd_point(int x,int y,int color);
//获取bmp图片信息
BMP get_bmp_info(char* bmpname);
//画一张bmp图片
void lcd_draw_bmp(char* bmpname, int x, int y);
bmp.c:对bmp.h各个方法的具体实现。
touch.h:定义有关触摸屏的初始化及其他方法所需的函数。
//初始化触摸屏
void touch_init();
//解除触摸屏初始化
void touch_uninit();
//获取触摸点坐标 x表示触摸点的横坐标 y表示触摸点的纵坐标
void get_xy(int* x, int* y);
//获取手指离开开发板时的坐标
void get_xy1(int* x, int* y);
touch.c:对touch.c中各个方法的具体实现。
mian.c:
定义几个全局变量和数组
int j[10]={0};//用来标识楼层是否被按下
int nowf= 1; //当前楼层
int h_num = 0; //当前楼层上面有几个楼层被按下
int l_num = 0; //当前楼层下面有几个楼层被按下
char *onbmp[10]={"001.bmp","002.bmp","003.bmp","004.bmp","005.bmp","006.bmp","007.bmp","008.bmp","009.bmp","010.bmp",};//灭
char *keybmp[10]={"01.bmp","02.bmp","03.bmp","04.bmp","05.bmp","06.bmp","07.bmp","08.bmp","09.bmp","10.bmp",};//灭
char *numbmp[10]={"1.bmp","2.bmp","3.bmp","4.bmp","5.bmp","6.bmp","7.bmp","8.bmp","9.bmp","0010.bmp",};//数字
int x7,y7;//x7用于保存对应楼层计算后的对应结果(非坐标);y7用于保存对应楼层计算后的对应结果(坐标)//y0是个内建函数
int x;//触摸的点x坐标
int y;//触摸的点y坐标
调用bmp.c和touch.c中的方法和其他设计实现电梯运行系统演示。
1.设备初始化
初始化设备:
//初始化显示屏
lcd_init();
//初始化触摸屏
touch_init();
2.显示初始化界面
定义一个showbmp()用于显示初始化界面:
//启动进入界面
showbmp();
void showbmp()
{
//在屏幕上显示一张图片
lcd_draw_bmp("./main.bmp",0,0);
sleep(5);
lcd_draw_bmp("./bg3.bmp",0,0);
lcd_draw_bmp("./01.bmp",600,0);
lcd_draw_bmp("./02.bmp",700,0);
lcd_draw_bmp("./03.bmp",600,96);
lcd_draw_bmp("./04.bmp",700,96);
lcd_draw_bmp("./05.bmp",600,192);
lcd_draw_bmp("./06.bmp",700,192);
lcd_draw_bmp("./07.bmp",600,288);
lcd_draw_bmp("./08.bmp",700,288);
lcd_draw_bmp("./09.bmp",600,384);
lcd_draw_bmp("./10.bmp",700,384);
lcd_draw_bmp(numbmp[nowf-1],200,120);//显示初次所在楼层,因nowf初始为1,故初次显示在一楼
}
3.创建一个线程循环播放广告
定义一个广告循环线程:
void* ad(void* arg)//广告循环
{
char *adbmp[2]={"ad1.bmp","ad2.bmp"};
int i=0;
while(1)
{
lcd_draw_bmp(adbmp[i++], 0,0);
sleep(3);
if(i==2)
i=0;
}
}
4.创建一个线程获取按下的楼层
(1)
获取按下的位置X,Y并转化为对应楼层的数值n
通过analyz()解析出n楼层对应位置的图片的写入点X7,Y7,以便修改按键的显示状态
(2)
通过修改数组j中的值的0、1状态(标志位)来表示对应按键是否被按下。0表示未被按下,1表示被按下。
(3)
当按下的楼层为当前楼层时,楼层按键显示先亮后灭,不修改对应j数组中的标志。电梯不运行。
(4)
当按下的楼层不为当前楼层时,修改对应j数组中的标志,调用fenxi()分析上下有多少楼层需要到达,同时所按楼层按键变亮。
(5)
当按下的楼层标志位已经是1时(即已经被按下,需要到达),再次按下修改标志位为0(表示不再需要去到达)同时依然调用fenxi()分析。
void* run(void* arg)
{
int x1;//用于计算按下的楼层位置(非坐标)
int y1;//用于计算按下的楼层位置(坐标)
int n;
printf("进入按键判断\n");
while(1)
{
get_xy1(&x,&y);
printf("获取坐标值了\n");
x=(x*800)/1024;
y=(y*480)/600;
printf("x=%d y=%d\n",x,y);
if(x>=600&&x<700&&y>=0&&y<96)
n=1;
if(x>=700&&x<800&&y>=0&&y<96)
n=2;
if(x>=600&&x<700&&y>=96&&y<192)
n=3;
if(x>=700&&x<800&&y>=96&&y<192)
n=4;
if(x>=600&&x<700&&y>=192&&y<288)
n=5;
if(x>=700&&x<800&&y>=192&&y<288)
n=6;
if(x>=600&&x<700&&y>=288&&y<384)
n=7;
if(x>=700&&x<800&&y>=288&&y<384)
n=8;
if(x>=600&&x<700&&y>=384&&y<480)
n=9;
if(x>=700&&x<800&&y>=384&&y<480)
n=10;
printf("当前按下的是%d\n",n);
analyz(n);
if(j[n-1]==0)
{
if(nowf==n)
{
if(x7==1)
{
lcd_draw_bmp(onbmp[n-1], 600,y7);//对应楼层亮
sleep(1);
lcd_draw_bmp(keybmp[n-1], 600,y7);//对应楼层灭
}
if(x7==0)
{
lcd_draw_bmp(onbmp[n-1], 700,y7);//对应楼层亮
sleep(1);
lcd_draw_bmp(keybmp[n-1], 700,y7);//对应楼层灭
}
}
if(nowf!=n)
{
j[n-1]=1;
fenxi();
if(x7==1)
{
lcd_draw_bmp(onbmp[n-1], 600,y7);//对应楼层亮
}
if(x7==0)
{
lcd_draw_bmp(onbmp[n-1], 700,y7);//对应楼层亮
}
}
}
else
{
//取消楼层
j[n-1]=0;
if(x7==1)
{
lcd_draw_bmp(keybmp[n-1], 600,y7);//对应楼层灭
}
if(x7==0)
{
lcd_draw_bmp(keybmp[n-1], 700,y7);//对应楼层灭
}
fenxi();
}
n=0;
}
}
5.分析按下某一楼层后,当前所在楼层上下合剩下多少楼层需要到达
通过循环遍历数组从当前位置到最高和最低之间有多少个1(即有多少楼层按键被按下)。用h_num表示上面还有少楼层要达到,用l_num表示下面还有少楼层要达到。
void fenxi()//上下还有多少楼层分析函数
{
int nowftemp;
nowftemp=nowf;
int *p=j;
int h_n = 0, l_n = 0;
for (int i = nowftemp; i < 11; i++)//当前楼层上面有几个楼层被按下
{
if (p[i-1] == 1)
{
h_n++;
}
}
for (int i = nowftemp; i > 0; i--)//当前楼层下面有几个楼层被按下
{
if (p[i-1] == 1)
{
l_n++;
}
}
h_num = h_n;
l_num = l_n;
printf("分析:现在在:%d\n",nowf);
printf("分析:上面有:%d 下面有%d\n",h_num,l_num);
}
6.电梯运行,显示当前到达的楼层和向上向下运行箭头
电梯向上运行:
(1)
通过判断h_num值是非为零判断电梯是非需要运行,若需要则nowf++,表示电梯在往上运行。同时显示向上运行图标和当前楼层
(2)
当到达需到达的楼层时,延时一秒表示开门,更新j数组的值,通过analyz()解析出当前楼层对应位置的图片的写入点X7,Y7,更新当前按键的状态。
(3)
到达一层后h_num的值减一,并调用fenxi()分析。
(4)
延时一秒表示电梯往上运行
(5)
当到达最高需到达的楼层时,刷新中间的显示屏幕以便去掉屏幕的向上箭头,并显示当前的楼层。
while(1)
{
//电梯向上运行
for (; h_num != 0; nowf++)
{
printf("电梯运行中现在是在:%d层\n",nowf);
printf("电梯运行中上面还有 %d层\n",h_num);
//在屏幕中间显示向上的箭头和当前楼层
lcd_draw_bmp("up.bmp",200,0);
lcd_draw_bmp(numbmp[nowf-1],200,120);
if (j[nowf-1] == 1)
{
//播放相应的提示语言
//延时一下, 表示开门
sleep(1);
//更新数组中的标识位
j[nowf-1]=0;
//刷新屏幕上的按键情况
analyz(nowf);
x1=x7;
y1=y7;
printf("x1=%d y1=%d\n",x1,y1);
if(x1==1)
{
lcd_draw_bmp(keybmp[nowf-1], 600,y1);//到了对应楼层灭
}
if(x1==0)
{
lcd_draw_bmp(keybmp[nowf-1], 700,y1);//到了对应楼层灭
}
h_num--;
fenxi();
}
//延时一下, 表示正在上楼
sleep(1);
if (h_num == 0)
{
//去掉屏幕中间向上的箭头
//1. 只刷新屏幕中间的区域, 然后显示当前楼层
printf("现在在:%d\n",nowf);
lcd_draw_bmp("refresh.bmp", 200,0);
lcd_draw_bmp(numbmp[nowf-1],200,120);
break;
//2. 将整个界面都刷新一遍
电梯向下运行亦是如此。
7.设备解除初始化
结果:
电梯运行到第7层:
附上整个项目的开发文件压缩包:https://download.csdn.net/download/weixin_51165960/86543461
完结。