运行环境要求:

硬件环境:QT210开发板,采用三星s5pv210为芯片方案,该芯片内核为ARM Cortex-A8

软件环境:软件采用开源的linux操作系统;LCD显示技术,触摸屏技术,并发技术

技术要求:

(1)Linux环境搭建及使用、Linux基本命令的使用,

(2))shell基本语法的应用、shell解释器原理;

(3)Linux系统IO接口函数的应用,bmp图片信息存储格式,

设计要求

具体要求:在开发板的屏幕上显示出钢琴界面,手指按压不同的区域时,对应位置的琴键显示按压的效果,并且会发出相对应的声音。当松开手指的时候,琴键按压效果消失,但为了和更接近真实钢琴,其发出的声音不会马上消失,而时等待该声音播放完。当按下下一个按键的时候,便会马上结束上一个声音的播放。

功能结构

电子钢琴分为3个模块,即lcd显示模块,触摸屏模块,并发模块;再往下到具体功能模块就有,钢琴界面显示;按键显示和按压效果展示;曲谱显示和曲谱切换效果展示;音乐的播放和停止。首先显示钢琴界面,琴键以及曲谱就是lcd模块的功能。显示琴键按压效果和曲谱切换显示就是lcd模块和触摸屏模块共同作用的结果。而当我们按压琴键时,会发出声音并播放音乐,这就是并发模块的功能。图片显示和音乐播放的并发。

功能结构图如同所示:

系统流程图

lcd显示模块

再此模块中,首先是对屏幕进行初始化,具体包括,打开屏幕文件和打开映射。然后是定义画点函数,即lcd_display_point();作用是给每个点映射对应的颜色。最后是关闭屏幕文件和关闭映射。

触摸屏模块

在此模块中,先是要打开触摸屏文件,然后读取触摸屏的模式,将其存放在缓冲区类,在不同模式下,将读取到的值赋给x,y(横纵坐标)和p(按键)。个根据x,y,p的值,编写判断程序,不同条件就进入不同的功能函数。最后则是关闭触摸屏文件。

触屏模块程序流程图如同所示:

多线程模块

本模块用到的是多线程并发,要实现手指按压屏幕,按压效果显示和音乐播放并发,首先实在并发模块的主程序创建新的线程函数,新创建的线程函数内容是播放一个MP3文件,而在主程序中写显示按压效果图片。这样一来就实现了图片显示和音乐播放的并发。

并发模块程序流程图:

lcd模块测试

实验结果:在任意位置显示任意大小的图片

触摸屏模块测试

触摸屏模块实验结果:按压琴键会显示按压效果,点击屏幕左上角和右上角,分别向前和向后循环切换图片

按压钢琴键效果图:

按压左上角或右上角切换曲谱图:

并发模块测试

实验结果:当手指按下琴键的时候,屏幕上对应位置的琴键会展示出按压效果,同时会播放出音乐,当手指松开屏幕,按键按压效果消失,音乐并不会消失。当未按下下一个按键的时候,该音乐会播放到直至结束。当按下一个按键的时候,该位置的按键会显示按压效果,并结束上一个音乐的播放,播放本次按压对应位置的音频。

项目源码

//main.c#include <stdio.h>
#include "bmp.h"
#include "lcd.h"
#include "chupin.h"
#include "pthread.h"int main()
{int r = lcd_init();if(r == -1){printf("lcd_init fail\n");return 0;}lcd_display_bmp("piano.bmp",0,0);chupin();lcd_uninit();
}Lcd.c  //lcd显示模块#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include "lcd.h"int lcd_init()
{lcd_fd = open("/dev/fb0",O_RDWR);if(lcd_fd == -1){perror("open lcd error");return -1;}p = mmap(NULL,480*800*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);if(p == NULL){perror("mmap error");return -1;}return 0;
}void lcd_uninit()
{close(lcd_fd);munmap(p,800*480*4);
}/*功能:在屏幕上显示一个点i:这个点的行j:这个点的列color:这个点的颜色
*/
int lcd_display_point(int i,int j,int color)
{if(i>=0 && i<480 && j>=0 && j<800)*(p+(480-1-i)*800+j) = color;//lcdbuf[j+800*(480-1-j)]elseprintf("error\n");
}bmp.c  //图片模块,获取图片的宽高#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include"bmp.h"/*功能:在lcd屏幕上的任意位置显示一张任意大小的图片bmpname:是你要显示的图片的路径名(带路径的文件名)x0:代表这张图片从屏幕的第x0行开始显示y0:代表这张图片从屏幕的第y0列开始显示
*/void lcd_display_bmp(char * bmpname,int x0,int y0)
{int fd = open(bmpname,O_RDWR);if(fd == -1){perror("open error");return;}lseek(fd,0x12,SEEK_SET);//因为宽度的偏移量是12h//char buf[4] ;int w;//用来保存图片的宽度read(fd,&w,4);lseek(fd,0x16,SEEK_SET);//因为高度的偏移量是12h//char buf[4] ;int h;//用来保存图片的高度read(fd,&h,4);char buf[w*h*3];lseek(fd,54,SEEK_SET);//跳过“文件头”,定位到“像素数组”read(fd,buf,w*h*3);int i,j;int color;int n = 0;//for(i=0;i<h;i++)//因为有480行{for(j=0;j<w;j++)//因为一行有800个像素点{//*(p+800*i+j) = color; 0x0000 0000 // 0xff ff ff   0xff<<16 0xff0000  0xff<<8 0xff00 color = buf[3*n] | buf[3*n+1]<<8 | buf[3*n+2]<<16;lcd_display_point(i+x0,j+y0,color);n++;}}    close(fd);
}chupin.c //触摸屏模块#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>
#include <linux/input.h>
#include <sys/mman.h>
#include "chupin.h"
#include "pthread.h"
#include <stdlib.h>int chupin()
{   //lcd_display_bmp("tiger.bmp",279,0);int x,y,p;int num = 1;int flag = 1;int n = 1;int ts = open("/dev/input/event0",O_RDWR);struct input_event buf;bzero(&buf,sizeof(buf));while(1){read(ts,&buf,sizeof(buf));if(buf.type == EV_SYN)printf("-----------------EV_SYV------------------\n");if (buf.type == EV_ABS){if(buf.code == ABS_X ){x = buf.value;//printf("x = %d\n",x);}if (buf.code == ABS_Y){y = buf.value;}}if(buf.type == EV_KEY && buf.code == BTN_TOUCH){p = buf.value;//printf("p = %d\n",p);}if (p == 1 && x>0 && x < 57 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("1.bmp",0,0);create1("madplay -Q d1.mp3");flag = 0;}if (p == 1 && x>57 && x < 125 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("2.bmp",0,60);create1("madplay -Q d2.mp3");flag = 0;}if (p == 1 && x>125 && x < 193 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("3.bmp",0,127);create1("madplay -Q d3.mp3");flag = 0;}if (p == 1 && x>193 && x < 261 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("4.bmp",0,195);create1("madplay -Q d4.mp3");flag = 0;}if (p == 1 && x>261 && x < 329 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("5.bmp",0,263);create1("madplay -Q d5.mp3");flag = 0;}if (p == 1 && x>329 && x < 399 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("6.bmp",0,330);create1("madplay -Q d6.mp3");flag = 0;}if (p == 1 && x>397 && x < 465 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("7.bmp",0,398);create1("madplay -Q d7.mp3");flag = 0;}if (p == 1 && x>465 && x < 533 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("8.bmp",0,465);create1("madplay -Q d8.mp3");flag = 0;}if (p == 1 && x>533 && x < 601 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("9.bmp",0,533);create1("madplay -Q d9.mp3");flag = 0;}if (p == 1 && x>601 && x < 669 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("10.bmp",0,601);create1("madplay -Q d10.mp3");flag = 0;}if (p == 1 && x>669 && x < 737 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("11.bmp",0,669);create1("madplay -Q d11.mp3");flag = 0;}if (p == 1 && x>737 && x < 799 && flag == 1  && y>280 && y <479){system("killall -9 madplay");lcd_display_bmp("12.bmp",0,731);create1("madplay -Q d12.mp3");flag = 0;}if(x>0 && x<100 && y>0 && y < 100 && p == 1 && flag == 1){n = n*(-1);flag = 0;}if(x<800 && x>700 && y>0 && y < 100 && p == 1 && flag == 1){n = n*(-1);flag = 0;}// printf("n = %d",n);if (p == 0 && flag == 0){lcd_display_bmp("piano.bmp",0,0);//system("killall -9 madplay");flag = 1;}if(n == 1 && p == 0 ){lcd_display_bmp("tiger.bmp",279,0);}if (n == -1 && p == 0){lcd_display_bmp("star.bmp",279,0);}}close(ts);return 0;
}pthread.c     //多线程模块
#include<stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdlib.h>
/*
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);thread: 是一个地址,用来保存新建线程的id           attr:线程的属性,一般来说,这个参数为NULL,表示采取默认属性start_routine:函数指针,具体解析在上面应该要指向线程函数(也就是新线程要去执行的那个函数)arg:就是线程函数的参数如果线程函数不需要参数,那么可以为NULL
*/
//线程函数void * start_routine(void * string)
{pthread_detach(pthread_self());system((char *)string);pthread_exit(0) ;
}int create1(char *string)
{pthread_t tid;//线程idpthread_create(&tid,NULL,start_routine,(void *)string);return 0;
}

嵌入式电子钢琴游戏开发设计相关推荐

  1. android策略模式_Android游戏开发–设计游戏实体–策略模式

    android策略模式 在这一部分中,我将尝试解释我对好的游戏设计元素的理解. 我将在示例中使用droid,并编写基本的战斗模拟器脚本以查看其行为. 问题: 我指挥一个机器人,我想消灭敌人. 再次面对 ...

  2. 嵌入式c语言开发闹钟,嵌入式电子闹钟()时钟课程设计.doc

    #include //头文件 #include #define uchar unsigned char //宏定义 #define uint unsigned int //位定义 sbit rs=P2 ...

  3. C语言——简单的五子棋小游戏开发设计

    下面展示一些 功能实现 一.菜单功能模块设计 int Menu() {system("color 3F");printf("-----------------亲,欢迎来到 ...

  4. 基于原生JavaScript的经典坦克大战游戏开发设计

    主要含有以下功能: 1.玩家采用等级机制,共5级: 2.补充装备有子弹.金星.炸弹.导弹.手枪.战舰,分值各不相同: 3.打掉障碍可加分: 4.用鼠标控制子弹射击,左键为单发射击.右键为双发射击,屏蔽 ...

  5. 嵌入式电子产品业务逻辑设计

    例子1: 状态1 按键方式1 状态2 按键方式1 状态2 按键方式2 状态1 按键方式2 例子2:

  6. Web MIDI 入门:如何用电子钢琴做一款游戏

    译注:本文是作者 Peter Anglea 发布在 <SmashingMagazine>上的一篇介绍 Web MIDI API 及用其开发一款电子钢琴游戏的文章.(转载请注明出处) 原文链 ...

  7. IOS塔防游戏《坦克对大炮》的开发设计记录

    IOS塔防游戏<坦克对大炮>的开发设计记录 引子 游戏已经在App Store上线几个月了,一直很想写点什么记录一下.真要写的时候,却又发现无从下笔没啥好写的.在2012年进入IOS,对于 ...

  8. 【转】部分游戏开发工具

    2019独角兽企业重金招聘Python工程师标准>>> GPL许可证        GPL通用性公开许可证(General Public License,简称GPL).在字典中的含义 ...

  9. 部分游戏开发工具(转载)

      GPL许可证 GPL通用性公开许可证(General Public License,简称GPL).在字典中的含义是非洲大羚羊,我们可以常常看到非常个性化的羊头,想必很多人已经非常熟悉.象征 GNU ...

  10. 用Python制作简易播放器(电子钢琴) mac系统

    用Python制作简易播放器(电子钢琴) 开发环境:Python3.7 Mac OS 思路: 先根据需要设计GUI的样式,并思考需要定义什么功能 把功能写出来 把功能填入GUI之中 用曲子测试完整的程 ...

最新文章

  1. 在 App Store 三年學到的 13 件事(下)
  2. SQL SERVER数据页checksum校验算法
  3. 第一课 计算机组成原理(哈工大)
  4. Sublime Text 2
  5. 图片序列化和反序列化成图片文件(代码)
  6. Angular页面发生更新时,更新如何从view层传递到model层
  7. maven中文乱码问题——编译错误
  8. shell 基础知识
  9. 老司机们看一下!支付宝又为你省下一笔钱了,还有6大免费承诺
  10. 完成一个Vue3项目的过程
  11. 计算机应用基础教案 电子书,计算机应用基础教案(全套)-20210511075659.pdf-原创力文档...
  12. 2020淘宝双十一快速刷金币工具
  13. vue的封装之路(二)-封装一个基于element ui的省市区级联选择器
  14. 谈 Scratch 版“植物大战僵尸”
  15. Cadence IC617工艺库安装步骤
  16. js控制浏览器窗口弹出、警告框、确认框
  17. JavaScript捕获同时多个按键-非组合键
  18. 不明恶意攻击致搜狗搜索搜索结果跳转百度搜索技术原理分析
  19. Linux下更改下只读文件
  20. 认知什么是关键词,什么是长尾词?

热门文章

  1. 传智博客JAVA基础第二十三天
  2. 【12】Kotlin函数泛型协程
  3. Linux错误码汇总
  4. Windows下CURL编译 支持HTTPS
  5. iPhone/iPad解锁屏幕密码
  6. mac mysql 5.7.12修改密码_Mac下 Mysql5.7忘记root密码及mysql5.7修改root密码的方法
  7. 在div的左上角添加三角形,文字45度倾斜显示
  8. 「节能学院」浅谈智能安全配电装置在养老福利单位的研究与应用
  9. c#学习笔记之八 函数的代表delegate的用法:c# 求 三角函数 指数函数 积分
  10. Kattle Spoon同步工具