功能实现伪代码
//大家可以参考一下大致实现过程
int floor_num[10] = {0}; //0表示楼层按键熄灭,1表示楼层按键点亮,10个元素对应10层楼
int cuccent_floor = 1; //当前楼层,默认在1楼
int floor_flag = 0; //电梯运行标记 0表示停止,1表示向上,-1表示向下
int h_num = 0; //当前楼层上面有多少楼层按键被按下了、
int l_num = 0; //当前楼层下面有多少楼层按键被按下了int main()
{
设备初始化
显示一个项目的进入界面或开机动画
创建一个线程用于播放广告
创建一个线程用于接受所按楼层信息并记录
{
while(1)
{
获取楼层信息(根据触摸屏按键,来判断是按下那个楼层)
当前楼层不获取
更新楼层数组中保存的标识符floor_num[]
更新屏幕上的按键
int h_n = 0, l_n = 0;
for(int i = curren_foor+1; i < 11; i++)
{
if(floor_num[i-1] == 1)
h_n++; //记录当前楼层上面有多少楼层的按键被按下了
}
//记录当前楼层下面有多少楼层的按键被按下了 类比推导//加锁
h_num = h_n; l_num = l_n;
//解锁
}
}
对记录的数据进行处理 ---> 电梯开始运行
while(1)
{
if(floor_flag == 0) //电梯停止
{
if(h_num > 0) //电梯有向上的请求
{
floor_flag = 1;
}
eles if(l_num > 0) //电梯有向下的请求
{
floor_flag = -1;
}
}
//电梯向上运行
if(floor_flag == 1)
{
for(; h_num != 0; current_floor++)
{
在屏幕中间显示当前楼层及向上的箭头
//如果当前楼层就是被按下的楼层
if(floor_num[current_floor-1] == 1)
{
播放相应的提示语音/显示一张提示图片
延时一下,表示开门
更新楼层数组floor_num中的标志位
刷新屏幕中的按键情况(熄灭当前楼层对应的按键)
//加锁
h_num--;
//解锁
}
//延时一下,表示上楼
//当到达按下的最高楼层
if(h_num == 0)
{
去掉屏幕中间的向上的箭头
if(l_num == 0) //电梯没有向下的请求
{
floor_flag = 0; //电梯停止
}
else if(l_num > 0) //电梯有向下的请求
{
floor_flag = -1; //电梯向下
}
}
}
}
//电梯向下运行。。。。。
if(floor_flag == -1)
.......
}
}
"以下有关lcd的代码请参考2048项目中实现方法"
main.c
头文件及定义
#include "touch.h"
#include "lcd.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <semaphore.h>
#include <stdbool.h>
#include <string.h>
#include <sys/wait.h>
#define FIFONAME "/home/work/elevator/vedio.fifo"
//定义一个互斥锁
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
struct array
{
int x;//楼层按钮左上角的横坐标
int y;//楼层按钮左上角的纵坐标
bool flag;//0标识楼层未被按下或到达相应楼层, 1标识楼层被按下
}array[10];
int now = 1;//表示当前楼层
int target = 0;//表示目标楼层
int h_num = 0;//表示当前楼层上面有几个楼层被按下
int l_num = 0;//表示当前楼层下面有几个楼层被按下
int fd = -1; //用于创建管道文件
char TTime[20] = {0}; //保存管道文件里的信息
int vedio = 0;
char* ad[] ={"./advertising.bmp","./ad1"};//左边广告图片
char* bmp[10] ={"./1.bmp","./2.bmp","./3.bmp","./4.bmp","./5.bmp","./6.bmp","./7.bmp","./8.bmp","./9.bmp","./10.bmp"};//中间按钮图标
char* bmp1[10] ={"./01.bmp","./02.bmp","./03.bmp","./04.bmp","./05.bmp","./06.bmp","./07.bmp","./08.bmp","./09.bmp","./010.bmp"};//白按钮图标
char* bmp2[10] ={"./001.bmp","./002.bmp","./003.bmp","./004.bmp","./005.bmp","./006.bmp","./007.bmp","./008.bmp","./009.bmp","./0010.bmp"};//黄按钮图标
char* mp4[] = {"1.mp4"}; //左边视频
创建有名管道来传输数据,将slave命令写入管道文件。
int create_FIFO()
{
//创建有名管道
int ret = mkfifo(FIFONAME, 0664);
if(ret == -1 && errno != EEXIST)
{
perror("mkfifo error");
return -1;
}
}
//把slave命令写入管道文件
int slave_write_cmd(int fifo_fd,char *cmd)
{
fd = open(FIFONAME, O_WRONLY);
write(fd,cmd,strlen(cmd));
close(fd);
return 0;
}
初始化页面
//电梯按键初始化,坐标和标志位
void array_init()
{
array[0].x = 600;
array[0].y = 384;
array[0].flag = 0;
array[1].x = 700;
array[1].y = 384;
array[1].flag = 0;
array[2].x = 600;
array[2].y = 288;
array[2].flag = 0;
array[3].x = 700;
array[3].y = 288;
array[3].flag = 0;
array[4].x = 600;
array[4].y = 192;
array[4].flag = 0;
array[5].x = 700;
array[5].y = 192;
array[5].flag = 0;
array[6].x = 600;
array[6].y = 96;
array[6].flag = 0;
array[7].x = 700;
array[7].y = 96;
array[7].flag = 0;
array[8].x = 600;
array[8].y = 0;
array[8].flag = 0;
array[9].x = 700;
array[9].y = 0;
array[9].flag = 0;
}
根据按下的坐标区域返回楼层数,display显示对应图片。
int eve()
{
int e = -1; //按下的楼层数
int x = -1,y = -1;
get_touch_xy_down(&x,&y);
x /= 1.28;
y /= 1.25;
if(x >= 600 && x <= 700 && y >= 0 && y <= 96)
{
e = 9;
}
else if(x >= 700 && x <= 800 && y >= 0 && y <= 96)
{
e = 10;
}
else if(x > 600 && x < 700 && y > 96 && y < 192)
{
e = 7;
}
else if(x > 700 && x < 800 && y > 96 && y < 192)
{
e = 8;
}
else if(x > 600 && x < 700 && y > 192 && y < 288)
{
e = 5;
}
else if (x > 700 && x < 800 && y > 192 && y < 288)
{
e = 6;
}
else if(x > 600 && x < 700 && y > 288 && y < 384)
{
e = 3;
}
else if (x > 700 && x < 800 && y > 288 && y < 384)
{
e = 4;
}
else if(x > 600 && x < 700 && y > 384 && y < 480)
{
e = 1;
}
else if (x > 700 && x < 800 && y > 384 && y < 480)
{
e = 2;
}
return e;
}
void display(void)
{
lcd_draw_bmp(600,384,bmp1[0]);
lcd_draw_bmp(700,384,bmp1[1]);
lcd_draw_bmp(600,288,bmp1[2]);
lcd_draw_bmp(700,288,bmp1[3]);
lcd_draw_bmp(600,192,bmp1[4]);
lcd_draw_bmp(700,192,bmp1[5]);
lcd_draw_bmp(600,96,bmp1[6]);
lcd_draw_bmp(700,96,bmp1[7]);
lcd_draw_bmp(600,0,bmp1[8]);
lcd_draw_bmp(700,0,bmp1[9]);
}
三个线程的实现函数分别是:检测到达的楼层并刷新图标,按键按下和再次按下的图标改变,和保存楼层上面或下面有多少层数的函数
//检测到达的楼层并刷新楼层图标
void* flash_lcd(void* f)
{
while(1)
{
if(array[now - 1].flag) //按下了该楼层
{
switch (now)
{
case 1:
lcd_draw_bmp(600,384,bmp1[now - 1]);
break;
case 2:
lcd_draw_bmp(700,384,bmp1[now - 1]);
break;
case 3:
lcd_draw_bmp(600,288,bmp1[now - 1]);
break;
case 4:
lcd_draw_bmp(700,288,bmp1[now - 1]);
break;
case 5:
lcd_draw_bmp(600,192,bmp1[now - 1]);
break;
case 6:
lcd_draw_bmp(700,192,bmp1[now - 1]);
break;
case 7:
lcd_draw_bmp(600,96,bmp1[now - 1]);
break;
case 8:
lcd_draw_bmp(700,96,bmp1[now - 1]);
break;
case 9:
lcd_draw_bmp(600,0,bmp1[now - 1]);
break;
case 10:
lcd_draw_bmp(700,0,bmp1[now - 1]);
break;
default:
break;
}
}
}
}
void* key_deal(void* k)
{
while(1)
{
target = eve();
array[target - 1].flag = !array[target - 1].flag;
if(array[target - 1].flag) //按下了该楼层
{
switch (target)
{
case 1:
lcd_draw_bmp(600,384,bmp2[target - 1]);
break;
case 2:
lcd_draw_bmp(700,384,bmp2[target - 1]);
break;
case 3:
lcd_draw_bmp(600,288,bmp2[target - 1]);
break;
case 4:
lcd_draw_bmp(700,288,bmp2[target - 1]);
break;
case 5:
lcd_draw_bmp(600,192,bmp2[target - 1]);
break;
case 6:
lcd_draw_bmp(700,192,bmp2[target - 1]);
break;
case 7:
lcd_draw_bmp(600,96,bmp2[target - 1]);
break;
case 8:
lcd_draw_bmp(700,96,bmp2[target - 1]);
break;
case 9:
lcd_draw_bmp(600,0,bmp2[target - 1]);
break;
case 10:
lcd_draw_bmp(700,0,bmp2[target - 1]);
break;
default:
break;
}
continue;
}
else //再次按下取消选择
{
switch (target)
{
case 1:
lcd_draw_bmp(600,384,bmp1[target - 1]);
break;
case 2:
lcd_draw_bmp(700,384,bmp1[target - 1]);
break;
case 3:
lcd_draw_bmp(600,288,bmp1[target - 1]);
break;
case 4:
lcd_draw_bmp(700,288,bmp1[target - 1]);
break;
case 5:
lcd_draw_bmp(600,192,bmp1[target - 1]);
break;
case 6:
lcd_draw_bmp(700,192,bmp1[target - 1]);
break;
case 7:
lcd_draw_bmp(600,96,bmp1[target - 1]);
break;
case 8:
lcd_draw_bmp(700,96,bmp1[target - 1]);
break;
case 9:
lcd_draw_bmp(600,0,bmp1[target - 1]);
break;
case 10:
lcd_draw_bmp(700,0,bmp1[target - 1]);
break;
default:
break;
}
continue;
}
}
}
void* floor_info(void* f)//保存当前楼层上面或下面有多少层
{
while(1)
{
int h_n = 0, l_n = 0;
if(now ==target )
{
//lcd_draw_bmp(200,0,bmp1[now - 1]);
continue;
}
else if(target > now)
{
for (int i = now + 1; i < 11; i++)
{
if (array[i-1].flag == 1)
{
h_n++;
}
}
pthread_mutex_lock(&mutex1);
h_num = h_n;
pthread_mutex_unlock(&mutex1);
}
else if (target < now)
{
for (int i = now-1; i > 0; i--)
{
if (array[i-1].flag == 1)
{
l_n++;
}
}
pthread_mutex_lock(&mutex2);
l_num = l_n;
pthread_mutex_unlock(&mutex2);
}
}
}
main函数建立线程,判断上下楼,初始化映射解除映射功能。
int main(int argc,char const* argv[])
{
lcd_init();
lcd_draw_bmp(0,0,"./main.bmp");
sleep(2);
lcd_draw_background(0xF5E2DC);
lcd_draw_bmp(240,140,bmp[0]);
lcd_draw_bmp(0,240,"./advertising.bmp");
display();
//创建有名管道,用来接收命令播放视频
create_FIFO();
pid_t ppid = fork();
if(ppid > 0)
{
int flag = 0;
int ret;
pthread_t pid = -1; //保存线程的ID
ret = pthread_create(&pid, NULL, key_deal, NULL);
pthread_detach(pid);
pthread_t pid1 = -1; //保存线程的ID
ret = pthread_create(&pid1, NULL, floor_info, NULL);
pthread_detach(pid1);
pthread_t pid2 = -1; //保存线程的ID
ret = pthread_create(&pid2, NULL, flash_lcd, NULL);
pthread_detach(pid2);
}
else if(ppid == 0)
{
int ret = execl("/usr/bin/mplayer", "mplayer", "-quiet",
"-input","file=/home/work/elevator/vedio.fifo","-loop","0","-geometry", "0:0","-zoom","-x","200","-y","240",mp4[0], NULL);
if(ret == -1)
{
exit(1);
}
}
// pthread_join(pid,NULL);
// pthread_join(pid1,NULL);
while(1)
{
//上楼
for( ; h_num > 0;now++)
{
//在屏幕中间显示向上的箭头
lcd_draw_bmp(480,120,"./up.bmp");
//在屏幕中间显示当前楼层
lcd_draw_bmp(240,140,bmp[now-1]);
if(array[now - 1].flag == 1)
{
//更新楼层中的标识位
array[now-1].flag = 0;
sleep(3);
//恢复按键的颜色(白)
lcd_draw_bmp(array[now-1].x,array[now-1].y,bmp1[now-1]);
//覆盖up,刷新屏幕中间的区域
lcd_draw_bmp(480,120,"./restore_pic1.bmp");
//sleep(5);
pthread_mutex_lock(&mutex1);
h_num--;
pthread_mutex_unlock(&mutex1);
}
printf("上楼中\n");
sleep(3); //表示正在上楼
if (h_num == 0)
{
lcd_draw_bmp(480,120,"./restore_pic1.bmp");//覆盖up,刷新屏幕中间的区域
now--;
}
}
//下楼
for( ; l_num > 0;now--)
{
//在屏幕中间显示向下的箭头
lcd_draw_bmp(480,120,"./down.bmp");
//在屏幕中间显示当前楼层
lcd_draw_bmp(240,140,bmp[now-1]);
if(array[now - 1].flag == 1)
{
//更新楼层中的标识位
array[now-1].flag = 0;
sleep(3);
//恢复按键的颜色(白)
lcd_draw_bmp(array[now-1].x,array[now-1].y,bmp1[now-1]);
//覆盖up,刷新屏幕中间的区域
lcd_draw_bmp(480,120,"./restore_pic1.bmp");
//sleep(5);
pthread_mutex_lock(&mutex2);
l_num--;
pthread_mutex_unlock(&mutex2);
}
printf("下楼中\n");
sleep(3); //表示正在下楼
if (l_num == 0)
{
lcd_draw_bmp(480,120,"./restore_pic1.bmp");//覆盖down,刷新屏幕中间的区域
now++;
}
}
}
lcd_uninit();
return 0;
}
标签:draw,多媒体,bmp,并发,电梯,lcd,楼层,array,now From: https://blog.csdn.net/qq_63147384/article/details/142378106全部代码:
链接:https://pan.baidu.com/s/1oPFlK_dykkqnwor5-4iO5w?pwd=j9h0
提取码:j9h0