嵌入式实验

  • 引语
  • 内容介绍
  • 案例展示
    • 原理
    • 代码
    • 结果展示

引语

记录学习路程,抛砖引玉。如有更好的算法或者出现错误,欢迎指点。

内容介绍

1、理解触摸屏的工作原理
2、掌握触摸屏获取坐标的方法
3、理解多线程的原理。
4、掌握多线程的编程方法。
5、通过触摸屏实现智能家居控制系统人机界面交互
6、实现MP3音乐播放、暂停、继续和退出

案例展示

原理

一、多线程原理
1、线程的创建
gec@ubuntu:/mnt/hgfs/project$ man 3 pthread_create
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
参数说明:
pthread_t *thread ---- 创建的子线程的ID
const pthread_attr_t *attr ---- 线程的属性
void *(*start_routine) (void *)—创建的线程的执行函数
void *arg ---->创建线程的时候,向线程的执行函数传递的参数。
返回值:
On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.
Compile and link with -pthread.
2、线程的等待
int pthread_join(pthread_t thread, void **retval);
如果在主线程中调用这个函数,则这个函数会等待子线程退出,如果子线程不退出,主线程不会退出。
3、让一个线程退出的函数
#include <pthread.h>
int pthread_cancel(pthread_t thread);
参数:
pthread_t thread —cancle线程的ID
4、线程自己退出
#include <pthread.h>
void pthread_exit(void *retval);

二、触摸屏的原理
1.触摸屏
电容式触摸屏:(0,0)(799,479)或者(0,0)(1023,599)
2.设备文件
在Linux中访问硬件设备都是通过设备文件来访问的,访问的时候使用的是Linux系统IO函数:open()/read()/write()/lseek()/close().
液晶屏:
[root@GEC6818 /]#ls /dev/fb0 -l
crw-rw---- 1 root root 29, 0 Jan 1 1970 /dev/fb0
触摸屏:
[root@GEC6818 /]#ls /dev/input/event0 -l
crw-rw---- 1 root root 13, 64 Jan 1 1970 /dev/input/event0
注意:
有些嵌入式平台,触摸屏的设备文件是/dev/event0
思考:
Linux中文件的类型(7种)----- #ls -l
1)字符设备文件
[root@GEC6818 /]#ls /dev/fb0 -l
crw-rw---- 1 root root 29, 0 Jan 1 1970 /dev/fb0
c—charactor
2)块设备文件
[root@GEC6818 /]#ls /dev/sda* -l
brw-rw-rw- 1 root root 8, 0 Jan 1 00:05 /dev/sda
brw-rw-rw- 1 root root 8, 1 Jan 1 00:05 /dev/sda1
b—block,一般大容量的存储设备
3)普通文件
[root@GEC6818 /]#ls /test/main.bmp -l
-rw-r–r-- 1 root root 1152054 Jan 1 2015 /test/main.bmp

  • ----普通文件
    4)目录文件
    drwxr-xr-x 2 root root 4096 Jan 1 2015 test
    d— directory 文件夹
    5)链接文件
    [root@GEC6818 /lib]#ls /lib -l
    total 6144
    -rwxrwxr-x 1 root root 169264 Dec 27 2016 ld-2.23.so
    lrwxrwxrwx 1 root root 10 Dec 27 2016 ld-linux.so.3 -> ld-2.2
    l----link 快捷方式
    6)管道文件
    进程通信的一种方式
    p— pipe
    7)socket文件/套接字文件
    s — socket
    3.查看触摸屏的文件
    查看系统中有哪些输入类型的设备----触摸屏也是输入类型的设备。
    [root@GEC6818 /lib]#cat /proc/bus/input/devices
    4、检测触摸屏是否ok
    [root@GEC6818 /]#cat /dev/input/event0

三、如何获取触摸屏的坐标
1、打开触摸屏
例:
int fd_ts;
fd_ts = open("/dev/input/event0", O_RDONLY);
if(fd_ts == -1)
{
perror(“open ts”);
return 0;
}
2、读入触摸屏的数据
char ts_buf[100];
read(fd_ts, ts_buf, 100); —错误的代码。
解决:
在Linux系统中,应用程序从输入类型的设备(鼠标、键盘、手写板、按钮、触摸屏等)中读出来的数据是有一个固定的格式的。这个固定的格式在<linux/input.h>中定义,是一个结构体struct input_event。
gec@ubuntu:~$ gedit /usr/include/linux/input.h
/*

  • The event structure itself
    */
    struct input_event {
    struct timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
    };
    成员说明:
    struct timeval time; ----输入事件的时间
    __u16 type; ---- 输入事件的类型
    __u16 code; ----- 输入事件的编码
    __s32 value;----- 输入事件的值
    触摸屏X轴和Y轴的坐标就是包含在struct input_event 的结构体中。
    例:读取触摸屏的数据
    struct input_event ts_data;
    read(fd_ts, &ts_data, sizeof(struct input_event));
    注意:
    数组的名字是数组的地址,结构体的名字不是结构体的地址。
    根据type、code和value分析触摸屏的坐标。
    3、关闭触摸屏
    close(fd_ts);

四、触摸屏数据的分析
type=3,code=0,value=58 ----->触摸屏事件,ABS_X,坐标值
type=3,code=1,value=595 ----->触摸屏事件,ABS_Y,坐标值
type=1,code=330,value=1 ----->按键事件,code=330触摸屏,(触摸屏按下)
type=0,code=0,value=0 ----->同步事件
type=1,code=330,value=0 ----->按键事件(触摸屏松开)
type=0,code=0,value=0 ----->同步事件
注意:
1.每次点击触摸屏,应用程序循环读取六次数据。
2.在读取触摸屏数据的过程中,如果没有点击触摸屏,应用程序会产生阻塞,等待触摸屏按下。
数据分析
1、type ----- 输入设备的类型—>通过type可以知道读到的设备的类型。
#define EV_SYN 0x00 ---->同步事件,触摸屏按下和松开都会产生一次同步事件。
#define EV_KEY 0x01 ---->按键事件
#define EV_REL 0x02 ---->相对坐标事件(鼠标)
#define EV_ABS 0x03 ---->绝对坐标事件(触摸屏)
2、code ---- 输入事件的编码
code的是和type相关的,不用的type下面,code含义不同。
例:
type == 1(EV_KEY)
则code代表哪一个按钮(按钮的编号)
#define KEY_T 20
#define KEY_Y 21
#define KEY_U 22
#define KEY_I 23
#define BTN_TOUCH 0x14a
如果type等于3,则code代表的是触摸屏的坐标轴
#define ABS_X 0x00
#define ABS_Y 0x01
3、value ----- 输入事件的值
例:
如果type等于1,code == 20,value == 0
键盘上的T按钮松开。value:0–按钮松开,1–按键按下
如果type==3,code == 1,value == 100;
触摸屏的Y轴坐标是100.

五、触摸屏的校正
触摸屏的校正----让触摸屏的坐标和液晶屏的坐标保持一致。
两个方面的校正:
1.坐标的范围:
液晶屏:(0,0)~(799,479)
触摸屏:(0,0)(1023,599)—>按比例调整(0,0)(799,479)
2.坐标轴的调整
如果触摸屏和液晶屏的原点不一致,需要调整。
注意:液晶屏的原点(0,0)是在液晶屏的左上角。

六、多个远程源程序的编译
lcd.c lcd.h main.c touch.c touch.h ----->可执行程序main
#arm-linux-gcc lcd.c touch.c main.c -o main -std=c99

七、播放音乐
1.音乐播放器
[root@GEC6818 /]#which madplay
/usr/bin/madplay

2.mp3音乐
如何讲一个mp3文件下载到开发板
串口、U盘、网络下载(tftp)
1)使用网线将电脑直接连接开发板(GEC6818)。
2)电脑的设置
(1)设置静态IP:172.22.75.1
(2)关闭windows的防火墙
(3)最好关闭wifi
3)配置GEC6818的IP
4)开发板和电脑之间互ping一下
要可以互ping
5)打开一个tftp服务器,并设置下载目录
tftpd32.exe
6)在开发板端下载文件
[root@GEC6818 /]#tftp 172.22.75.1 -g -r music.mp3
-g ---- get
-r ---- remote
7)通过tftp将文件上传到PC机
[root@GEC6818 /]#tftp 172.22.75.1 -p -l music.mp3
-p ---- put
-l ---- local

3.使用命令行:
[root@GEC6818 /test]#madplay music.mp3
2.如何编写程序播放音乐
管理madplay的主程序,包括播放,暂停播放,恢复播放,停止播放
system(“madplay north.mp3 &”);//利用system函数调用madplay播放器播放*.mp3音乐
system(“madplay north.mp3 -r &”);//循环播放:参数-r
system(“killall -9 madplay”);//利用system函数调用killall命令将madplay终止掉
system(“killall -STOP madplay &”);//利用system函数调用killall命令将madplay暂停
system(“killall -CONT madplay &”);//利用system函数调用killall命令恢复madplay的播放

代码

1.显示图片,单色循环lcd.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int lcd_show_bmp(char *bmp_name)
{int fd_bmp;int fd_lcd; int  *fb_base =NULL;char bmp_buf[800*480*3];int lcd_buf[800*480];int lcd_new[800*480]; //风险:每个进程的stack不能超过8MBfd_bmp = open(bmp_name, O_RDONLY);if(fd_bmp == -1){perror("open bmp");return -1;}lseek(fd_bmp,54,SEEK_SET);read(fd_bmp,bmp_buf, 800*480*3);//RGB数据close(fd_bmp);for(int i=0;i<800*480;i++)lcd_buf[i] =(0x00<<24) + (bmp_buf[3*i+2]<<16) + (bmp_buf[3*i+1]<<8) + (bmp_buf[3*i+0]);for(int i=0;i<800;i++)for(int j=0;j<480;j++)lcd_new[i+(479-j)*800] = lcd_buf[i+j*800];fd_lcd= open("/dev/fb0", O_RDWR);if(fd_lcd == -1){perror("open lcd"); //根据错误码,输出错误的原因return -1;}fb_base = mmap( NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_lcd, 0 );if(fb_base == NULL){printf("mmap error\n");return 0;}for(int i =0; i<800*480; i++)  //arm-linux-gcc -o test test.c  -std=c99    *(fb_base+i)= lcd_new[i];munmap(fb_base, 800*480*4);close(fd_lcd);return 0;
}
int lcd_show_color(unsigned int color)
{   int fd_lcd; int  *fb_base =NULL;fd_lcd= open("/dev/fb0", O_RDWR);if(fd_lcd == -1){perror("open lcd"); //根据错误码,输出错误的原因return -1;}fb_base = mmap( NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, fd_lcd, 0 );if(fb_base == NULL){printf("mmap error\n");return 0;}for(int i =0; i<800*480; i++)  //arm-linux-gcc -o test test.c  -std=c99    *(fb_base+i)= color;munmap(fb_base, 800*480*4);close(fd_lcd);return 0;
}

2.触摸屏touch.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "touch.h"
struct ts_data get_ts_xy(void)
{//1、打开触摸屏int fd_ts,i;struct ts_data ts_temp;struct input_event ts_data;fd_ts=open("/dev/input/event0",O_RDONLY);if(fd_ts==-1){perror("open ts");exit(0);}//读入触摸屏数据for(i=0;i<6;i++){read(fd_ts,&ts_data,sizeof(struct input_event));if((ts_data.type == EV_ABS) && ts_data.code == ABS_X )ts_temp.x = ts_data.value*800/1024;else if((ts_data.type == EV_ABS) && ts_data.code == ABS_Y)ts_temp.y = ts_data.value*480/600;}close(fd_ts);return ts_temp;
}

3.音乐播放上一曲和下一曲和液晶屏检测

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "lcd.h"
#include <pthread.h>
#include "touch.h"
#include <stdlib.h>
#include <unistd.h>
struct music_ls{char *music_term;struct music_ls *next;struct music_ls *last;};
struct ts_data ts_xy;
int mos=1;
struct music_ls rc,lm,*p;
void music(void)
{   system("madplay lm.mp3 &");p=&lm;int u=1,c=1;while(1){   if(mos==7 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){    mos=2;lcd_show_bmp("control.bmp");system("killall -9 madplay");break;}if(mos==7 && ts_xy.x>10 && ts_xy.x<95 && ts_xy.y>10 && ts_xy.y<50 && u==1){  if(p->last!=NULL){  system("killall -9 madplay");p=p->last;usleep(100000);system(p->music_term);u=0;} }if(mos==7 && ts_xy.x>10 && ts_xy.x<95 && ts_xy.y>93 && ts_xy.y<133 && u==0){   if(p->next!=NULL){  system("killall -9 madplay");p=p->next;usleep(100000);system(p->music_term);u=1;}}if(mos==7 && ts_xy.x>10 && ts_xy.x<95 && ts_xy.y>50 && ts_xy.y<93 && c==1){ system("killall -STOP madplay &");c=0;ts_xy.x=0;ts_xy.y=0;}if(mos==7 && ts_xy.x>10 && ts_xy.x<95 && ts_xy.y>50 && ts_xy.y<93 && c==0){ system("killall -CONT madplay &");c=1;ts_xy.x=0;ts_xy.y=0;}}
}
void lcd_show_color_xh(void)//循环显示单色
{   while(1){   lcd_show_color(0x00FF0000);sleep(2);if(mos==5 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){  mos=2;lcd_show_bmp("control.bmp");break;}lcd_show_color(0x0000FF00);sleep(2);if(mos==5 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){  mos=2;lcd_show_bmp("control.bmp");break;}lcd_show_color(0x000000FF);sleep(2);        if(mos==5 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){  mos=2;lcd_show_bmp("control.bmp");break;}}
}
void lcd_show_bmp_xh(void)
{   while(1){   lcd_show_bmp("lx1.bmp");sleep(2);if(mos==6 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){   mos=2;lcd_show_bmp("control.bmp");break;}lcd_show_bmp("lx2.bmp");sleep(2);if(mos==6 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){   mos=2;lcd_show_bmp("control.bmp");break;}lcd_show_bmp("lx3.bmp");sleep(2);if(mos==6 && ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){   mos=2;lcd_show_bmp("control.bmp");break;}}
}
void *ts_thread(void *data)
{    while(1){  ts_xy=get_ts_xy();}
}
int main(void)
{int ret;pthread_t tid_ts;ret=pthread_create(&tid_ts,NULL,ts_thread,NULL);if(ret<0){    perror("ts thread error");return -1;}//对音频文件的预处理rc.music_term="madplay rc.mp3 &";rc.next=&lm;rc.last=NULL;lm.music_term="madplay lm.mp3 &";lm.next=NULL;lm.last=&rc;//1、打开触摸屏int fd_ts;
struct input_event ts_data;fd_ts = open("/dev/input/event0", O_RDONLY);if(fd_ts == -1){    perror("open ts");return 0;}lcd_show_bmp("main.bmp");while(1){  if(mos==1){   if(ts_xy.x>650 && ts_xy.x<800 && ts_xy.y>427 && ts_xy.y<473){   mos=2;lcd_show_bmp("control.bmp");}}if(mos==2){    if(ts_xy.x>60 && ts_xy.x<300 && ts_xy.y>140 && ts_xy.y<200){    mos=3;lcd_show_bmp("led_ctrl.bmp");}if(ts_xy.x>460 && ts_xy.x<700 && ts_xy.y>140 && ts_xy.y<200){    mos=4;lcd_show_bmp("lx.bmp");}if(ts_xy.x>60 && ts_xy.x<300 && ts_xy.y>245 && ts_xy.y<305){   mos=5;lcd_show_color_xh();}if(ts_xy.x>460 && ts_xy.x<700 && ts_xy.y>245 && ts_xy.y<305){mos=6;lcd_show_bmp_xh();} if(ts_xy.x>60 && ts_xy.x<300 && ts_xy.y>350 && ts_xy.y<410){   mos=7;lcd_show_bmp("rc1.bmp");music();}if(ts_xy.x>460 && ts_xy.x<700 && ts_xy.y>350 && ts_xy.y<410){   mos=8;lcd_show_bmp("lx3.bmp");}}if(mos==3 || mos==4|| mos==8){   if(ts_xy.x>700 && ts_xy.x<800 && ts_xy.y>0 && ts_xy.y<50){mos=2;lcd_show_bmp("control.bmp");}}}//3、关闭触摸屏close(fd_ts);return 0;
}

结果展示

Linux|智能家居嵌入式系统之音乐播放相关推荐

  1. linux嵌入式智能家居环境监测系统的设计,智能家居环境监测系统.doc

    智能家居环境监测系统.doc 智能家居环境监测系统 近些年来,智能家居系统的使用功能愈加健全.本文之中在充分了解嵌入式系统平台的具体构建的前提下,以智能家居系统当前的功能要求为主要方向,以该平台的硬件 ...

  2. 基于QT的智能家居中控系统的简明设计

    文章目录 系统总体说明 主板UI设计 后续改进与完善 系统总体说明   系统采用 "主从式架构" ,即一主多从式,该智能居家控制系统的主要功能包括登录功能.注册功能.音乐播放功能. ...

  3. QG工作室——智能与嵌入式系统小组

    一.小组简介 (1)小组历史 本小组是在2005年12月,在计算机智能与软计算所指导下,为了更好的让学生投入到计算机专业实践,而创立的.本小组目前有指导老师两位,分别是曾碧教授(计算机学院副院长,智能 ...

  4. 基于android系统的音乐播放器,基于Android系统的音乐播放器软件设计与实现.doc

    基于Android平台的音乐播放器 The Development of Mobile Music Player Based on Android platform system 学生学号: 学生姓名 ...

  5. 基于Unity3D的智能家居仿真系统——户型绘制基本功能介绍

    本篇我们来介绍一下左侧工具栏中基本绘制的应用. 一.墙体绘制 直墙 & 矩形墙 绘制墙体时,可以看到上方的工具栏中对墙体进行参数的设定. 弧形墙 在建筑版的户型工具中,增加了弧形墙的绘制功能, ...

  6. 基于Wio Terminal的简易智能家居中控系统(初代版本)

    经过不断地踩坑(学习),初代的简易智能家居中控系统已经做好了,在申请项目时填写的功能都做出来了,但是有些功能不是用Wio Terminal实现的(一方面是因为代码量太大,会给Wio Terminal的 ...

  7. 基于51单片机的智能家居环境监测系统

    基于51单片机的智能家居环境监测系统 1)实时监测温度.湿度.烟雾浓度 2)按键可更改三个参数的报警值上下限 3)声光报警 程序有详细注释!!! 资料包含: 仿真.程序.AD原理图.PCB.报告等 P ...

  8. 魅族鸿蒙操作系统,魅族lipro智能家居鸿蒙系统

    魅族lipro智能家居鸿蒙系统是可以让用户尽享便捷智能生活的软件,引入全新的鸿蒙系统,让用户进行操作更加流畅轻松,随时都可以去感受最佳的生活服务方式, 而且用户用户进行全新系统的更新都是简单便捷,任何 ...

  9. linux安装音乐软件教程,Linux上好用的五款音乐播放器

    Jack Wallen 盘点他***的五款 Linux 音乐播放器. 不管你做什么,你都有时会来一点背景音乐.不管你是开发.运维或是一个典型的电脑用户,享受美妙的音乐都可能是你在电脑上最想做的事情之一 ...

最新文章

  1. Pytorch的网络结构可视化(tensorboardX)(详细)
  2. 网上的假货太多,你把握不住的,让AI来
  3. 2017年英特尔在其数据中心业务和AI方面下大注
  4. elasticsearch Java API 索引API
  5. [云炬Mysql数据库笔记] 第3章 数据定义
  6. zk的数据目录:`version-2`
  7. oracle cast multiset table 语法演示
  8. 栈应用_检测成对符号是否正确使用(代码、分析、汇编)
  9. java各层级限流对比,面试官说:来谈谈限流-从概念到实现,一问你就懵逼了?...
  10. Javascript 闭包何时回收?
  11. hdu 4790 Just Random (2013成都J题) 数学思路题 容斥
  12. python3 相对路径导入_Python中相对路径(导入)和绝对路径(导入)的区别
  13. 简单使用Java实现微信公众号推送模板消息
  14. Ps,Lr,Pr,Ae,Au,C4D,达芬奇调色
  15. STVD+Cosmic搭建STM8开发环境
  16. 远距离485无线传输方案
  17. Python基础---List(列表)
  18. 这是我见过最好的唐诗,而且通俗易懂2
  19. 南卡全新NEO系列骨传导耳机,主打轻运动风的南卡NEO测评!!!
  20. orcal根据身份证获取年龄

热门文章

  1. 转一篇详细的pkt文件的说明文档
  2. 谷歌可以正常显示图片,但IE不能正常显示图片的问题的解决办法
  3. ADAMS使用过程中的license不可用导致软件不能打开问题的解决
  4. git设置tag标签
  5. 重装系统后,microsoft下的word,excel之类的软件没有了怎么办?
  6. 差分近似图像导数算子之Laplace算子
  7. 使用jquery完成跨域访问
  8. 米拓模板:农业农产品公司网站模板推荐
  9. 某人去玩具店买小熊,小熊进价为20,卖价是30,付给老板100元,老板没有零钱,就在卖鞋的人那里换了100元零钱,找给卖家70,卖鞋的发现那100元是假币,于是找老板换回了100元,请问玩具店老板损失
  10. python一元线性回归