嵌入式课程设计之触摸屏程序设计

时间:2019-05-12 04:36:30下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《嵌入式课程设计之触摸屏程序设计》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《嵌入式课程设计之触摸屏程序设计》。

第一篇:嵌入式课程设计之触摸屏程序设计

嵌入式课程设计

设计题目:触摸屏驱动程序设计 班级: 学号: 姓名: 指导老师:

设计时间:2010年12月25日--12月28日

目录

第一部分 要求................................................................................................................................1 1.1设计目的.................................................................................................................................1 1.2 设计意义................................................................................................................................1 1.3 设计内容................................................................................................................................1 1.4 主要任务................................................................................................................................1 第二部分 正文................................................................................................................................2 2.1触摸屏工作原理(触摸屏接口工作模式).........................................................................2 2.2、设计总体方案......................................................................................................................3 2.3、设计所需工具......................................................................................................................6 2.4、平台构建过程......................................................................................................................6 2.4.1、硬件平台搭建...............................................................................................................6 2.4.2根文件系统的制作..........................................................................................................8(1)根文件系统.....................................................................................................................8 第三章 程序..................................................................................................................................13 3.1.程序流程图:.......................................................................................................................13 3.2.分析驱动...............................................................................................................................13 3.2.1、触摸屏设备驱动中数据结构.....................................................................................13 3.2.2、触摸屏驱动模块加载和卸载函数.............................................................................15 3.2.3、触摸屏设备驱动的读函数.........................................................................................17 3.2.4、触摸屏设备驱动的轮询与异步通知.........................................................................17 3.2.5源程序触摸屏驱动代码:............................................................................................18 3.2.6、实验结果显示:.........................................................................................................29 第四部分 心得..............................................................................................................................30 4.1 课程设计心得体会:..........................................................................................................30 第五部分 参考文献......................................................................................................................32 5.1【参考文献】........................................................................................................................32

第一部分 要求

1.1 设计目的

1.基于Linux操作系统,以及Emest III实验箱,利用触摸屏返回触点坐标值及动作信息。

2.坐标及动作的具体显示:触摸笔动作,触点X坐标值,触点Y坐标值。

1.2 设计意义

1.熟悉嵌入式系统开发平台

2.掌握ARM嵌入式Linux操作系统下的各个指令的使用方法 3.了解触摸屏的原理

1.3 设计内容

1.Linux系统的正确移植和使用 2.根文件系统的正确移植和使用 3.驱动程序的编译与装载

4.嵌入式系统下应用程序的交叉编译及下载与调试

1.4 主要任务

1.熟悉实验的流程

2.vivi,linux内核的烧写

3.cramfs文件系统(烧写前需编译)的烧写 4.理解驱动程序源代码

5.调用驱动程序的某些函数,编译与调试应用程序

第二部分 正文

2.1触摸屏工作原理(触摸屏接口工作模式)

(1)普通转换模式

普通转换模式(AUTO_PST = 0,XY_PST = 0)是用作一般目的下的ADC转换。这个模式可以通过设置ADCCON和ADCTSC来进行对AD转换的初始化;而后读取ADCDAT0(ADC数据寄存器0)的XPDATA域(普通ADC转换)的值来完成转换。(2)分离的X/Y轴坐标转换模式:X轴坐标转换和Y轴坐标转换。

X轴坐标转换(AUTO_PST=0且XY_PST=1)将X轴坐标转换数值写入到ADCDAT0寄存器的XPDATA域。转换后,触摸屏接口将产生中断源(INT_ADC)到中断控制器。

Y轴坐标转换(AUTO_PST=0且XY_PST=2)将X轴坐标转换数值写入到ADCDAT1寄存器的YPDATA域。转换后,触摸屏接口将产生中断源(INT_ADC)到中断控制器。

(3)自动(连续)X/Y轴坐标转换模式。

自动(连续)X/Y轴坐标转换模式(AUTO_PST=1且XY_PST= 0)以下面的步骤工作:

触摸屏控制器将自动地切换X轴坐标和Y轴坐标并读取两个坐标轴方向上的坐标。触摸屏控制器自动将测量得到的X轴数据写入到ADCDAT0寄存器的XPDATA域,然后将测量到的Y轴数据到ADCDAT1的YPDATA域。自动(连续)转换之后,触摸屏控制器产生中断源(INT_ADC)到中断控制器。(4)等待中断模式

当触摸屏控制器处于等待中断模式下时,它实际上是在等待触摸笔的点击。在触摸笔点击到触摸屏上时,控制器产生中断信号(INC_TC)。中断产生 2

后,就可以通过设置适当的转换模式(分离的X/Y轴坐标转换模式或自动X/Y轴坐标转换模式)来读取X和Y的位置。(5)静态(Standby)模式

当ADCCON寄存器的STDBM位被设为1时,Standby模式被激活。在该模式下,A/D转换操作停止,ADCDAT0寄存器的XPDATA域和ADCDAT1寄存器的YPDATA(正常ADC)域保持着先前转换所得的值。

2.2、设计总体方案

1、软件

(1)Embest Online Flash Programmer For ARM: Embest Flash在线编程器(2)HYPER TERMINAL(超级终端):传送vivi.nand;

传送vivi.nand

vivi> load flash kernel x <回车> 烧写更新内核,传送zImage文件;等待传送内核文件

传送内核:

vivi>load flash root j <回车> 烧写更新文件系统;烧写新的文件系统 load flash root j

(3)EmbestIDE Pro for ARM: 应用于嵌入式软件开发的新一代集成开发环境,是一个高度集成的图形界面操作环境,包含编辑器、编译汇编链接器、调试器、工程管理、Flash 编程等工具;支持的开发语言包括标准C和汇编语言。(4)cygwin: 一个在windows平台上运行的unix模拟环境,它对于学习unix/linux操作环境,或者从unix到windows的应用程序移植,或者进行某些特殊的开发工作,尤其是使用gnu工具集在windows上进行嵌 5

入式系统开发,把gcc,gdb,gas等开发工具进行了改进,能够生成并解释win32的目标文件。

2、硬件

S3C2410处理器是Samsung公司基于ARM公司的ARM920T处理器核,32位微控制器。该处理器拥有:独立的16KB指令Cache和16KB数据Cache,MMU,支持TFT的LCD控制器,NAND闪存控制器,3路UART,4路DMA,4路带PWM的Timer,I/O口,RTC,8路10位ADC,Touch Screen接口,IIC-BUS 接口,IIS-BUS 接口,2个USB主机,1个USB设备,SD主机和MMC接口,2路SPI。S3C2410处理器最高可运行在203MHz。

2.3、设计所需工具

1.软件: Embest Online Flash Programmer For ARM,HYPER TERMINAL(超级终端),EmbestIDE Pro for ARM,cygwin 1.硬件:s3c2410开发板,Embest实验箱

2.4、平台构建过程

2.4.1、硬件平台搭建

硬件流程图:

(1)Vivi烧写过程

1)首先把SW104断开,Flash Programmer的Program,在File选择Open打开要烧写的配置文件S3C2410&NandFLash_vivi.cfg,在Flash Programmer的Program页中选择要烧写的文件vivi.bon&load.bin。点击按钮 Progarm 开始烧写,直到烧写成功

2)连接串口线到 PC 机 COM1,运行光盘中提供的 Windows 超级终端Hyper Terminal.ht 把开发板重新加电,程序运行后,在超级终端上可以看到串口输出Wating,表示正在等待用户从超级终端下载文件。这时,请点击超级终端菜单“传送”选择 Xmodem 方式下载 vivi.nand 文件,点击 OK 后等待下载烧写结束即可。(2)内核zImage烧写

1)首先SW104设为短接(从Nand Flash启动),并确定已经烧写vivi.nand,加电。)在vivi启动等待中,敲入空格键进入vivi界面环境,并输入以下命令:vivi> load flash kernel x <回车> 烧写更新内核约1分钟即可烧写完毕 3)点击超级终端菜单中的“传送”,选“发送文件”zImage” 并选择xModem方式传送)烧写结束,重起实验板,观测超级终端窗口提示信息就可以启动linux内核,(3)新文件系统的烧写

1)首先SW104设为短接(从Nand Flash启动),确定已经成功烧写vivi.nand,加电运行可以看到vivi启动信息,输入空格进入命令状态;

2)双击运行Download.pjf(该文件在/tmp/edukit-2410/image/中)工程(将启动Embest IDE环境),点击连接Remote connect,程序应该正在运行(命令按钮STOP为红色);在串口输入help,看看有没有反应,如果没反应,点击IDE 按钮:Reset->Start(F5);再输入help测试,直到有反应为止;

3)如果可以输出一些信息,再点击IDE中的Stop,配置Debug的Download地址为0x30000000,并点击IDE菜单Project选择Settings项,在Download页下拉Category到Download项,在Download File选择root.cramfs文件,点击确定后:

点击IDE菜单DEBUG选择Download下载文件系统映象约1分钟

下载完毕后,点击Start(F5)然后在超级终端里输入: load flash root j(烧写更新文件系统)约1分钟即可烧写完毕

注意:只能在“vivi的烧写”操作完成后,才可以按以上方法正确烧写root映象到Nand Flash。

重起实验板,观测超级终端窗口提示信息,引导整个系统启动到linux行命令输入状态。

2.4.2根文件系统的制作(1)根文件系统

根文件系统是Linux系统的核心部分,包含系统使用的软件和库,以及所有用来为用户提供支持架构和用户使用的应用软件,并作为储存数据读写结果的区域。在Linux系统启动时,首先完成内核安装及环境初始化,最后会寻找一个文件系统作为根文件系统被加载。Linux系统中使用“/”来唯一表示根文件系统的安装路径。嵌入式系统中通常可以悬着的根文件系统有:Romfs、CRAMFS、RAMFS、JFFS2、EXT2等,甚至还可以使用NFS作为根文件系统。

(2)cramfs文件系统

Cramfs是Linux创始人Linux torvalds开发的一个适用于嵌入式系统的小文件系统。Cramfs是一个只读文件系统,采用zlib压缩,压缩比一般可以达到1:2,但仍可以做到高效的随机读取。Linux系统中,通常把需要修改的目录压缩存放,并在系统引导的时候再将压缩文件解开。因为cramfs不会影响系统读取文件的速度,而且是一个高度压缩的文件系统,因此非常广泛应用于嵌入式系统中。

(3)cygwin简介

Cygwin是一个在windows平台上运行的unix/Linux模拟环境,是cygnus solutions公司开发的自由软件。Cygwin中,“/”表示根目录,即cygwin的安 8

装目录。我们常用的set_env_linux.sh中定义的目录有:

SOURCEDIR:/tmp/edukit-2410存储了vivi、linux、fs等源代码和例程 WORKDIR:/usr/local/src/edukit-2410工作区。

一般情况下都要把已经规划好的目录结构转换成一个映象文件,即使用命令工具 mkcramfs(cygwin下为 mkcramfs.exe),把相应的 cramfs 目录树压缩为单一的映象文件。其命令格式为:

mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile 可以使用我们提供的 mkcramfs.exe 在 cygwin 下编译生成文件系统映象文件 root.cramfs,再固化到开发系统 FLASH 上运行。

(4)常用的Linux行命令

1)、cd 改变当前目录(文件夹)。例如下,cd/ 返回到根目录 cd..退回到上级目录

cd/tmp/edukit-2410/进入/tmp/edukit-2410/文件夹 2)、ls 列出当前目录中的内容。Ls 简单格式列表 ls–l 使用详细格式列表。3)、pwd 显示当前所在的目录。

(5)tar工具命令

tar 程序用于储存或展开 tar 存档文件。命令格式:

tar [-参数] [文件名][路径]-x :extract |--get 从存档展开文件-v :--verbose 详细显示处理的文件-j :--有 bz2 属性的必须包含

-f :--file [HOSTNAME:]F 指定存档或设备(缺省为 /dev/rmt0)

(6)解压原文件系统(命令+解压目录的存放)

1)先将 root.cramfs.tar.bz2文件放在C:cygwin目录中

2)解压文件系统

运行cygwin,执行以下命令解压安装:

$> source /tmp/edukit-2410/set_env_linux.sh Linux编译环境变量设置 $> cd /

$> tar-xvjf root.cramfs.tar.bz2 $> ls „ root „

root文件夹中就是我们想要的cramfs文件系统 3)如果在根目录中产生root文件夹,解压成功 4)在root目录中新建xx文件夹,用于存放应用程序

进入该目录后执行以下命令编译链接测试程序: $> cd root $>mkdir xx

(7)编译应用程序 ts.c(命令+生成文件格式+存放位置): 将编写好的ts.c程序放在C:cygwin目录中 进入该目录后执行以下命令编译链接测试程序: $> cd / $> arm-linux-gcc-o ts ts.c(也可以编写Makefile来编译)

生成文件: ts 如下图所示

将ts文件放入root 下的xx文件夹中

(8)新文件系统的制作: 把刚才编译输出的ts文件拷贝到文件系统所在的工作目录root目录下,执行以下命令生成新的文件系统映象: $> cd /

$> mkcramfs root root.new

刚刚编译生成的文件系统映象 root.new 中已经包含测试程序即生成文件。解压文件系统

解压成功如下

在root目录中新建xx文件夹,用于存放应用程序

将编写好的ts.c程序放在C:cygwin目录中

生成文件: ts 如下图所示

新文件系统的制作

生成文件:

第三章 程序

3.1.程序流程图:

3.2.分析驱动

触摸屏驱动在/kernel/drivers/char/s3c2410-ts.c 文件中。

3.2.1、触摸屏设备驱动中数据结构

(1)触摸屏的file_operations static struct file_operations s3c2410_fops={ owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read,release: s3c2410_ts_release, #ifdef USE_ASYNC fasync: s3c2410_ts_fasync,//异步通知

#endif poll: s3c2410_ts_poll,//轮询 };(2)触摸屏设备结构体的成员与按键设备结构体的成员类似,也包含一个缓冲区,同时包括自旋锁、等待队列和fasync_struct指针 typedef struct { unsigned int penStatus;/* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF];/* protect against overrun(环形缓冲区)*/ unsigned int head, tail;/* head and tail for queued events(环形缓冲区的头尾)*/ wait_queue_head_t wq;//* 等待队列数据结构 spinlock_t lock;//* 自旋锁

#ifdef USE_ASYNC struct fasync_struct *aq;#endif #ifdef CONFIG_PM struct pm_dev *pm_dev;//友善之臂专有的,我后面的代码删除了这段 #endif } TS_DEV;

(3)触摸屏结构体中包含的TS_RET值的类型定义,包含X、Y坐标和状态(PEN_DOWN、PEN_UP)等信息,这个信息会在用户读取触摸信息时复制到用户空 间

typedef struct { 14

unsigned short pressure;//* 压力,这里可定义为笔按下,笔抬起,笔拖曳

unsigned short x;//* 横坐标的采样值 unsigned short y;//* 纵坐标的采样值 unsigned short pad;//* 填充位 } TS_RET;

(4)在触摸屏设备驱动中,将实现open()、release()、read()、fasync()和poll()函数,因此,其文件操作结构体定义

触摸屏驱动文件操作结构体:static struct file_operations s3c2410_fops={} 3.2.2、触摸屏驱动模块加载和卸载函数

(1)在触摸屏设备驱动的模块加载函数中,要完成申请设备号、添加cdev、申请中断、设置触摸屏控制引脚(YPON、YMON、XPON、XMON)等多项工作 触摸屏设备驱动的模块加载函数

static int __init s3c2410_ts_init(void)触摸屏设备驱动模块卸载函数

static void __exit s3c2410_ts_exit(void)(2)可知触摸屏驱动中会产生两类中断,一类是触点中断(INT-TC),一类是X/Y位置转换中断(INT-ADC)。在前一类中断发生后,若之前处于PEN_UP状态,则应该启动X/Y位置转换。另外,将抬起中断也放在INT-TC处理程序中,它会调用tsEvent()完成等待队列和信号的释放 触摸屏设备驱动的触点/抬起中断处理程序

static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)

当X/Y位置转换中断发生后,应读取X、Y的坐标值,填入缓冲区 触摸屏设备驱动X/Y位置转换中断处理程序

static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)触摸屏设备驱动中获得X、Y坐标

static inline void s3c2410_get_XY(void)(3)tsEvent最终为tsEvent_raw(),这个函数很关键,当处于PEN_DOWN状态时调用该函数,它会完成缓冲区的填充、等待队列的唤醒以及异步通知信号的释放;否则(处于PEN_UP状态),将缓冲区头清0,也唤醒等待队列并释放信号

触摸屏设备驱动的tsEvent_raw()函数 static void tsEvent_raw(void)(4)在包含了对拖动轨迹支持的情况下,定时器会被启用,周期为10ms,在每次定时器处理函数被引发时,调用start_ts_adc()开始X/Y位置转换过程

触摸屏设备驱动的定时器处理函数

static void ts_timer_handler(unsigned long data)(5)在触摸屏设备驱动的打开函数中,应初始化缓冲区、penStatus和定期器、等待队列及tsEvent时间处理函数指针 触摸屏设备驱动的打开函数

static int s3c2410_ts_open(struct inode *inode, struct file *filp)16

(6)触摸屏设备驱动的释放函数非常简单,删除为用于拖动轨迹所使用的定时器即可

触摸屏设备驱动的释放函数

static int s3c2410_ts_release(struct inode *inode, struct file *filp)3.2.3、触摸屏设备驱动的读函数

触摸屏设备驱动的读函数实现缓冲区中信息向用户空间的复制,当缓冲区有内容时,直接复制;否则,如果用户阻塞访问触摸屏,则进程在等待队列上睡眠,否则,立即返回-EAGAIN 触摸屏设备驱动的读函数

static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)3.2.4、触摸屏设备驱动的轮询与异步通知

在触摸屏设备驱动中,通过s3c2410_ts_poll()函数实现了轮询接口,这个函数的实现非常简单。它将等待队列添加到poll_table,当缓冲区有数据时,返回资源可读取标志,否则返回0 触摸屏设备驱动的poll()函数

static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait)而为了实现触摸屏设备驱动对应用程序的异步通知,设备驱动中要实现s3c2410_ts_fasync()函数 触摸屏设备驱动的fasync()函数

static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)3.2.5源程序触摸屏驱动代码:

/* * s3c2410-ts.c * * touchScreen driver for SAMSUNG S3C2410 * * Author: Janghoon Lyu * Date : $Date: 2002/06/04 07:11:00 $ * * $Revision: 1.1.2.6 $ * * Based on pt036001b-ts.c * * This file is subject to the terms and conditions of the GNU General Public * License.See the file COPYING in the main directory of this archive * for more details.* * History: * * 2002-05-27: Janghoon Lyu *PM 内靛啊 甸绢啊 乐变 窍瘤父 抛胶飘 登瘤 臼疽澜.* */

#include #include #include #include

#include #include #include #include #include #include #include

#include

#ifdef CONFIG_PM #include #endif

/* debug macros */ #undef DEBUG #ifdef DEBUG #define DPRINTK(x...)printk(“s3c2410-ts: ” ##x)#else #define DPRINTK(x...)#endif

#define PEN_UP 0

#define PEN_DOWN 1 #define PEN_FLEETING 2 #define MAX_TS_BUF 16 /* how many do we want to buffer */

#undef USE_ASYNC 1 #define DEVICE_NAME “s3c2410-ts” #define TSRAW_MINOR 1

typedef struct { unsigned int penStatus;/* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF];/* protect against overrun */ unsigned int head, tail;/* head and tail for queued events */ wait_queue_head_t wq;spinlock_t lock;#ifdef USE_ASYNC struct fasync_struct *aq;#endif #ifdef CONFIG_PM struct pm_dev *pm_dev;#endif } TS_DEV;

static TS_DEV tsdev;

#define BUF_HEAD(tsdev.buf[tsdev.head])#define BUF_TAIL(tsdev.buf[tsdev.tail])#define INCBUF(x,mod)((++(x))&((mod)-1))

static int tsMajor = 0;

static void(*tsEvent)(void);

#define HOOK_FOR_DRAG #ifdef HOOK_FOR_DRAG #define TS_TIMER_DELAY(HZ/100)/* 10 ms */ static struct timer_list ts_timer;#endif

#define wait_down_int(){ ADCTSC = DOWN_INT | XP_PULL_UP_EN |

XP_AIN | XM_HIZ | YP_AIN | YM_GND |

XP_PST(WAIT_INT_MODE);} #define wait_up_int(){ ADCTSC = UP_INT | XP_PULL_UP_EN | XP_AIN | XM_HIZ |

YP_AIN | YM_GND | XP_PST(WAIT_INT_MODE);} #define mode_x_axis(){ ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ |

XP_PULL_UP_DIS | XP_PST(X_AXIS_MODE);} #define mode_x_axis_n(){ ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ |

XP_PULL_UP_DIS | XP_PST(NOP_MODE);} #define mode_y_axis(){ ADCTSC = XP_AIN | XM_HIZ | YP_EXTVLT | YM_GND |

XP_PULL_UP_DIS | XP_PST(Y_AXIS_MODE);} #define start_adc_x(){ ADCCON = PRESCALE_EN | PRSCVL(49)|

ADC_INPUT(ADC_IN5)| ADC_START_BY_RD_EN |

ADC_NORMAL_MODE;

ADCDAT0;} #define start_adc_y(){ ADCCON = PRESCALE_EN | PRSCVL(49)|

ADC_INPUT(ADC_IN7)| ADC_START_BY_RD_EN |

ADC_NORMAL_MODE;

ADCDAT1;} #define disable_ts_adc(){ ADCCON &= ~(ADCCON_READ_START);}

static int adc_state = 0;static int x, y;/* touch screen coorinates */

static void tsEvent_raw(void){ if(tsdev.penStatus == PEN_DOWN){

BUF_HEAD.x = x;

BUF_HEAD.y = y;

BUF_HEAD.pressure = PEN_DOWN;

#ifdef HOOK_FOR_DRAG

ts_timer.expires = jiffies + TS_TIMER_DELAY;

add_timer(&ts_timer);#endif } else { #ifdef HOOK_FOR_DRAG

del_timer(&ts_timer);#endif

BUF_HEAD.x = 0;

BUF_HEAD.y = 0;

BUF_HEAD.pressure = PEN_UP;}

tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF);wake_up_interruptible(&(tsdev.wq));

#ifdef USE_ASYNC if(tsdev.aq)

kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);#endif

#ifdef CONFIG_PM pm_access(tsdev.pm_dev);#endif }

static int tsRead(TS_RET * ts_ret){ spin_lock_irq(&(tsdev.lock));ts_ret->x = BUF_TAIL.x;ts_ret->y = BUF_TAIL.y;ts_ret->pressure = BUF_TAIL.pressure;tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF);spin_unlock_irq(&(tsdev.lock));

return sizeof(TS_RET);}

static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){ TS_RET ts_ret;

retry: if(tsdev.head!= tsdev.tail){

int count;

count = tsRead(&ts_ret);

if(count)copy_to_user(buffer,(char *)&ts_ret, count);

return count;} else {

if(filp->f_flags & O_NONBLOCK)

return-EAGAIN;

interruptible_sleep_on(&(tsdev.wq));

if(signal_pending(current))

return-ERESTARTSYS;

goto retry;}

return sizeof(TS_RET);}

#ifdef USE_ASYNC static int s3c2410_ts_fasync(int fd, struct file *filp, int mode){ return fasync_helper(fd, filp, mode, &(tsdev.aq));} #endif

static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait){ poll_wait(filp, &(tsdev.wq), wait);return(tsdev.head == tsdev.tail)? 0 :(POLLIN | POLLRDNORM);}

static inline void start_ts_adc(void){ adc_state = 0;mode_x_axis();start_adc_x();}

static inline void s3c2410_get_XY(void){ if(adc_state == 0){

adc_state = 1;

disable_ts_adc();

y =(ADCDAT0 & 0x3ff);

mode_y_axis();

start_adc_y();} else if(adc_state == 1){

adc_state = 0;

disable_ts_adc();

x =(ADCDAT1 & 0x3ff);

tsdev.penStatus = PEN_DOWN;

DPRINTK(“PEN DOWN: x: %08d, y: %08dn”, x, y);

wait_up_int();

tsEvent();} }

static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg){ #if 0 DPRINTK(“Occured Touch Screen Interruptn”);DPRINTK(“SUBSRCPND = 0x%08lxn”, SUBSRCPND);#endif spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_UP)s3c2410_get_XY();#ifdef HOOK_FOR_DRAG else s3c2410_get_XY();#endif spin_unlock_irq(&(tsdev.lock));}

static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg){ #if 0 DPRINTK(“Occured Touch Screen Interruptn”);DPRINTK(“SUBSRCPND = 0x%08lxn”, SUBSRCPND);#endif spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_UP){ start_ts_adc();} else { tsdev.penStatus = PEN_UP;DPRINTK(“PEN UP: x: %08d, y: %08dn”, x, y);wait_down_int();tsEvent();

} spin_unlock_irq(&(tsdev.lock));}

#ifdef HOOK_FOR_DRAG static void ts_timer_handler(unsigned long data){ spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_DOWN){

start_ts_adc();} spin_unlock_irq(&(tsdev.lock));} #endif

static int s3c2410_ts_open(struct inode *inode, struct file *filp){ tsdev.head = tsdev.tail = 0;tsdev.penStatus = PEN_UP;#ifdef HOOK_FOR_DRAG init_timer(&ts_timer);ts_timer.function = ts_timer_handler;#endif tsEvent = tsEvent_raw;init_waitqueue_head(&(tsdev.wq));

MOD_INC_USE_COUNT;return 0;}

static int s3c2410_ts_release(struct inode *inode, struct file *filp){ #ifdef HOOK_FOR_DRAG del_timer(&ts_timer);#endif MOD_DEC_USE_COUNT;return 0;}

static struct file_operations s3c2410_fops = { owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read,release: s3c2410_ts_release,#ifdef USE_ASYNC fasync: s3c2410_ts_fasync, #endif poll: s3c2410_ts_poll, };

void tsEvent_dummy(void){} #ifdef CONFIG_PM static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,void *data){ switch(req){

case PM_SUSPEND:

tsEvent = tsEvent_dummy;

break;

case PM_RESUME:

tsEvent = tsEvent_raw;

wait_down_int();

break;} return 0;} #endif

#ifdef CONFIG_DEVFS_FS static devfs_handle_t devfs_ts_dir, devfs_tsraw;#endif static int __init s3c2410_ts_init(void){ int ret;

tsEvent = tsEvent_dummy;

ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);if(ret < 0){ printk(DEVICE_NAME “ can't get major numbern”);return ret;} tsMajor = ret;

/* set gpio to XP, YM, YP and YM */ #if 0 set_GPIO_mode(GPIO106_nYPON_MD);

set_GPIO_mode(GPIO105_YMON_MD);set_GPIO_mode(GPIO104_nXPON_MD);set_GPIO_mode(GPIO103_XMON_MD);

GPUP(GPIO106_nYPON)|= GPIO_bit(GPIO106_nYPON);GPUP(GPIO105_YMON)&= GPIO_bit(GPIO105_YMON);GPUP(GPIO104_nXPON)|= GPIO_bit(GPIO104_nXPON);GPUP(GPIO103_XMON)&= GPIO_bit(GPIO103_XMON);#else set_gpio_ctrl(GPIO_YPON);set_gpio_ctrl(GPIO_YMON);set_gpio_ctrl(GPIO_XPON);set_gpio_ctrl(GPIO_XMON);#endif

/* Enable touch interrupt */ ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT,DEVICE_NAME, s3c2410_isr_adc);if(ret)goto adc_failed;ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT,DEVICE_NAME, s3c2410_isr_tc);if(ret)goto tc_failed;

/* Wait for touch screen interrupts */ wait_down_int();

#ifdef CONFIG_DEVFS_FS devfs_ts_dir = devfs_mk_dir(NULL, “touchscreen”, NULL);devfs_tsraw = devfs_register(devfs_ts_dir, “0raw”, DEVFS_FL_DEFAULT,tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,&s3c2410_fops, NULL);#endif

#ifdef CONFIG_PM #if 0 tsdev.pm_dev = pm_register(PM_GP_DEV, PM_USER_INPUT,s3c2410_ts_pm_callback);#endif tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT,s3c2410_ts_pm_callback);#endif printk(DEVICE_NAME “ initializedn”);

return 0;tc_failed: free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);adc_failed: return ret;}

static void __exit s3c2410_ts_exit(void){ #ifdef CONFIG_DEVFS_FS

devfs_unregister(devfs_tsraw);devfs_unregister(devfs_ts_dir);#endif unregister_chrdev(tsMajor, DEVICE_NAME);#ifdef CONFIG_PM pm_unregister(tsdev.pm_dev);#endif free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);free_irq(IRQ_TC, s3c2410_isr_tc);}

module_init(s3c2410_ts_init);module_exit(s3c2410_ts_exit);触摸屏应用程序

#include #include #include /* 文件操作 */

#define PEN_UP 0 /* 触摸笔抬笔,即触摸屏不被压下 */ #define PEN_DOWN 1 /* 触摸笔下笔,即触摸屏被压下 */ #define PEN_FLEETING 2 /* 触摸笔拖动 */

typedef struct { unsigned short pressure;/* 触摸笔动作 */ unsigned short x;

/* 触点x座标值 */ unsigned short y;

/* 触点y座标值 */ unsigned short pad;}TS_RET;

int main(){ int fd,ret,i;

unsigned char suba;TS_RET tsret;

fd = open(“/dev/touchscreen/0raw”, O_RDWR);/* 打开设备 */ if(fd ==-1){ printf(“nCan't open I2C device!n”);exit(-1);}

while(1){

ret = read(fd,(char *)&tsret, sizeof(TS_RET));

if(ret!= sizeof(TS_RET))

{

printf(“read touch screen error!”);

close(fd);

exit(-1);

}

else

{

printf(“pressure is: %dn”, tsret.pressure);

printf(“x is: %dn”, tsret.x);

printf(“y is: %dn”, tsret.y);

} }

close(fd);return 0;} 3.3.应用程序的调试

使用s3c2410_ts.c触摸屏驱动编写应用程序,读取触摸屏的触点坐标值及动作信息(触点x坐标值,y坐标及是否有压力值press),并在串口中断打印出来

对触摸屏设别的操作有打开设备,关闭设备,读操作等。编写应用程序读取触摸屏的触点坐标值及动作信息时,只需利用触摸屏驱动程序便可实现,先打开触摸屏设备,然后调用读函数即可。

其中,触摸笔动作取值如下: #define PEN_UP 0 #define PEN_DOWN

/* 触摸笔抬笔,即触摸屏不被压下 */ /* 触摸笔下笔,即触摸屏被压下 */

#define PEN_FLEETING 2 结构体定义如下: typedef struct { unsigned short pressure;unsigned short x;unsigned short y;unsigned short pad;}TS_RET 打开应用程序:

/* 触摸笔拖动 */

/* 触摸笔动作 */ /* 触点x座标值 */ /* 触点y座标值 */

3.2.6、实验结果显示:

第四部分 感想

第四部分 心得

4.1 课程设计心得体会:

为期几天的课程设计结束了,再次期间我积极亲自实验,用的目标板是s3c2410核心子板,用JTAG仿真器,用Cygwin模拟软件来学习触摸板的设计。我学会了很多,学会了很多。

首先我扪主要了解整个设计过程,以及实验环境的建立,这次用的是交叉编译环境,通过这次课设我更清楚搭建嵌入式系统的开发平台,我们用的目标板是s3c2410核心子板,用JTAG仿真器,用Cygwin模拟软件,课设的这几天我学会了熟练的使用Cygwin软件,掌握了一些常用的命令,加上研究生学长给我们的指导,知道了如何学习,如何思考,知道了运linux操作系统开发嵌入式与wince操作系统开发嵌入式的区别。

其次是学会vivi,内核,根文件系统的编译与移植(烧写),通过这个过程我熟悉了怎么把软件固化到硬件上,知道了软件怎么控制硬件,这个步骤很重要,要烧写不成功,目标板系统就运行不起来,实验就失败了,这个过程我们练习了好多变呢,大家都很累哦!

再次我们就开始写我们的应用程序,通过以上步骤实验系统搭建好了,只要调试好应用程序,然后再运行成功就行了,为此我又把课本上讲得触摸屏原理那章认真看了,又看了实验指导书,查资料,上网搜索,终于编出应用程序,经过不断的调试才编译成功,这个过程太辛苦了,加上实验板不太好,真是对我们的挑战,不过看到运行的 30

结果,大家都很高兴,也很有成就感啊!还看懂了一些s3c2410的驱动程序的源代码,了解了s3c2410一些控制器的使用,以及s3c2410A的一些接口原理与应用。

我明白了只有不断的努力,不断的学习,才能在将来遇到的问题中能够游刃有余,才能够不会捉襟见肘。

第五部分 参考文献

5.1【参考文献】 程昌南,方强等.《ARM Linux入门与实践 》【M】.北京:北京航空航天大学出版社,2008.10 2 张晓林等.《嵌入式系统设计与实践》【M】.北京:北京航空航天大学出版社,2006.1 3 李俊等.《嵌入式Linux设备驱动开发详解》【M】.北京:北京人民邮电出版社,2008.3 4 黄智伟,邓月明,王彦.《ARM9嵌入式系统设计基础教程》.北京:北京航空航天大学出版社,2008.8 5 [美]Wayne Wolf.嵌入式计算系统设计原理.孙玉芳, 梁彬 罗保国 等译.北京: 机械工业出版社, 2002 李剑, 赵鹏程, 汤建彬.32位ARM嵌入式处理器的调试技术.电子技术应用, 2003,(3)钟汉如, 王创生.嵌入式Linux的中断处理与实时调度的实现机制.计算机工程, 2002, 28(10)Arnold Berger.嵌入式系统设计.吕骏 译.北京: 电子工业出版社, 2002

第二篇:嵌入式程序设计课程设计

课程设计

课 程 名嵌入式软件开发技术

题 目 基于嵌入式Linux的温度监测系统的

设计与实现

专 业 计算机科学与技术(嵌入式系统方向)班 级 13计算机嵌入式系统班 学 号 学生姓名

2016年6月

摘要

温度是个很普遍而又非常重要的参数,在日常生活、工农业生产以及科研领域都有着广泛的应用。因此,研制能够准确地测量和记录这个参数值的系统具有十分重要的意义。

基于ARM的嵌入式温度监测系统是采用嵌入式Linux作为操作系统,针对以S5PV210为处理器的开发板设计的一个嵌入式温度监测系统。论文在分析了Linux设备驱动程序的基本工作原理基础上,讨论了开发中经常会碰到的中断处理、拥塞处理、I/O端口,并在此基础上实现了基于S5PV210嵌入式处理器的开、读、写、关外部RAM的字符设备驱动和网络驱动。结合高精度温度传感器DS18B20,实现温度的正确采集,并通过以太网络将数据上传给上位机客户端。

论文首先介绍了通信网络中各种设备特性、总线结构及传输技术,然后根据单片机与PC机之间的串行通信原理,用ubantu完成温度监测系统的软件设计与实现,为用户提供一个友好的人机界面,对监测系统进行控制并显示采集后的数据。本系统还通过多线程实现了多个客户端与服务器的通信。

关键词:S5PV210;嵌入式Linux操作系统;DS18B20;网络编程

I

Abstract

Temperature is a very common and very important parameter, in daily life, industrial and agricultural production and scientific research fields have a wide range of applications.Therefore, it is very important to develop a system that can accurately measure and record the value of this parameter.The temperature monitoring system of base on the ARM is use of embedded Linux as the operating system for the processor to S5PV210 development board designed for an embedded temperature monitoring system.Based on the analysis of the basic working principle based on the Linux device drivers discussed development often encounter interrupt handling, congestion handling, I / O ports, and on this basis to achieve the embedded processor based on open S5PV210 reading, writing, characters off the external RAM device driver and network drives.Combined with precision temperature sensor DS18B20, to achieve the correct temperature acquisition, and upload the data via Ethernet to a PC client.At first,the paper introduces the characteristics of various devices in a communication network, the bus structure and transmission technology, and according to the principle of serial communication between SCM and PC, with ubantu complete temperature monitoring system software design and implementation, to provide users with a friendly man-machine interface, the monitoring system to control and display the data after collection.The system also enables communication via a plurality of multi-threaded client and the server.Key words:S5PV210;embedded Linux operating system;DS18B20;Network programming

II

1.引言.......................................................................................................................................1 1.1 设计背景及意义...............................................................................................................1 1.2 设计的主要内容................................................................................................................2 2.相关技术...............................................................................................................................2 2.1 嵌入式Linux......................................................................................................................2 2.2 S5PV210.............................................................................................................................3 2.3 socket网络编程..............................................................................................................3 3.具体实现功能.......................................................................................................................4 3.1总体框架图........................................................................................................................4 3.2客户端功能........................................................................................................................5 3.3 服务器功能........................................................................................................................5 3.4 实验板输出信息...............................................................................................................5 4.具体实现过程.......................................................................................................................6 4.1 交叉编译工具的安装.......................................................................................................6 4.2 客户端模块的设计...........................................................................................................7 4.3 服务器模块.......................................................................................................................8 4.4 LED点亮模块..................................................................................................................10 4.5 温度感应模块.................................................................................................................11 5.测试结果分析.....................................................................................................................13 5.1 各模块运行的效果.........................................................................................................13 5.2 可扩展功能......................................................................................................................15 6.总结与展望.......................................................................................................................15

第一章 引言

1.1 设计背景及意义

温度作为工业、农业、国防和科研等部门最普遍的测量项目。它在工农业生产、现代科学研究以及高新技术开发过程中也是一个极其普遍而又非

常重要的参数。因此,在这些领域中,对于这个参数的测量与控制就显得尤为重要,特别是在纺织工业、冶金、化工、食品、温室种植,汽车制造以及气象预报和科研实验室等许多地方,都具有举足轻重的作用。

以往这些工作大多是由人工完成,不但工作量大,记录的数据少,对温度的调节缺乏实时性,而且电路复杂,标定和校准也比较麻烦,难以满足现代温度测量的要求[1]。自从传感器技术、微控制器技术和计算机技术日渐成熟之后,现代的温度测量与控制系统克服了以往系统中存在的一些问题,比如对环境温度的控制与调节以及数据的记录都由微控制器或计算机自动完成,人们的工作量大大地降低,而且测得的数据也更加的精确,对环境温度的调节更具有实时性[2]。

1.2 设计的主要内容

此次主要采用嵌入式Linux作为操作系统,针对以S5PV210为处理器的开发板设计的一个嵌入式温度监测系统。在Linux设备驱动程序的基本工作原理基础上,讨论了开发中经常会碰到的中断处理、拥塞处理、I/O端口,并在此基础上实现了基于S5PV210嵌入式处理器的开、读、写、关外部RAM的字符设备驱动和网络驱动。结合高精度温度传感器DS18B20,实现温度的正确采集,并通过以太网络将数据上传给上位机客户端。

温度监测系统根据Linux中的网络通信技术和串口通信技术来传输数据。用ubantu完成温度监测系统的软件设计与实现,为用户提供一个友好的人机界面,对监测系统进行控制并显示采集后的数据。本系统还通过多线程实现了多个客户端与服务器的通信。

第二章 相关技术

2.1 嵌入式Linux Linux是UNIX系统的一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行主要的UNIX工具软件、应用程序和网络协议。支持32位和64位硬件。Linux继承了Unix以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。它诞生与1991年的10月5日。以后借助与Internet

网,并进过全世界各地计算机爱好者的共同努力下,现已成为世界上使用最多的一种UNIX类操作系统,并且使用人数还在迅猛增涨。

本次设计采用Linux作为嵌入式操作系统的原因有以下几点:[3] 1)低成本开发系统: 2)可应用于多种硬件平台 3)可定制的内核 4)性能优异 5)良好的网络支持

2.2 S5PV210

S5PV210又名“蜂鸟”(Hummingbird),是三星推出的一款适用于智能手机和平板电脑等多媒体设备的应用处理器。

S5PV210采用了ARM CortexTM-A8内核,ARM V7指令集,主频可达1GHZ,64/32位内部总线结构,32/32KB的数据/指令一级缓存,512KB的二级缓存,可以实现2000DMIPS(每秒运算20亿条指令集)的高性能运算能力。

包含很多强大的硬件编解码功能,内建MFC(Multi Format Codec),支持MPEG-1/2/4,H.263,H.264等格式视频的编解码,支持模拟/数字TV输出。JPEG硬件编解码,最大支持8000x8000分辨率

内建高性能PowerVR SGX540 3D图形引擎和2D图形引擎,支持2D/3D图形加速,是第五代PowerVR产品,其多边形生成率为2800万多边形/秒,像素填充率可达2.5亿/秒,在3D和多媒体方面比以往大幅提升,能够支持DX9,SM3.0,OpenGL2.0等PC级别显示技术。

具备IVA3硬件加速器,具备出色的图形解码性能,可以支持全高清、多标准的视频编码,流畅播放和录制30帧/秒的1920×1080像素(1080p)的视频文件,可以更快解码更高质量的图像和视频,同时,内建的HDMIv1.3,可以将高清视频输出到外部显示器上。

2.3 socket网络编程

Socket是进程通讯的一种方式,即调用这个网络库的一些API函数实现分布在不同主机的相关进程之间的数据交换。[4] 几个定义:

(1)IP地址:即依照TCP/IP协议分配给本地主机的网络地址,两个进程要通讯,任一进程首先要知道通讯对方的位置,即对方的IP。

(2)端口号:用来辨别本地通讯进程,一个本地的进程在通讯时均会占用一个端口号,不同的进程端口号不同,因此在通讯前必须要分配一个没有被访问的端口号。

(3)连接:指两个进程间的通讯链路。

(4)半相关:网络中用一个三元组可以在全局唯一标志一个进程:(协议,本地地址,本地端口号)

这样一个三元组,叫做一个半相关,它指定连接的每半部分。(4)全相关:一个完整的网间进程通信需要由两个进程组成,并且只能使用同一种高层协议。也就是说,不可能通信的一端用TCP协议,而另一端用UDP协议。因此一个完整的网间通信需要一个五元组来标识:(协议,本地地址,本地端口号,远地地址,远地端口号)

这样一个五元组,叫做一个相关(association),即两个协议相同的半相关才能组合成一个合适的相关,或完全指定组成一连接。

第三章 具体实现功能

3.1总体框架图

图1 项目总体框架图

3.2客户端功能

1)显示简单的用户界面 2)发送命令给服务器 3)接收服务器传输的数据 4)显示温度数据

3.3 服务器功能

1)接收客户端发送的命令 2)处理命令

3)把命令转发给硬件 4)获取硬件处理所得的数据 5)把该数据传给客户端

3.4 实验板输出信息

1)LED灯按照客户端的指令亮灭 2)蜂鸣器唱歌

3)核心板控制输出温度传感器的数据到服务器

第四章 具体实现过程

个应用系统要完成各项功能,首先必须有较完善的硬件作保证。同时还必须得到相应设计合理的软件的支持,尤其是微机应用高速发展的今天,许多由硬件完成的工作,都可通过软件编程而代替。甚至有些必须采用很复杂的硬件电路才能完成的工作,用软件编和有时会变得很简单。因此充分利用其内部丰富的硬件资源和软件资源。

程序设计语言有三种:机器语言、汇编语言、高级语言。本系统运用的是高级语言所编写,也就是C语言。所用到的开发平台为ubuntu系统。

4.1 交叉编译工具的安装

(1)考虑到现今Linux平台发展,交叉编译平台编统一为arm-linux-gcc-4.4.3(2)在windows系统下,建立一个共享目录,如:e:/linux_file(3)将光盘目录linux中的arm-linux-gcc-4.4.3.tar.gz 复制到e:/linux_file(4)注意在进行虚拟机设置时使共享目录的有效,并添加共享目录e:/linux_file(5)进入linux操作系统,root目录下建立一个Armcode的子目录,将共享目录下的文件arm-linux-gcc-4.4.3.tar.gz复制到该目录(6)然后进入到该目录,执行解压命令:#cd /root/Armcode;#tar xvzf arm-linux-gcc-4.4.3.tgz –C /;注意:C 后面有个空格,并且C 是大写的,它是英文单词“Change”的第一个字母,在此是改变目录的意思。(7)执行

令,将

arm-linux-gcc

到/opt/FriendlyARM/toolschain /4.4.3/bin 目录。

(8)把编译器路径加入系统环境变量,运行命令:#gedit /root/.bashrc 编辑/root/.bashrc 文件,在最后一行添加:export PATH=$PATH: /opt/FriendlyARM/toolschain/4.4.3/bin(9)重新登录系统(不必重启机器,开始->logout 即可),使以上设置生效,在命令行输入:arm-linux-gcc –v,会出现如下信息,这说明交叉编译环境已经成功安装。

4.2 客户端模块的设计

用户界面的显示:

void interface_print(char *temp){ system(“clear”);printf(“e[31m*******************2016梧*********************e[0mn”);printf(“e[31m*

*e[0mn”);printf(“e[31m*e[0m e[32m点亮LED1: on1

on2e[0me[31m

*e[0mn”);printf(“e[31m*e[0m e[33m关闭LED1: off1

off2e[0me[31m

*e[0mn”);printf(“e[31m*e[0m e[34m开蜂鸣器: onb

songe[0me[31m

*e[0mn”);printf(“e[31m*e[0m e[35m获取温度: get

e[31m *e[0mn”,temp);printf(“e[31m*e[0m e[36m退

出: e[0me[31m

*e[0mn”);printf(“e[31m*

*e[0mn”);printf(“e[31m******************未

来**********************e[0mn”);}

发送命令给服务器:

/*5.调用I/O函数(read/write)与客户端通讯。*/ int i = 5;int pos;while(1){

ret = poll(pfd,2,-1);

if(ret > 0){

if(pfd[0].revents == POLLIN){

interface_print(temp);

/*从终端读取数据*/

memset(buf,0,sizeof(buf));

ret = read(pfd[0].fd,buf,sizeof(buf)-1);7

州学院

|

点亮LED2:

|

关闭LED2:

|

播放音乐:

|

温度:[%s]e[0m quit

|

的大

} if(ret > 0){

}

/*发送数据给服务器*/ write(sockfd,buf,ret);

接受服务器传输的数据:

if(pfd[1].revents == POLLIN){

if(!strncmp(buf,“get”,3)){

/*接收服务器发送的信息*/

memset(temp,0,sizeof(temp));

ret = read(pfd[1].fd,temp,sizeof(temp)-1);

if(ret > 0){

temp[ret-1] = '';

/*把信息显示到终端*/

interface_print(temp);

}

} } 4.3 服务器模块

接收客户端发送的命令:

/*读取客户端信息*/

memset(buf,0,sizeof(buf));

ret = read(newfd,buf,sizeof(buf)-1);

if(ret > 0){

把命令转发给硬件:

/*发送命令给硬件*/

if(!strncasecmp(buf,“on1”,3)){

cmd = LED_ON;

val = 3;

}else if(!strncasecmp(buf,“on2”,3)){

cmd = LED_ON;

val = 4;

}else if(!strncasecmp(buf,“off1”,4)){

cmd = LED_OFF;

val = 3;

}else if(!strncasecmp(buf,“off2”,4)){

cmd = LED_OFF;

}

val = 4;

}else if(!strncasecmp(buf,“onb”,3)){

pwm_on();

}else if(!strncasecmp(buf,“song”,4)){

pwm_music_fun();

}

if(ioctl(fd_led,cmd,(unsigned long)val)< 0){

perror(“ioctl failedn”);

exit(1);

} } } return(void *)0;

获取硬件处理所得的数据:

void *do_temp(void *arg){ int newfd = *(int *)arg;char buf[100];int dev_fd;unsigned int temp[2];float tempvalue=0;unsigned pos;

dev_fd = open(“/dev/fs210_gpio”,O_RDWR | O_NONBLOCK);if(dev_fd < 0){

perror(“open”);

exit(1);}

while(1){

temp[1]= ioctl(dev_fd,GPIO_ON,temp);

/*

temp[1]&=0xffff;

tempvalue=(float)(temp[1])*0.0625;

*/

if(temp[1]&0x8000)

{

temp[1]= ~temp[1]+1;

temp[1]&=0xffff;

tempvalue=(float)(temp[1])*0.0625;

} } else {

temp[1]&=0xffff;

tempvalue=(float)(temp[1])*0.0625;} memset(buf,0,sizeof(buf));sprintf(buf,“%f”,tempvalue);strcat(buf,“n”);write(newfd,buf,strlen(buf));memset(buf,0,sizeof(buf));sleep(1);} return(void *)0;4.4 LED点亮模块

/*参考内核,采用静态的方式实现点灯和灭灯*/ void led_on(unsigned long val){ printk(“ %ld %sn”,val,__func__);gpio_set_value(S5PV210_GPC0(val),1);}

void led_off(unsigned long val){ printk(“ %ld %sn”,val,__func__);gpio_set_value(S5PV210_GPC0(val),0);}

long test_ioctl(struct file *file, unsigned int cmd, unsigned long data){ unsigned long val = data;switch(cmd){

case LED_ON:

led_on(val);

break;

case LED_OFF:

led_off(val);

break;

default:

break;

}

} return 0;/*向系统注册申请设备号*/ ret = register_chrdev(LED_MAJOR,LED_NAME,&led_fops);if(ret){ printk(“register chrdev failed!n”);errno =-EBUSY;

goto err1;}

/*创建一个设备类*/ led_dev->led_class = class_create(THIS_MODULE, LED_MODULE);if(IS_ERR(led_dev->led_class)){ printk(“class create failedn”);errno = PTR_ERR(led_dev->led_class);goto err2;} /*创建一个设备文件,之后系统会自动在/dev目录下自动创建一个设备文件*/ led_dev->led_device = device_create(led_dev->led_class,NULL,MKDEV(LED_MAJOR,0),NULL,“led”);if(IS_ERR(led_dev->led_device)){

printk(“class create failedn”);

errno = PTR_ERR(led_dev->led_device);

goto err3;} led_init();

return 0;

4.5 温度感应模块

static void WriteOneChar(unsigned char dat){ unsigned char i=0;

writel((readl(gph1con)& 0xFFFFFFF0)| 0x1, gph1con);//gph1_0,output spin_lock(&lock);for(i=0;i<8;i++){

writel(readl(gph1dat)&(0xFFFFFFFE), gph1dat);

__udelay(15);

if(dat&0x01){

writel(readl(gph1dat)| 0x1 , gph1dat);

}

else{

writel(readl(gph1dat)&(0xFFFFFFFE), gph1dat);

}

__udelay(45);

writel(readl(gph1dat)| 0x1 , gph1dat);

__udelay(1);

dat>>=1;} spin_unlock(&lock);}

static unsigned int ReadTemp(void){ unsigned char T_h=0;unsigned char T_l=0;unsigned int temp=0;

writel((readl(gph1pud)& 0xFFFc)| 0x02, gph1pud);//gph1_0,pull-up enabled

spin_lock(&lock);Init_DS18B2O();spin_unlock(&lock);__udelay(400);writel((readl(gph1con)& 0xFFFFFFF0)| 0x1, gph1con);//gph1_0,output writel(readl(gph1dat)| 0x1 , gph1dat);WriteOneChar(0xcc);WriteOneChar(0x44);mdelay(100);spin_lock(&lock);Init_DS18B2O();spin_unlock(&lock);__udelay(400);writel((readl(gph1con)& 0xFFFFFFF0)| 0x1, gph1con);//gph1_0,output writel(readl(gph1dat)| 0x1 , gph1dat);WriteOneChar(0xcc);WriteOneChar(0xBE);T_l=ReadOneChar();//L T_h=ReadOneChar();//H

temp=(unsigned int)(((unsigned int)T_h<<8)|T_l);

printk(“temp=%xrn”,temp);

return temp;}

第五章5.1 各模块运行的效果

客户端:

测试结果分析13

图2 客户端运行效果

服务器:

图3 服务器运行效果

开发板:

图4 开发板的显示效果

5.2 可扩展功能

本项目的只是完成其中的一些功能,其可扩展性强,对进行加强完善,还可作如下扩展:

1.拓展成温度报警器,设定一个上限值和下下限值,当温度达到某个值时,如低于20摄氏度时,LED灯亮,高于40摄氏度时,蜂鸣器发出报警提示音。

2.可使开发板的核心板链接生活中的物件,如台灯,或者房间的灯,从而控制生活中物件的开关。

3.找到家庭电器中的接口,连接相应接口可实现远程控制家电。

第六章 总结与展望

通过这次的课程设计,让我受益匪浅,让我对智能硬件有了更深一层的了解,也体会了智能化在现实生活中的重要性,也让我了解和掌握了一些编程思想。让

我把理论知识用在实践中,实现了理论和实践相结合,从中更懂得理论的是实践的基础,实践有能检验理论的正确性,更激发了我对专业知识的渴求,这些对我以后参加工作或者继续学习都会有很大的帮助和影响。通过这次课程设计,让我意识到了自己的一些不足,从而让我认识到了学习的重要性。

虽然这次实训是那么短暂的1周时间,但是这几天我所学到的还是很多的,通过此次培训学生运用本专业所学的理论知识和专业知识来分析解决实际问题的重要教学环节,是对三年所学知识的复习和巩固。同时通过这次培训让我明白了一个很深刻的道理,让我意识到了团队合作的重要性,一个人不能完成的事情,团队能完成。团队精神有利于提高组织整体效能,只有通过发扬团队精神,才能取得更好的成绩。

因时间及精力有限,系统做的还不是很完善,还是有不足的地方,如果时间充足的话,还可以做得更完善,对其进行功能扩展。

以上这些收获对我来说是非常有帮助的,让我受益匪浅,它也是我人生中一笔宝贵的财富。

参考文献

[1] 李勇, 艾竹君, 刘巧云等.一种新型温度测量系统的设计[J].低温与超导, 2007, 35(5):451-454 [2] 马净, 李晓光,宁伟.几种常用温度传感器的原理及发展[J].中国仪器仪表, 2004,(6):1

[3] 曹忠明, 程姚根.从实践中学嵌入式Linux操作系统[M].北京:电子工业出版社, 2014:8-9 [4] 陈刚 , 冯利美.从实践中学嵌入式Linux应用程序开发[M].北京:电子工业出版社, 2012:193-192

第三篇:嵌入式论文关于触摸屏设计

嵌入式实验课程设计

目 基于嵌入式的触摸屏控制实验

电子工程系

信息工程

20092309022

杨 金 磊

指导教师

董立军

二O一二 年 六 月 八 日

目 录

1.要求.............................................................2 1.1设计目的......................................................1 1.2 设计意义......................................................2 1.3 设计内容......................................................2 1.4 主要任务......................................................2 2.正文.............................................................3 2.1触摸屏工作原理(触摸屏接口工作模式)..........................3 2.2、设计总体方案.................................................4 2.3、设计所需工具.................................................5 2.4、平台构建过程.................................................5

2.4.1、硬件平台搭建.............................................5 2.4.2根文件系统的制作...........................................7(1)根文件系统.................................................7 3.程序............................................................11 3.1.程序流程图:.................................................11 3.2.分析驱动.....................................................11 3.2.1、触摸屏设备驱动中数据结构................................11 3.2.2、触摸屏驱动模块加载和卸载函数............................13 3.2.3、触摸屏设备驱动的读函数..................................15 3.2.4、触摸屏设备驱动的轮询与异步通知..........................15 3.2.5源程序触摸屏驱动代码:....................................16 3.2.6、实验结果显示:..........................................27 4.心得............................................................28 4.1 课程设计心得体会:...........................................28 5.参考文献........................................................28

5.1【参考文献】..................................错误!未定义书签。

第一章 要求

1.1 设计目的

(1)基于WINDOWS操作系统,以及实验箱,利用触摸屏返回触点坐标值及动作信息。

(2)坐标及动作的具体显示:触摸笔动作,触点X坐标值,触点Y坐标值。

1.2 设计意义

(1)熟悉嵌入式系统开发平台

(2)掌握ARM嵌入式操作系统下的各个指令的使用方法(3)了解触摸屏的原理

1.3 设计内容

(1)系统的正确移植和使用(2)根文件系统的正确移植和使用(3)驱动程序的编译与装载

(4)嵌入式系统下应用程序的交叉编译及下载与调试

1.4 主要任务

(1)熟悉实验的流程(2)理解驱动程序源代码

(3)调用驱动程序的某些函数,编译与调试应用程序

第二章 正文

2.1触摸屏工作原理(触摸屏接口工作模式)

(1)普通转换模式

普通转换模式(AUTO_PST = 0,XY_PST = 0)是用作一般目的下的ADC转换。这个模式可以通过设置ADCCON和ADCTSC来进行对AD转换的初始化;而后读取ADCDAT0(ADC数据寄存器0)的XPDATA域(普通ADC转换)的值来完成转换。(2)分离的X/Y轴坐标转换模式:X轴坐标转换和Y轴坐标转换。

X轴坐标转换(AUTO_PST=0且XY_PST=1)将X轴坐标转换数值写入到ADCDAT0寄存器的XPDATA域。转换后,触摸屏接口将产生中断源(INT_ADC)到中断控制器。

Y轴坐标转换(AUTO_PST=0且XY_PST=2)将X轴坐标转换数值写入到ADCDAT1寄存器的YPDATA域。转换后,触摸屏接口将产生中断源(INT_ADC)到中断控制器。

(3)自动(连续)X/Y轴坐标转换模式。

自动(连续)X/Y轴坐标转换模式(AUTO_PST=1且XY_PST= 0)以下面的步骤工作:

触摸屏控制器将自动地切换X轴坐标和Y轴坐标并读取两个坐标轴方向上的坐标。触摸屏控制器自动将测量得到的X轴数据写入到ADCDAT0寄存器的XPDATA域,然后将测量到的Y轴数据到ADCDAT1的YPDATA域。自动(连续)转换之后,触摸屏控制器产生中断源(INT_ADC)到中断控制器。(4)等待中断模式

当触摸屏控制器处于等待中断模式下时,它实际上是在等待触摸笔的点击。在触摸笔点击到触摸屏上时,控制器产生中断信号(INC_TC)。中断产生后,就可以通过设置适当的转换模式(分离的X/Y轴坐标转换模式或自动X/Y轴

坐标转换模式)来读取X和Y的位置。(5)静态(Standby)模式

当ADCCON寄存器的STDBM位被设为1时,Standby模式被激活。在该模式下,A/D转换操作停止,ADCDAT0寄存器的XPDATA域和ADCDAT1寄存器的YPDATA(正常ADC)域保持着先前转换所得的值。

2.2、设计总体方案

2.2.1 软件

(1)Embest Online Flash Programmer For ARM: Embest Flash在线编程器(2)HYPER TERMINAL(超级终端):传送vivi.nand;

传送vivi.nand

vivi> load flash kernel x <回车> 烧写更新内核,传送zImage文件;等待传送内核:

vivi>load flash root j <回车> 烧写更新文件系统;烧写新的文件系统 load flash root j

(3)EmbestIDE Pro for ARM: 应用于嵌入式软件开发的新一代集成开发环境,是一个高度集成的图形界面操作环境,包含编辑器、编译汇编链接器、调试器、工程管理、Flash 编程等工具;支持的开发语言包括标准C和汇编语言。(4)cygwin: 4

一个在windows平台上运行的unix模拟环境,它对于学习unix/linux操作环境,或者从unix到windows的应用程序移植,或者进行某些特殊的开发工作,尤其是使用gnu工具集在windows上进行嵌入式系统开发,把gcc,gdb,gas等开发工具进行了改进,能够生成并解释win32的目标文件。2.2.2 硬件

S3C2410处理器是Samsung公司基于ARM公司的ARM920T处理器核,32位微控制器。该处理器拥有:独立的16KB指令Cache和16KB数据Cache,MMU,支持TFT的LCD控制器,NAND闪存控制器,3路UART,4路DMA,4路带PWM的Timer,I/O口,RTC,8路10位ADC,Touch Screen接口,IIC-BUS 接口,IIS-BUS 接口,2个USB主机,1个USB设备,SD主机和MMC接口,2路SPI。S3C2410处理器最高可运行在203MHz。

2.3、设计所需工具

2.3.1 软件: Embest Online Flash Programmer For ARM,HYPER TERMINAL(超级终端),EmbestIDE Pro for ARM,cygwin 2.3.2 硬件:s3c2410开发板,Embest实验箱

2.4、平台构建过程

2.4.1、硬件平台搭建

硬件流程图:

(1)Vivi烧写过程

1)首先把SW104断开,Flash Programmer的Program,在File选择Open打开要烧写的配置文件S3C2410&NandFLash_vivi.cfg,在Flash Programmer的Program页中选择要烧写的文件vivi.bon&load.bin。点击按钮 Progarm 开始烧写,直到烧写成功

2)连接串口线到 PC 机 COM1,运行光盘中提供的 Windows 超级终端Hyper Terminal.ht 把开发板重新加电,程序运行后,在超级终端上可以看到串口输出Wating,表示正在等待用户从超级终端下载文件。这时,请点击超级终端菜单“传送”选择 Xmodem 方式下载 vivi.nand 文件,点击 OK 后等待下载烧写结束即可。(2)内核zImage烧写

1)首先SW104设为短接(从Nand Flash启动),并确定已经烧写vivi.nand,加电。)在vivi启动等待中,敲入空格键进入vivi界面环境,并输入以下命令:vivi> load flash kernel x <回车> 烧写更新内核约1分钟即可烧写完毕)点击超级终端菜单中的“传送”,选“发送文件”zImage” 并选择xModem方式传送)烧写结束,重起实验板,观测超级终端窗口提示信息就可以启动linux内核,(3)新文件系统的烧写

1)首先SW104设为短接(从Nand Flash启动),确定已经成功烧写vivi.nand,加电运行可以看到vivi启动信息,输入空格进入命令状态;

2)双击运行Download.pjf(该文件在/tmp/edukit-2410/image/中)工程(将启动Embest IDE环境),点击连接Remote connect,程序应该正在运行(命令按钮STOP为红色);在串口输入help,看看有没有反应,如果没反应,点击IDE 按钮:Reset->Start(F5);再输入help测试,直到有反应为止;

3)如果可以输出一些信息,再点击IDE中的Stop,配置Debug的Download地 6

址为0x30000000,并点击IDE菜单Project选择Settings项,在Download页下拉Category到Download项,在Download File选择root.cramfs文件,点击确定后:

点击IDE菜单DEBUG选择Download下载文件系统映象 下载完毕后,点击Start(F5)然后在超级终端里输入: load flash root j(烧写更新文件系统)

注意:只能在“vivi的烧写”操作完成后,才可以按以上方法正确烧写root映象到Nand Flash。

重起实验板,观测超级终端窗口提示信息,引导整个系统启动到linux行命令输入状态。

2.4.2根文件系统的制作(1)根文件系统

根文件系统是Linux系统的核心部分,包含系统使用的软件和库,以及所有用来为用户提供支持架构和用户使用的应用软件,并作为储存数据读写结果的区域。在Linux系统启动时,首先完成内核安装及环境初始化,最后会寻找一个文件系统作为根文件系统被加载。Linux系统中使用“/”来唯一表示根文件系统的安装路径。嵌入式系统中通常可以悬着的根文件系统有:Romfs、CRAMFS、RAMFS、JFFS2、EXT2等,甚至还可以使用NFS作为根文件系统。

(2)cramfs文件系统

Cramfs是Linux创始人Linux torvalds开发的一个适用于嵌入式系统的小文件系统。Cramfs是一个只读文件系统,采用zlib压缩,压缩比一般可以达到1:2,但仍可以做到高效的随机读取。Linux系统中,通常把需要修改的目录压缩存放,并在系统引导的时候再将压缩文件解开。因为cramfs不会影响系统读取文件的速度,而且是一个高度压缩的文件系统,因此非常广泛应用于嵌入式系统中。

(3)cygwin简介

Cygwin是一个在windows平台上运行的unix/Linux模拟环境,是cygnus solutions公司开发的自由软件。Cygwin中,“/”表示根目录,即cygwin的安装目录。我们常用的set_env_linux.sh中定义的目录有:

SOURCEDIR:/tmp/edukit-2410存储了vivi、linux、fs等源代码和例程 WORKDIR:/usr/local/src/edukit-2410工作区。

一般情况下都要把已经规划好的目录结构转换成一个映象文件,即使用命令工具 mkcramfs(cygwin下为 mkcramfs.exe),把相应的 cramfs 目录树压缩为单一的映象文件。其命令格式为:

mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile 可以使用我们提供的 mkcramfs.exe 在 cygwin 下编译生成文件系统映象文件 root.cramfs,再固化到开发系统 FLASH 上运行。

(4)常用的Linux行命令

1)、cd 改变当前目录(文件夹)。例如下,cd/ 返回到根目录 cd..退回到上级目录

cd/tmp/edukit-2410/进入/tmp/edukit-2410/文件夹 2)、ls 列出当前目录中的内容。Ls 简单格式列表 ls–l 使用详细格式列表。3)、pwd 显示当前所在的目录。

(5)tar工具命令

tar 程序用于储存或展开 tar 存档文件。命令格式:

tar [-参数] [文件名][路径]-x :extract |--get 从存档展开文件-v :--verbose 详细显示处理的文件-j :--有 bz2 属性的必须包含

-f :--file [HOSTNAME:]F 指定存档或设备(缺省为 /dev/rmt0)

(6)解压原文件系统(命令+解压目录的存放)

1)先将 root.cramfs.tar.bz2文件放在C:cygwin目录中 2)解压文件系统

运行cygwin,执行以下命令解压安装:

$> source /tmp/edukit-2410/set_env_linux.sh Linux编译环境变量设置 $> cd /

$> tar-xvjf root.cramfs.tar.bz2 $> ls „ root „

root文件夹中就是我们想要的cramfs文件系统 3)如果在根目录中产生root文件夹,解压成功 4)在root目录中新建xx文件夹,用于存放应用程序

进入该目录后执行以下命令编译链接测试程序: $> cd root $>mkdir xx

(7)编译应用程序 ts.c(命令+生成文件格式+存放位置): 将编写好的ts.c程序放在C:cygwin目录中 进入该目录后执行以下命令编译链接测试程序: $> cd / $> arm-linux-gcc-o ts ts.c(也可以编写Makefile来编译)

生成文件: ts 如下图所示

将ts文件放入root 下的xx文件夹中

(8)新文件系统的制作: 把刚才编译输出的ts文件拷贝到文件系统所在的工作目录root目录下,执行以下命令生成新的文件系统映象:

$> cd /

$> mkcramfs root root.new

刚刚编译生成的文件系统映象 root.new 中已经包含测试程序即生成文件。解压文件系统在root目录中新建xx文件夹,用于存放应用 将编写好的ts.c程序放在C:cygwin目录中 生成文件: ts 如下图所示

新文件系统的制作

生成文件:

第三章 程序

3.1.程序流程图:

3.2.分析驱动

触摸屏驱动在/kernel/drivers/char/s3c2410-ts.c 文件中。

3.2.1、触摸屏设备驱动中数据结构

(1)触摸屏的file_operations static struct file_operations s3c2410_fops={ owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read,release: s3c2410_ts_release, #ifdef USE_ASYNC fasync: s3c2410_ts_fasync,//异步通知

#endif poll: s3c2410_ts_poll,//轮询 };(2)触摸屏设备结构体的成员与按键设备结构体的成员类似,也包含一个缓冲区,同时包括自旋锁、等待队列和fasync_struct指针 typedef struct { unsigned int penStatus;/* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF];/* protect against overrun(环形缓冲区)*/ unsigned int head, tail;/* head and tail for queued events(环形缓冲区的头尾)*/ wait_queue_head_t wq;//* 等待队列数据结构 spinlock_t lock;//* 自旋锁

#ifdef USE_ASYNC struct fasync_struct *aq;#endif #ifdef CONFIG_PM struct pm_dev *pm_dev;//友善之臂专有的,我后面的代码删除了这段 #endif } TS_DEV;

(3)触摸屏结构体中包含的TS_RET值的类型定义,包含X、Y坐标和状态(PEN_DOWN、PEN_UP)等信息,这个信息会在用户读取触摸信息时复制到用户空 间

typedef struct { 12

unsigned short pressure;//* 压力,这里可定义为笔按下,笔抬起,笔拖曳

unsigned short x;//* 横坐标的采样值 unsigned short y;//* 纵坐标的采样值 unsigned short pad;//* 填充位 } TS_RET;

(4)在触摸屏设备驱动中,将实现open()、release()、read()、fasync()和poll()函数,因此,其文件操作结构体定义

触摸屏驱动文件操作结构体:static struct file_operations s3c2410fops={} _3.2.2、触摸屏驱动模块加载和卸载函数

(1)在触摸屏设备驱动的模块加载函数中,要完成申请设备号、添加cdev、申请中断、设置触摸屏控制引脚(YPON、YMON、XPON、XMON)等多项工作 触摸屏设备驱动的模块加载函数

static int __init s3c2410_ts_init(void)触摸屏设备驱动模块卸载函数

static void __exit s3c2410_ts_exit(void)(2)可知触摸屏驱动中会产生两类中断,一类是触点中断(INT-TC),一类是X/Y位置转换中断(INT-ADC)。在前一类中断发生后,若之前处于PEN_UP状态,则应该启动X/Y位置转换。另外,将抬起中断也放在INT-TC处理程序中,它会调用tsEvent()完成等待队列和信号的释放 触摸屏设备驱动的触点/抬起中断处理程序

static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)

当X/Y位置转换中断发生后,应读取X、Y的坐标值,填入缓冲区 触摸屏设备驱动X/Y位置转换中断处理程序

static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)触摸屏设备驱动中获得X、Y坐标

static inline void s3c2410_get_XY(void)(3)tsEvent最终为tsEvent_raw(),这个函数很关键,当处于PEN_DOWN状态时调用该函数,它会完成缓冲区的填充、等待队列的唤醒以及异步通知信号的释放;否则(处于PEN_UP状态),将缓冲区头清0,也唤醒等待队列并释放信号

触摸屏设备驱动的tsEvent_raw()函数 static void tsEvent_raw(void)(4)在包含了对拖动轨迹支持的情况下,定时器会被启用,周期为10ms,在每次定时器处理函数被引发时,调用start_ts_adc()开始X/Y位置转换过程

触摸屏设备驱动的定时器处理函数

static void tstimerhandler(unsigned long data)(5)在触摸屏设备驱动的打开函数中,应初始化缓冲区、penStatus和定期器、等待队列及tsEvent时间处理函数指针 触摸屏设备驱动的打开函数

static int s3c2410tsopen(struct inode *inode, struct file *filp)

_

_

_

_ 14

(6)触摸屏设备驱动的释放函数非常简单,删除为用于拖动轨迹所使用的定时器即可

触摸屏设备驱动的释放函数

static int s3c2410tsrelease(struct inode *inode, struct file *filp)

_

_3.2.3、触摸屏设备驱动的读函数

触摸屏设备驱动的读函数实现缓冲区中信息向用户空间的复制,当缓冲区有内容时,直接复制;否则,如果用户阻塞访问触摸屏,则进程在等待队列上睡眠,否则,立即返回-EAGAIN 触摸屏设备驱动的读函数

static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, sizet count, lofft *ppos)_

_3.2.4、触摸屏设备驱动的轮询与异步通知

在触摸屏设备驱动中,通过s3c2410_ts_poll()函数实现了轮询接口,这个函数的实现非常简单。它将等待队列添加到poll_table,当缓冲区有数据时,返回资源可读取标志,否则返回0 触摸屏设备驱动的poll()函数

static unsigned int s3c2410_ts_poll(struct file *filp, struct polltablestruct *wait)而为了实现触摸屏设备驱动对应用程序的异步通知,设备驱动中要实现s3c2410_ts_fasync()函数 触摸屏设备驱动的fasync()函数 __

static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)3.2.5源程序触摸屏代码:

/* * s3c2410-ts.c * * touchScreen driver for SAMSUNG S3C2410 * * Author: Janghoon Lyu * Date : $Date: 2002/06/04 07:11:00 $ * * $Revision: 1.1.2.6 $ * * Based on pt036001b-ts.c * * This file is subject to the terms and conditions of the GNU General Public * License.See the file COPYING in the main directory of this archive * for more details.* * History: * * 2002-05-27: Janghoon Lyu *PM.* */

#include #include #include #include

#include #include #include #include #include #include #include

#include

#ifdef CONFIG_PM #include #endif

/* debug macros */ #undef DEBUG #ifdef DEBUG #define DPRINTK(x...)printk(“s3c2410-ts: ” ##x)#else #define DPRINTK(x...)#endif

#define PEN_UP 0

#define PEN_DOWN 1 #define PEN_FLEETING 2 #define MAX_TS_BUF 16 /* how many do we want to buffer */

#undef USE_ASYNC 1 #define DEVICE_NAME “s3c2410-ts” #define TSRAW_MINOR 1

typedef struct { unsigned int penStatus;/* PEN_UP, PEN_DOWN, PEN_SAMPLE */ TS_RET buf[MAX_TS_BUF];/* protect against overrun */ unsigned int head, tail;/* head and tail for queued events */ wait_queue_head_t wq;spinlock_t lock;#ifdef USE_ASYNC struct fasync_struct *aq;#endif #ifdef CONFIG_PM struct pm_dev *pm_dev;#endif } TS_DEV;

static TS_DEV tsdev;

#define BUF_HEAD(tsdev.buf[tsdev.head])#define BUF_TAIL(tsdev.buf[tsdev.tail])#define INCBUF(x,mod)((++(x))&((mod)-1))

static int tsMajor = 0;

static void(*tsEvent)(void);

#define HOOK_FOR_DRAG #ifdef HOOK_FOR_DRAG #define TS_TIMER_DELAY(HZ/100)/* 10 ms */ static struct timer_list ts_timer;#endif

#define wait_down_int(){ ADCTSC = DOWN_INT | XP_PULL_UP_EN |

XP_AIN | XM_HIZ | YP_AIN | YM_GND |

XP_PST(WAIT_INT_MODE);} #define wait_up_int(){ ADCTSC = UP_INT | XP_PULL_UP_EN | XP_AIN | XM_HIZ |

YP_AIN | YM_GND | XP_PST(WAIT_INT_MODE);} #define mode_x_axis(){ ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ |

XP_PULL_UP_DIS | XP_PST(X_AXIS_MODE);} #define mode_x_axis_n(){ ADCTSC = XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ |

XP_PULL_UP_DIS | XP_PST(NOP_MODE);} #define mode_y_axis(){ ADCTSC = XP_AIN | XM_HIZ | YP_EXTVLT | YM_GND |

XP_PULL_UP_DIS | XP_PST(Y_AXIS_MODE);} #define start_adc_x(){ ADCCON = PRESCALE_EN | PRSCVL(49)|

ADC_INPUT(ADC_IN5)| ADC_START_BY_RD_EN |

ADC_NORMAL_MODE;

ADCDAT0;} #define start_adc_y(){ ADCCON = PRESCALE_EN | PRSCVL(49)|

ADC_INPUT(ADC_IN7)| ADC_START_BY_RD_EN |

ADC_NORMAL_MODE;

ADCDAT1;} #define disable_ts_adc(){ ADCCON &= ~(ADCCON_READ_START);}

static int adc_state = 0;static int x, y;/* touch screen coorinates */

static void tsEvent_raw(void){ if(tsdev.penStatus == PEN_DOWN){

BUF_HEAD.x = x;

BUF_HEAD.y = y;

BUF_HEAD.pressure = PEN_DOWN;

#ifdef HOOK_FOR_DRAG

ts_timer.expires = jiffies + TS_TIMER_DELAY;

add_timer(&ts_timer);#endif } else { #ifdef HOOK_FOR_DRAG

del_timer(&ts_timer);#endif

BUF_HEAD.x = 0;

BUF_HEAD.y = 0;

BUF_HEAD.pressure = PEN_UP;}

tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF);wake_up_interruptible(&(tsdev.wq));

#ifdef USE_ASYNC if(tsdev.aq)

kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);#endif

#ifdef CONFIG_PM pm_access(tsdev.pm_dev);#endif }

static int tsRead(TS_RET * ts_ret){ spin_lock_irq(&(tsdev.lock));ts_ret->x = BUF_TAIL.x;ts_ret->y = BUF_TAIL.y;ts_ret->pressure = BUF_TAIL.pressure;tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF);spin_unlock_irq(&(tsdev.lock));

return sizeof(TS_RET);}

static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){ TS_RET ts_ret;

retry: if(tsdev.head!= tsdev.tail){

int count;

count = tsRead(&ts_ret);

if(count)copy_to_user(buffer,(char *)&ts_ret, count);

return count;} else {

if(filp->f_flags & O_NONBLOCK)

return-EAGAIN;

interruptible_sleep_on(&(tsdev.wq));

if(signal_pending(current))

return-ERESTARTSYS;

goto retry;}

return sizeof(TS_RET);}

#ifdef USE_ASYNC static int s3c2410_ts_fasync(int fd, struct file *filp, int mode){ return fasync_helper(fd, filp, mode, &(tsdev.aq));} #endif

static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait){ poll_wait(filp, &(tsdev.wq), wait);return(tsdev.head == tsdev.tail)? 0 :(POLLIN | POLLRDNORM);}

static inline void start_ts_adc(void){ adc_state = 0;mode_x_axis();start_adc_x();}

static inline void s3c2410_get_XY(void){ if(adc_state == 0){

adc_state = 1;

disable_ts_adc();

y =(ADCDAT0 & 0x3ff);

mode_y_axis();

start_adc_y();} else if(adc_state == 1){

adc_state = 0;

disable_ts_adc();

x =(ADCDAT1 & 0x3ff);

tsdev.penStatus = PEN_DOWN;

DPRINTK(“PEN DOWN: x: %08d, y: %08dn”, x, y);

wait_up_int();

tsEvent();} }

static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg){ #if 0 DPRINTK(“Occured Touch Screen Interruptn”);DPRINTK(“SUBSRCPND = 0x%08lxn”, SUBSRCPND);#endif spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_UP)s3c2410_get_XY();#ifdef HOOK_FOR_DRAG else s3c2410_get_XY();#endif spin_unlock_irq(&(tsdev.lock));}

static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg){ #if 0 DPRINTK(“Occured Touch Screen Interruptn”);DPRINTK(“SUBSRCPND = 0x%08lxn”, SUBSRCPND);#endif spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_UP){ start_ts_adc();} else { tsdev.penStatus = PEN_UP;DPRINTK(“PEN UP: x: %08d, y: %08dn”, x, y);wait_down_int();tsEvent();

} spin_unlock_irq(&(tsdev.lock));}

#ifdef HOOK_FOR_DRAG static void ts_timer_handler(unsigned long data){ spin_lock_irq(&(tsdev.lock));if(tsdev.penStatus == PEN_DOWN){

start_ts_adc();} spin_unlock_irq(&(tsdev.lock));} #endif

static int s3c2410_ts_open(struct inode *inode, struct file *filp){ tsdev.head = tsdev.tail = 0;tsdev.penStatus = PEN_UP;#ifdef HOOK_FOR_DRAG init_timer(&ts_timer);ts_timer.function = ts_timer_handler;#endif tsEvent = tsEvent_raw;init_waitqueue_head(&(tsdev.wq));

MOD_INC_USE_COUNT;return 0;}

static int s3c2410_ts_release(struct inode *inode, struct file *filp){ #ifdef HOOK_FOR_DRAG del_timer(&ts_timer);#endif MOD_DEC_USE_COUNT;return 0;}

static struct file_operations s3c2410_fops = { owner: THIS_MODULE, open: s3c2410_ts_open, read: s3c2410_ts_read,release: s3c2410_ts_release,#ifdef USE_ASYNC fasync: s3c2410_ts_fasync, #endif poll: s3c2410_ts_poll, };

void tsEvent_dummy(void){} #ifdef CONFIG_PM static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,void *data){ switch(req){

case PM_SUSPEND:

tsEvent = tsEvent_dummy;

break;

case PM_RESUME:

tsEvent = tsEvent_raw;

wait_down_int();

break;} return 0;} #endif

#ifdef CONFIG_DEVFS_FS static devfs_handle_t devfs_ts_dir, devfs_tsraw;#endif static int __init s3c2410_ts_init(void){ int ret;

tsEvent = tsEvent_dummy;

ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);if(ret < 0){ printk(DEVICE_NAME “ can't get major numbern”);return ret;} tsMajor = ret;

/* set gpio to XP, YM, YP and YM */ #if 0 set_GPIO_mode(GPIO106_nYPON_MD);

set_GPIO_mode(GPIO105_YMON_MD);set_GPIO_mode(GPIO104_nXPON_MD);set_GPIO_mode(GPIO103_XMON_MD);

GPUP(GPIO106_nYPON)|= GPIO_bit(GPIO106_nYPON);GPUP(GPIO105_YMON)&= GPIO_bit(GPIO105_YMON);GPUP(GPIO104_nXPON)|= GPIO_bit(GPIO104_nXPON);GPUP(GPIO103_XMON)&= GPIO_bit(GPIO103_XMON);#else set_gpio_ctrl(GPIO_YPON);set_gpio_ctrl(GPIO_YMON);set_gpio_ctrl(GPIO_XPON);set_gpio_ctrl(GPIO_XMON);#endif

/* Enable touch interrupt */ ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT,DEVICE_NAME, s3c2410_isr_adc);if(ret)goto adc_failed;ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT,DEVICE_NAME, s3c2410_isr_tc);if(ret)goto tc_failed;

/* Wait for touch screen interrupts */ wait_down_int();

#ifdef CONFIG_DEVFS_FS devfs_ts_dir = devfs_mk_dir(NULL, “touchscreen”, NULL);devfs_tsraw = devfs_register(devfs_ts_dir, “0raw”, DEVFS_FL_DEFAULT,tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,&s3c2410_fops, NULL);#endif

#ifdef CONFIG_PM #if 0 tsdev.pm_dev = pm_register(PM_GP_DEV, PM_USER_INPUT,s3c2410_ts_pm_callback);#endif tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT,s3c2410_ts_pm_callback);#endif printk(DEVICE_NAME “ initializedn”);

return 0;tc_failed: free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);adc_failed: return ret;}

static void __exit s3c2410_ts_exit(void){ #ifdef CONFIG_DEVFS_FS

devfs_unregister(devfs_tsraw);devfs_unregister(devfs_ts_dir);#endif unregister_chrdev(tsMajor, DEVICE_NAME);#ifdef CONFIG_PM pm_unregister(tsdev.pm_dev);#endif free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);free_irq(IRQ_TC, s3c2410_isr_tc);}

module_init(s3c2410_ts_init);module_exit(s3c2410_ts_exit);触摸屏应用程序

#include #include #include /* 文件操作 */

#define PEN_UP 0 /* 触摸笔抬笔,即触摸屏不被压下 */ #define PEN_DOWN 1 /* 触摸笔下笔,即触摸屏被压下 */ #define PEN_FLEETING 2 /* 触摸笔拖动 */

typedef struct { unsigned short pressure;/* 触摸笔动作 */ unsigned short x;

/* 触点x座标值 */ unsigned short y;

/* 触点y座标值 */ unsigned short pad;}TS_RET;

int main(){ int fd,ret,i;

unsigned char suba;TS_RET tsret;

fd = open(“/dev/touchscreen/0raw”, O_RDWR);/* 打开设备 */ if(fd ==-1){ printf(“nCan't open I2C device!n”);exit(-1);}

while(1){

ret = read(fd,(char *)&tsret, sizeof(TS_RET));

if(ret!= sizeof(TS_RET))

{

printf(“read touch screen error!”);

close(fd);

exit(-1);

}

else

{

printf(“pressure is: %dn”, tsret.pressure);

printf(“x is: %dn”, tsret.x);

printf(“y is: %dn”, tsret.y);

} }

close(fd);return 0;} 3.3.应用程序的调试

使用s3c2410_ts.c触摸屏驱动编写应用程序,读取触摸屏的触点坐标值及动作信息(触点x坐标值,y坐标及是否有压力值press),并在串口中断打印出来

对触摸屏设别的操作有打开设备,关闭设备,读操作等。编写应用程序读取触摸屏的触点坐标值及动作信息时,只需利用触摸屏驱动程序便可实现,先打开触摸屏设备,然后调用读函数即可。

其中,触摸笔动作取值如下: #define PEN_UP 0 #define PEN_DOWN

/* 触摸笔抬笔,即触摸屏不被压下 */ /* 触摸笔下笔,即触摸屏被压下 */

#define PEN_FLEETING 2 结构体定义如下: typedef struct { unsigned short pressure;unsigned short x;unsigned short y;unsigned short pad;}TS_RET 打开应用程序:

/* 触摸笔拖动 */

/* 触摸笔动作 */ /* 触点x座标值 */ /* 触点y座标值 */

3.2.6、实验结果显示:

第四部分 感想

第四章 心得

4.1 课程设计心得体会:

经过个人的努力和老师以及同学们的帮助和指导,我顺利的完成了本次《嵌入式系统原理》课程设计。本次课程设计为我提供了一个理论与实践相结合的机会,既锻炼了我的动手能力,又加深理解了在课堂所学习的理论知识。通过本次课程设计,将课本上的理论知识和实际应用有机结合起来,培养了我又动脑,又动手,独立思考分析问题的能力,提高了我运用所学知识解决实际问题的综合素质。通过本次课程设计我明白了只有不断的努力,不断的学习,才能在将来遇到的问题中能够游刃有余,才能够不会捉襟见肘。

参考文献 程昌南,方强等.《ARM Linux入门与实践 》【M】.北京:北京航空航天大学出版社,2008.10 2 张晓林等.《嵌入式系统设计与实践》【M】.北京:北京航空航天大学出版社,2006.1 3 李俊等.《嵌入式Linux设备驱动开发详解》【M】.北京:北京人民邮电出版社,2008.3 4 黄智伟,邓月明,王彦.《ARM9嵌入式系统设计基础教程》.北京:北京航空航天大学出版社,2008.8

第四篇:嵌入式课程设计报告

福建工程学院

《嵌入式系统》课程设计

报告书

题目:

基于S3C2440设备驱动及其界面设计

班级:

姓名:

学号:

指导老师:

陈靖,张平均,李光炀

目录

一、设计课题...............................................................................................................................4

二、设计目的...............................................................................................................................4

三、设计任务及要求...................................................................................................................4

四、设计内容...............................................................................................................................5

五、操作界面的生成...................................................................................................................7

六、操作界面调试.......................................................................................................................9

七、设计总结.............................................................................................................................10

八、设计参考书.........................................................................................................................12

九、附件(程序).....................................................................................................................13

一、设计课题

基于S3C2440的设备驱动及其界面设计

二、设计目的:

1.进一步巩固嵌入式系统的基本知识; 2.掌握嵌入式应用系统的基本结构; 3.掌握嵌入式系统开发环境建立和使用;

4.掌握嵌入式系统基本驱动、应用程序的设计调试和编译移植方法; 5.学会查阅有关专业资料及设计手册; 6.MiniGUI界面编程。

三、设计任务及要求:

1.掌握嵌入式系统开发环境建立和使用;

2.掌握嵌入式系统基本驱动、应用程序的设计调试和编译移植方法;

3、MiniGUI在PC上的安装、移植

4、Linux基本输入输出驱动程序设计编译与移植

5、基于MiniGUI的基本输入输出应用编程编译与移植

6、编写设计说明书(方案的确定、设计环节的考虑及必要说明等)及设备的使用说明;

7、绘制有关图纸.四、设计内容:

1、基础知识准备

1)讲解设计任务;2)熟悉ubuntu的使用;3)熟悉TQ2440试验系统的使用;4)掌握嵌入式系统开发环境建立和使用;

5)掌握嵌入式系统基本驱动、应用程序的设计调试和编译移植方法.2、界面设计环境构建:MiniGUI在PC上的安装、移植

2.1、MiniGUI在pc机上安装和运行

建立工作目录:mkdir /minigui-free

cd /minigui-free mkdir /src 复制源文件包到工作目录:cp /mnt/hgfs/D/src/* /minigui-free 解压文件到/minigui-free:

tar zxvf libminigui-1.6.10.tar.gz tar zxvf minigui-res-1.6.10.tar.gz tar zxvf mg-samples-1.6.10.tar.gz

2.2、MiniGUI库安装

(2)将libcross.sh考到minigui的lib库的解压文件夹中(3)将rescross.sh 考到minigui的res资源解压文件夹中(4)将samplecorss.sh 考到sample例子解压文件夹中(5)依次运行libcross.sh,rescross.sh,samplecorss.sh(6)到nfsroot的,目录下,将libreduce.sh考到这个目录下,运行libreduce.sh 2.3、安装qvfb(1)解压qvfb1.1.tar.gz(2)./configure(3)make(4)make install 2.4、配置MiniGUI.cfg vi /etc/MiniGUI.cfg 修改如下部分为 [system] # GAL engine and default options gal_engine=fbcon

defaultmode=800x480-16bpp # IAL engine ial_engine=fbcon mdev=/dev/mouse mtype=IMPS2 [fbcon] 6

defaultmode=800x480-16bpp [qvfb] defaultmode=800x480-16bpp display=0 1.5运行MiniGUI例子程序(1)打开qvfb:qvfb &(2)运行helloword:

五、操作界面的生成

1、操作界面面执行文件的生成

1).在/minigui-free/mg-samples-1.6.10/src/修改源文件treeview.c 2).再次运行samplecorss.sh,生成执行文件treeview

2、利用nfs进行挂载

1).将本地PC机的网络方式设置成为桥接

2).查看/etc/exports下可以挂载的目录

3).启动服务/etc/init.d/nfs-kernel-server restart 4).查看本机和ARM上的IP地址,设置在同一网段,然后ping,使其能够互通。5).在超级终端上,进行操作

Mount-o nolock,rsize=1024,wsize=1024 本机IP:/ /mnt

将虚拟机和ARM进行挂载,可以查看到虚拟机根目录下的文件。

3、在超级终端上将需要的文件从虚拟机上复制到ARM机上

1).重新烧写文件系统镜像文件

2).挂载成功后,将/mnt/minigui-free/nfsroot/lib/*复制到/usr/lib/ 3).将/mnt/minigui-free/nfsroot/usr/local/lib/*复制到/usr/local/lib/ 4).将/mnt/etc/MiniGUI.cfg复制到/etc/ 8

5).将/mnt/minigui-free/mg-samples-1.6.10/src/*复制到/usr/minigui/

4、在超级终端上运行执行文件

1).进入/usr/minigui/运行treeview文件 2).可以再操作界面上现实我们所设计的界面

六、操作界面调试

1、点击LED1LED2LED3LED4,分别控制四盏led灯的亮暗,调试界面如下:

2、输入频率值,点击START键控制四盏led灯闪烁,调试界面如下:

七、设计总结

1、设计过程中遇到的问题

错误1:

InitGUI: Can not initialize colors of window element!InitGUI failure when using /usr/local/etc/MiniGUI.cfg as cfg file.解决方法:正确配置MiniGUI.cfg文件 错误2:

Permission denied 解决方法:权限不够,使用root用户登录。错误3:

编译出错未找到jpeg,png等

解决方法:安装zlib,png,jpeg库。

错误4:

出现符号未找到等编译错误 解决方法:make clean 后在make 错误5:

在minigui创建和移植的过程中,出现lib库编译不成功的现象,这是由于minigui是基于qt3的,因此需要添加qt3所在路径至配置文件。错误:6 在开发板上添加鼠标设备后,提示视频采集失败,这是因为/etc下的配置文件MiniGUI.cfg中对外设控制范围的控制过大,银将其修改为与界面统一大小800*480.错误:7 在执行led灯控制程序之前应该首先停止开发板上原有的流水灯进程led-player。错误:8 运行执行程序treeview后界面上出现两个光标,此时应该在/etc/init.d下的rcS文件中停用qt3的光标。

2、心得体会

本学期为期两周的嵌入式课程设计在不知不觉中结束了,虽说这次课程设计时间不是很长,但是感觉自己收获颇丰,不仅学习到了一些新知识,回顾了以前的一些快要遗忘的知识点,而且使自己的学习目标更加明确,学习方法更加完善,也体会到软件开发的趣味,更加清楚地认识到了自己在软件开发及学习上的一些不足之处。

两周的课程设计,在计算机这个博大深奥的领域我感觉自己还有好多东西要学,还有好多的东西不懂!嵌入式软件开发应用广泛而且前景很好,目前正处于人才紧缺的关口,嵌入式技术在未来能够得到更加广泛的应用。学好嵌入式,C语言很重要,所以感觉自己有必要在学习、积累一下这方面的知识。很多东西的学习不是一帆风顺也是比较耗时的,嵌入式也不例外,要想学好还必须下大力气,还必须坚持。这次的课程设计让我明确了一点:嵌入式开发对于提升我们的系统知识有很大的帮助,尤其是操作系统的知识。嵌入式

系统开发对于我们的知识面要求非常的广,且要有一定的深度。这次的课程设计因为是一个有针对性的训练,所以记的会非常牢固。跟平时上课不太一样,平时上完理论课很少有时间上机进行时间或者隔几天才上机练习,等到上机时一些东西可能遗忘了,比较耗费时间。在课上,有老师在前面演示我们感觉看得懂或感觉没问题,可轮到我们独立完成的时候,因为实际操作的少,其中的问题就来了!我很感谢学校特别是学院老师有实训这样的安排,把我们这一学期学的东西系统的集中的进行训练,让我们深刻明确的体验了一下软件开发的流程!还要感谢给我们实训的楚老师,感觉楚老师能力很强,也很有耐心,即使老师讲了很多遍的问题,我们不会,老师还是会走进我们给我们耐心的指导,还给我们讲一些学习计算机的方法,一些软件开发需要注意的细节,让我们知道自己在哪方面不足,需要加强,也让我们了解到哪些需要认真的学习,那些是重点,不是没有方向的乱学一通,什么也学不好!经过这次的实训,我真真确确的感受到了计算机在我们生活中工作中的运用,这些软件、程序能让我们提高工作的效率,更直观更便捷的切入主题。当然,在学习的过程中并不是一帆风顺的,在这之中,因为要操作的东西很多,有时错一步,后面的结果就无法显示,而自己的计算机水平还有待提高,根本检查不出来是哪里出了错!这时候,老师都会耐心的过来帮助我!在平时我们就需要好好的查阅书籍或者上网搜集相关资料去解决问题。

短短两周的课程设计很快结束了,我发现我对计算机这个专业、对嵌入式技术、对Linux都有了新的认识。通过这次的实训,我了解到,要真真正正的掌握计算机程序还不是一件简单容易的事儿,但真正掌握后,它带给我们的将是无穷的便捷与科技,我喜欢高端便捷的生活。我希望我能做计算机这个万能机器人的主人而不是奴隶,我会努力加油的!感谢学校,感谢老师给我的帮助,让我的思想、技能又上了一个台阶!感谢!加油!

八、设计参考书

1、《嵌入式系统接口设计与Linux驱动程序开发》

2、《ARM9嵌入式LINUX系统构建与应用》

4、MiniGUI编程手册

5、Linux应用程序编程

九、附件(程序)

#include

#include

/*包括 MiniGUI 常用的宏以及数据类型的定义*/ #include /*包含了全局的和通用的接口函数以及某些杂项函数的定义*/ #include

/*包含了

MiniGUI

绘图函数的接口定义*/ #include

/*包含了

libminigui 中所有内建控件的接口定义*/ #include #include #include

/*包含了许多UNIX系统服务的函数原型*/ #include

/*提供对I/O控制的函数*/

#define ID_LED1 101

/*定义各个控件与定时器的ID号*/ #define ID_LED2 102 #define ID_LED3 103 #define ID_LED4 104 #define ID_TEXT1 105 #define ID_TEXT2 106 #define ID_START 107 #define ID_STOP 108 #define ID_COMBOBOX 109 #define ID_TIMER 110

static int a,b,c,d=0;

/*定义LED灯的初始值*/ static int fd_led;

/*定义文件描述符*/

HWND hMainWnd;

/*定义主窗口句柄*/

static void draw_circular(HWND hdig,int x,int y,int r,int which)

/*自定义一个画圆函数,x、y、r、which分别表示圆心坐标、半径、颜色*/ {

HDC hdc;

/*定义设备上下文句柄*/ int color;color=((which==0)?PIXEL_green:PIXEL_red);

hdc=BeginPaint(hdig);

/*获得设备上下文句柄*/ SetBrushColor(hdc,color);

/*设置画刷颜色*/ FillCircle(hdc,x,y,r);

/*调用园填充函数*/ EndPaint(hdig,hdc);

/*释放设备上下文句柄*/ }

static DLGTEMPLATE DlgInitProgress=

/*定义对话框模板.用static类型数据,使该数据的定义只在所在文件中有效,以免因为名字空间污染造成潜在的编译或连接错误*/ {

WS_BORDER|WS_CAPTION,/*对话框风格,WS_BORDER创建有边框的窗口 ,WS_CAPTION创建含标题栏的主窗口*/

WS_EX_NONE,/*对话框扩展风格,WS_EX_NONE表示无扩展风格*/

0,0,800,480,/*对话框位置,左上角坐标(0,0),800、480分别为宽和高*/

“MY_LED_CONTROL”,/*对话框标题*/

0,/*对话框图标*/

0,/*对话框菜单*/

9,/*对话框中控件个数。这个必须要匹配*/

NULL,/*pointer to control array*/

0

/*附加值*/ };

static CTRLDATA CtrlInitData[]=

/*控件数组*/ {

{

“static”,/*控件类型*/

WS_VISIBLE|SS_SIMPLE,/*控件风格,WS_VISIBLE创建初始可见的窗口,SS_SIMPLE显示单行文本*/

100,270,150,40,/*控件位置*/

ID_TEXT1,/*控件ID*/

“Please input frequency”,/*控件内容*/

0,/*附加值*/

WS_EX_NONE

/*控件扩展风格*/

}, { “static”, WS_VISIBLE|SS_SIMPLE, 605,270,150,40, ID_TEXT2, “HZ”, 0, WS_EX_NONE

}, {

“button”, WS_VISIBLE|WS_TABSTOP, 135,160,80,60, ID_LED1, “LED1”, 0, WS_EX_NONE

}, {

“button”, WS_VISIBLE|WS_TABSTOP, 285,160,80,60, ID_LED2, “LED2”, 0, WS_EX_NONE

}, {

“button”, WS_VISIBLE|WS_TABSTOP, 435,160,80,60, ID_LED3, “LED3”, 0,/*WS_TABSTOP支持Tab键*/

WS_EX_NONE

}, {

“button”,WS_VISIBLE|WS_TABSTOP,585,160,80,60,ID_LED4,“LED4”,0,WS_EX_NONE

}, {

“button”,WS_VISIBLE|WS_TABSTOP,285,360,80,60,ID_START,“START”,0,WS_EX_NONE

}, {

“button”,WS_VISIBLE|WS_TABSTOP,435,360,80,60,ID_STOP,“STOP”,0,WS_EX_NONE

}, {

CTRL_COMBOBOX,WS_VISIBLE|WS_TABSTOP|CBS_AUTOSPIN|CBS_AUTOLOOP,/*CBS_AUTOSPIN创建旋钮数字框,CBS_AUTOLOOP框中的数字将自动循 环显示*/

435,270,80,40,ID_COMBOBOX,“0”,/*旋钮数字框初始值*/

0,WS_EX_NONE

} };

static int DialogBoxProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)/*对话框过程函数,用来接收和处理所有发送到该窗口的消息*/ {

int number;

/*用来存从旋钮数字框获得的数值*/

static int t=0;

int num;

/*存放定时时间*/

switch(message)

{

case MSG_INITDIALOG:

/*用户在定义自己的对话框回调函数时,需要处理

MSG_INITDIALOG消息,该消息是在MiniGUI根据对话框模板建立对话框以及 控件之后,发送到对话框回调函数的。*/

SendDlgItemMessage(hWnd, ID_COMBOBOX, CB_SETSPINRANGE, 0, 10000);

/*设置旋钮数字框的最大小值*/

return 1;

case MSG_PAINT:/*重绘消息*/

draw_circular(hWnd,175,90,30,1);

draw_circular(hWnd,325,90,30,1);

draw_circular(hWnd,475,90,30,1);

draw_circular(hWnd,625,90,30,1);

printf(“*************************init draw_circular******************************n”);

case MSG_TIMER:t++;

/*定时器消息,这里完成LED灯的闪烁*/

if(t%2!=0)

{

ioctl(fd_led, 0,0);

ioctl(fd_led, 0, 1);

ioctl(fd_led, 0, 2);

ioctl(fd_led, 0, 3);printf(“*************************time red******************************n”);

draw_circular(hWnd,175,90,30,1);

draw_circular(hWnd,325,90,30,1);

draw_circular(hWnd,475,90,30,1);

draw_circular(hWnd,625,90,30,1);

break;

}

else

{

ioctl(fd_led, 1,0);

ioctl(fd_led, 1, 1);

ioctl(fd_led, 1, 2);

ioctl(fd_led, 1, 3);printf(“*************************time green******************************n”);

draw_circular(hWnd,175,90,30,0);

draw_circular(hWnd,325,90,30,0);

draw_circular(hWnd,475,90,30,0);

draw_circular(hWnd,625,90,30,0);

break;

}

case MSG_COMMAND: /*击键消息*/

switch(wParam)

{

case ID_LED1:a++;

/*控制LED灯亮暗*/

if(a%2!=0)

{

ioctl(fd_led,0,0);

draw_circular(hWnd,175,90,30,1);

}

else

{ /

ioctl(fd_led,1,0);

draw_circular(hWnd,175,90,30,0);

}

printf(“******************led1********************************n”);

break;

case ID_LED2:b++;

if(b%2!=0)

{

ioctl(fd_led,0,1);

draw_circular(hWnd,325,90,30,1);

}

else

{

ioctl(fd_led,1,1);

draw_circular(hWnd,325,90,30,0);

}

printf(“*******************led2********************************n”);

break;

case ID_LED3:c++;

if(c%2!=0)

{

ioctl(fd_led,0,2);

draw_circular(hWnd,475,90,30,1);

}

else

{

ioctl(fd_led,1,2);

draw_circular(hWnd,475,90,30,0);

}

printf(“*******************led3********************************n”);

break;

case ID_LED4:d++;

if(d%2!=0)

{

ioctl(fd_led,0,3);

draw_circular(hWnd,625,90,30,1);

printf(“*******************led33********************************n”);

}

else

{

ioctl(fd_led,1,3);

draw_circular(hWnd,625,90,30,0);

}

printf(“*******************led4********************************n”);

break;

case ID_START:printf(“*******************start1*********************n”);

number=SendMessage(GetDlgItem(hWnd,ID_COMBOBOX), CB_GETSPINVALUE, 0, 0);/*获取旋钮数字框的数值*/

printf(“**********%d*******************n”,number);

printf(“*******************start2*********************n”);

if(number!=0)

{

printf(“*******************start3*********************n”);

num=(int)(1000*(1.0/number));

/*将频率转换为时间*/

printf(“*******************start4*********************n”);

}

else

{

printf(“*******************start5*********************n”);

num=1000;

}

printf(“*******************start6*********************n”);

printf(“*******************start7*********************n”);

printf(“*******************start8*********************n”);

SetTimer(hWnd,ID_TIMER,num);/*创建定时器,时间为num*10ms*/ printf(“*************************SetTimer OK******************************n”);

SendMessage(hWnd,BM_CLICK,0,0);

/*发送点击信息*/ printf(“*************************SendMessage OK******************************n”);

//for(i=0;i++;i<10000)

/*当初用for循环时无法进入循环,也许是因为消息本身有循环机制,用for循环太多也许冲突,所以后来用了定时器*/

//{

//

printf(“********%d**********n,i”);

//

ioctl(fd_led, 1,0);//

ioctl(fd_led, 1, 1);//

ioctl(fd_led, 1, 2);//

ioctl(fd_led, 1, 3);

//

draw_circular(hWnd,175,90,30,0);

//

draw_circular(hWnd,325,90,30,0);

//

draw_circular(hWnd,475,90,30,0);

//

draw_circular(hWnd,625,90,30,0);

printf(“*******************start9*********************n”);

// usleep(number);

//usleep(num);

//

ioctl(fd_led, 0,0);//

ioctl(fd_led, 0, 1);//

ioctl(fd_led,0, 2);//

ioctl(fd_led, 0, 3);

// draw_circular(hWnd,175,90,30,1);

// draw_circular(hWnd,325,90,30,1);

// draw_circular(hWnd,475,90,30,1);

// draw_circular(hWnd,625,90,30,1);

// printf(“*******************start10*********************n”);

//usleep(number);

//usleep(num);

// }

printf(“*******************start********************************n”);

break;

case ID_STOP:

KillTimer(hWnd,ID_TIMER);/*关闭定时器。下面的表示灯灭*/

ioctl(fd_led, 0,0);

ioctl(fd_led, 0, 1);

ioctl(fd_led, 0, 2);

ioctl(fd_led, 0, 3);

draw_circular(hWnd,175,90,30,1);

draw_circular(hWnd,325,90,30,1);

draw_circular(hWnd,475,90,30,1);

draw_circular(hWnd,625,90,30,1);

printf(“**************stop******************n”);

break;

}

}

return(DefaultDialogProc(hWnd,message,wParam,lParam));

/*对话框的缺省消息处理由 DefaultDialogProc 函数完成*/ }

static void InitDialogBox(HWND hWnd){ DlgInitProgress.controls=CtrlInitData;

/*将对话框模板结构和控件结构数组关联起来*/ DialogBoxIndirectParam(&DlgInitProgress,hWnd,DialogBoxProc,0L);/*创建对话框*/

printf(“*************create dialog**********************n”);}

/*****************************************************************

主窗口的过程函数

static int LedWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam){

HDC hdc;

switch(message)

{

case MSG_PAINT:

hdc = BeginPaint(hWnd);

TextOut(hdc, 60, 60, “My leds control!”);

EndPaint(hWnd, hdc);

return 0;

case MSG_CLOSE:

DestroyMainWindow(hWnd);

PostQuitMessage(hWnd);

return 0;

}

return DefaultMainWinProc(hWnd, message, wParam, lParam);

}

*********************************************************************/ int MiniGUIMain(int argc, const char* argv[])

{

// MSG Msg;

// MAINWINCREATE CreateInfo;/*描述主窗口的属性*/

#ifdef _MGRM_PROCESSES

JoinLayer(NAME_DEF_LAYER , “led” , 0 , 0);

/*选择PROCESSES模式*/

#endif

printf(“****************into main*********************n”);

fd_led=open(“/dev/GPIO-Control”,0);

/*打开驱动设备*/

if(fd_led < 0)

{

perror(“open device led”);

exit(1);

}

ioctl(fd_led, 0, 0);

/*初始灯灭*/

ioctl(fd_led, 0, 1);

ioctl(fd_led, 0, 2);

ioctl(fd_led, 0, 3);

InitDialogBox(HWND_DESKTOP);

close(fd_led);/*********************************************************** CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;/窗口风格/

CreateInfo.dwExStyle=WS_EX_NONE;

/窗口扩展风格/

CreateInfo.spCaption=“MY_LED_CONTROL_WIN”;

/窗口标题/

CreateInfo.hMenu=0;

/菜单/

CreateInfo.hCursor= GetSystemCursor(0);

/光标/

CreateInfo.hIcon=0;

/图标/

CreateInfo.MainWindowProc=LedWinProc;

/设置主窗口的窗口函数,所用发往该窗口的消息由该函数处理/

CreateInfo.lx=0;

/窗口位置/

CreateInfo.ty = 0;

CreateInfo.rx = 240;

CreateInfo.by = 180;

CreateInfo.iBkColor=COLOR_lightwhite;

/设置背景颜色/

CreateInfo.dwAddData=0;

/附加数值/

CreateInfo.hHosting=HWND_DESKTOP;

/设置窗口的托管窗口为桌面窗口/

hMainWnd = CreateMainWindow(&CreateInfo);

/创建主窗口,返回创建窗口的句柄/

if(hMainWnd == HWND_INVALID)

return-1;

ShowWindow(hMainWnd,SW_SHOWNORMAL);

/显示窗口的显示方式/

while(GetMessage(&Msg, hMainWnd))/获取主窗口的句柄,指向MSG结构指针/

{

TranslateMessage(&Msg);

/将击键消息转换为MSG_CHAR消息,然后直接发送到窗口的过程函数/

DispatchMessage(&Msg);

/获取消息的目标窗口的窗口过程,然后直接调用 该窗口过程函数对消息进行处理/

}

MainWindowThreadCleanup(hMainWnd);/清除主窗口所使用消息队列的系统资源/ *****************************************************************************/

return 0;

}

#ifndef _MGRM_PROCESSES #include #endif

第五篇:嵌入式课程设计心得体会

嵌入式课程设计心得体会

本学期为期一周的嵌入式课程设计在不知不觉中结束了,虽说这次课程设计时间不是很长,但是感觉自己收获颇丰,不仅学习到了一些新知识,回顾了以前的一些快要遗忘的知识点,而且使自己的学习目标更加明确,学习方法更加完善,也体会到软件开发的趣味,更加清楚地认识到了自己在软件开发及学习上的一些不足之处。下面就来详细写一下我关于此次课程设计的心得体会:

此次课程设计的实训的是由上海杰普公司的楚老师带我们完成的。楚老师看上去比较年轻,给我们很有亲和力,技术上也很强,而且讲解的比较详细,操作上相当娴熟。让我们感觉到了计算机科学技术学习的趣味性,计算机技术的实用性。此次课程设计给老师选择项目是在Linux下用C语言开发一个摄像头驱动程序。项目的实施方式是团队分组合作,共同完成,让我们体验了一下公司开发项目的氛围。我们一人一机,老师边讲边练,还有企业项目经理的全程指导。虽说一些些技术我们在课堂上也曾学习过,但是大多停留在理论学习上,实际开发很少,而这次课程设计给了我们一个很好的边学习边实践的机会,对我们深入学习这些技术有很大帮助,深刻体会到了这些技术的实用性。每当自己成功调试一段代码或者通过自己的努力克服一个技术困难,都颇有收获感。这次实训让我们体验了软件开发的全过程,发现自己的不足,了解了当前流行技术的软件开发,增加了一定的项目开发经验,增强了一定的就业竞争力。简短的回顾一下这几天我们所学习的:

实训的前一天下午,我们先明确了一下下周课程设计的要求和目的,跟上海杰普公司的楚老师相互认识了一下。然后楚老师给我们详细的讲解了这一周我们要做什么,并演示了一个他自己开发的摄像头驱动程序。同学们看了,都很感兴趣,如果自己能开发出这样的一个小程序,着实让人高兴。接下来的这几天我们就跟着范老师一起学习摄像头驱动的开发,同时我们也分了小组,模拟体验一下公司的团队开发,同学们都积极策划自己团队的名字、团队的口号、队歌……

我们首先从基本的Linux命令学起,以及linux底下的C语言的一些基本知识。虽说这学期我们也学过Linux开发技术,有一定的基础,但这几天的学习,还是感觉到我们学的太浅,很多的东西需要去深入的学习才能有所收获。而且深刻的体会到“熟能生巧”这句良训,光学不练还是白搭。后两天我们学习了Linux底下一些开发工具的使用,如Qt,感觉这些工具功能确实够强大。当通过自己写的代码能够控制摄像头拍照时,别提有多高兴了。当然在调试的过程中也遇到不少错误,每当通过自己的努力把问题解决(一般自己思考一下,查查资料都没问题),也是一种很好的收获。还有一个比较深刻的体会就是API及一些文档的查阅,这对开发人员来说是一个必须具备的能力。

一周的课程设计,一周的实训,在计算机这个博大深奥的领域我感觉自己还有好多东西要学,还有好多的东西不懂(这也再次坚定了我考研深造的决心)!嵌入式软件开发应用广泛而且前景很好,目前正处于人才紧缺的关口,嵌入式技术在未来能够得到更加广泛的应用。学好嵌入式,C语言很重要,所以感觉自己有必要在学习、积累一下这方面的知识。很多东西的学习不死一帆风顺也是比较耗时的,嵌入式也不例外,要想学好还必须下大力气,还必须坚持。这次的课程设计让我明确了一点:嵌入式开发对于提升我们的系统知识有很大的帮助,尤其是操作系统的知识。嵌入式系统开发对于我们的知识面要求非常的广,且要有一定的深度。这次的课程设计因为是一个有针对性的训练,所以记的会非常牢固。跟平时上课不太一样,平时上完理论课很少有时间上机进行时间或者隔几天才上机练习,等到上机时一些东西可能遗忘了,比较耗费时间。在课上,有老师在前面演示我们感觉看得懂或感觉没问题,可轮到我们独立完成的时候,因为实际操作的少,跟中问题就来了!我很感谢学校特别是学院老师有实训这样的安排,把我们这一学期学的东西系统的集中的进行训练,让我们深刻明确的体验了一下软件开发的流程!还要感谢给我们实训的楚老师,感觉楚老师能力很强,也很有耐心,即使老师讲了很多遍的问题,我们不会,老师还是会走进我们给我们耐心的指导,还给我们讲一些学习计算机的方法,一些软件开发需要注意的细节,让我们知道自己在哪方面不足,需要加强,也让我们了解到哪些需要认真的学习,那些是重点,不是没有方向的乱学一通,什么也学不好!经过这次的实训,我真真确确的感受到了计算机在我们生活中工作中的运用,这些软件、程序能让我们提高工作的效率,更直观更便捷的切入主题。当然,在学习的过程中并不是一帆风顺的,在这之中,因为要操作的东西很多,有时错一步,后面的结果就无法显示,而自己的计算机水平还有待提高,根本检查不出来是哪里出了错!这时候,老师都会耐心的过来帮助我!在平时我们就需要好好的查阅书籍或者上网搜集相关资料去解决问题。

此次实训最大的收获不是我学习到了多少知识而是这几天实训给我的感悟:首先是心态。一定要有一个积极的心态,独立解决问题的意识,培养扎实基础的认识。不要什么东西都感觉跟简单(很多东西可能是看似简单)就不去做了或者不屑一做,以至于性网上搜搜就可以了,这样很不好。有自己的东西有自己的付出才会有程序运行成功时的喜悦和小自豪,这样也有助于培养自己的兴趣。要时刻牢记态度决定一切。其次是兴趣,感觉学习工作中兴趣很关键,只是一个引发人积极性的问题,有了兴趣就自觉了,效率自然就高了。再次要敢于尝试和挑战。不要安于现成的程序,而且不要害怕失败,在程序调试的过程中这点尤为重要,“发现出问题然后解决问题”是一个积累经验的过程,而且很高效。最后要不懈追求。对于源代码进行不断的完善,要尽可能的实现课题所要求的功能。对于初学者或者开发较少的人来说,大量大写程序还是有必要的,但同时要注意思考,理解其实现的内在意义。还可以自己添加一些有意义的功能来实现。当看到自己编写的程序正常运行时,兴趣也会随之而来,乐此不疲,形成一个良性循环。

短短一周的课程设计很快结束了,我发现我对计算机这个专业、对嵌入式技术、对Linux都有了新的认识。通过这次的实训,我了解到,要真真正正的掌握计算机程序还不是一件简单容易的事儿,但真正掌握后,它带给我们的将是无穷的便捷与科技,我喜欢高端便捷的生活。我希望我能做计算机这个万能机器人的主人而不是奴隶,我会努力加油的!感谢学校,感谢老师给我的帮助,让我的思想、技能又上了一个台阶!感谢!加油!

下载嵌入式课程设计之触摸屏程序设计word格式文档
下载嵌入式课程设计之触摸屏程序设计.doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    嵌入式系统课程设计

    《嵌入式系统概论》综合设计报告书 设计题目:用键盘控制LED显示不同图形 中央民族大学 二零零八年十月三十一日 一、 设计目的 了解LED点阵和矩阵键盘的工作原理。 二、 设计......

    VB程序设计课程设计

    VB程序设计课程设计 1、目的 VB程序设计课程设计是考察学生对VB程序设计课程相关知识点掌握情况的重要环节,也是激励学生进一步学习VB、提高运用VB开发实际计算机程序的能力......

    《嵌入式系统》课程设计题目

    《嵌入式系统》 课程设计题目及要求 设计报告要求: 1. 课题研究意义、现状及应用分析; 2. 课题总体方案设计及功能模块介绍; 3. 系统硬件平台及接口设计; 4. 系统软件功能设计,包......

    《嵌入式系统》课程设计题目

    《嵌入式系统》 课程设计题目及要求 2013年12月24日 设计报告要求: 1. 课题研究意义、现状及应用分析; 2. 课题总体方案设计及功能模块介绍; 3. 系统硬件平台及接口设计; 4. 系......

    嵌入式系统课程设计教学大纲

    嵌入式系统课程设计教学大纲 课程名称:嵌入式系统A课程(Embedded Systems) 课程编号:1310778236 设计时数:1周 学分:1 开课单位:信息电子技术学院通信工程教研室 适用专业:通信工......

    语言程序设计课程设计指导书

    汇编语言程序设计课程设计指导书 一、 课程设计的目的 本课程设计是《汇编语言程序设计》课程的后继教学环节,其宗旨是使学生通过对一个较大型的、综合性的应用程序进行阅读......

    Windows程序设计课程设计doc(精选五篇)

    Windows程序设计课程设计任务书 ,课程设计题目1: 设计一个简单的学生信息管理应用程序 一、设计目标与内容: 1. 了解Windows编程的基础知识,掌握MFC应用程序的基本知识; 2. 基......

    《JAVA程序设计》课程设计五篇

    JAVA程序设计》课程设计 ------ Chatter即时聊天工具 班 级: 姓 名: 学 号: 指导老师: 日 期: 1 《目录 1.引言... ..............................................................