ImageVerifierCode 换一换
格式:DOCX , 页数:22 ,大小:846.47KB ,
资源ID:5027664      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5027664.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(蜂鸣器设计实践报告.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

蜂鸣器设计实践报告.docx

1、蜂鸣器设计实践报告合肥师范学院嵌入式系统开发技术 课程设计专 业: 计算机科学与技术(嵌入式) 班 级: 2011级嵌入式应用技术 学 号: 姓 名: 设计题目: 蜂鸣器驱动程序设计 2014年05月目 录1.绪论 11.1概要 11.2设计内容 22.开发环境的搭建 22.1Redhat的安装 22.2安装arm-linux-gcc交叉编译器 62.3安装及编译 83.字符设备驱动相关知识 103.1模块机制 103.2字符设备开发基本步骤 113.3主设备号和次设备号 113.4实现字符驱动程序 124.蜂鸣器原理 144.1蜂鸣器的种类和工作原理 145.总体设计 155.1设计思路 1

2、55.2设计步骤 166、驱动及测试程序 167.运行结果及截图 208.综合设计总结与思考 21 1.绪论1.1概要linux 驱动在本质上就是一种软件程序,上层软件可以在不用了解硬件特性的情况下,通过驱动提供的接口,和计算机硬件进行通信。 系统调用是内核和应用程序之间的接口,而驱动程序是内核和硬件之间的接口,也就是内核和硬件之间的桥梁。它为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。 linux 驱动程序是内核的一部分,管理着系统中的设备控制器和相应的设备。它主要完成这么几个功能:对设备初始化和释放;传送数据到硬

3、件和从硬件读取数据;检测和处理设备出现的错误。 一般来说,一个驱动可以管理一种类型的设备。例如不同的 U 盘都属于 mass storage 设备,我们不需要为每一个 U 盘编写驱动,而只需要一个驱动就可以管理所有这些 mass storage 设备。 为方便我们加入各种驱动来支持不同的硬件,内核抽象出了很多层次结构,这些层次结构是 linux 设备驱动的上层。它们抽象出各种的驱动接口,驱动只需要填写相应的回调函数,就能很容易把新的驱动添加到内核。 一般来说, linux 驱动可以分为三类,就是块设备驱动,字符设备驱动和网络设备驱动。块设备的读写都有缓存来支持,并且块设备必须能够随机存取。块设

4、备驱动主要用于磁盘驱动器。 而字符设备的 I/O 操作没有通过缓存。字符设备操作以字节为基础,但不是说一次只能执行一个字节操作。例如对于字符设备我们可以通过 mmap 一次进行大量数据交换。字符设备实现比较简单和灵活。1.2设计内容本次设计是简单的字符设备驱动设计,基于mini2440的蜂鸣器的驱动设计。 2.开发环境的搭建2.1Redhat的安装创建一个虚拟机:点击菜单栏File-New-Virtual machine。点击下一步。选择Typical选项。选择Linux下的Red Hat Linux填写虚拟机的命名和存储地址。选择磁盘大小2.2安装arm-linux-gcc交叉编译器 将 a

5、rm-linux-gcc-4.5.1-v6-vfp-20120301.tgz复制到虚拟机的root目录下解压文件:tar zxvf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz在bash_profile里添加路径:vi /.bash_profiel 路径 /home/q/Desktop/opt/FriendlyARM/toolschain/4.5.1/binsource /.bash_profile 使更改生效截图:2.3安装及编译linux-2.6.35.7-mini210-tvp5150_linux_defconfig内核复制内核到root目录下解压内核文

6、件 tar zxvf arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz使内核文件生效:cp mini210-tvp5150_linux_defconfig .config使用make命令完成编译截图: 3.字符设备驱动相关知识3.1模块机制Linux提供了机制被称为模块(Module)的机制 提供了对许多模块支持, 包括但不限于, 设备驱动每个模块由目标代码组成( 没有连接成一个完整可执行程序 )insmod 将模块动态加载到正在运行内核rmmod 程序移除模块Linux内核模块的程序结构 static int _init beep_init(void)-模块初始

7、化函数 通过alloc_chrdev_region来分配设备号beep_cdev来对设备进行各种操作。比如在加载内核模块时,模块的加载函数 会自动被内核执行,完成模块的相关初始化工作 static void _exit beep_exit(void)-模块卸载函数(必须) 当通过unregister_chrdev_region命令卸载某模块时,模块的卸载函数会自动被内核执行,完成与模块装载函数相反的功能 MODULE_LICENSE()-模块许可证声明(必须)模块许可证(LICENSE)声明描述内核模块的许可权限如果不声明LICENSE,模块被加载时,将收到内核被污染(kernel taint

8、ed)的警告 其他一些声明MODULE_XXXXX()-模块声明(可选)模块加载函数static int _init initialization_function(void) /* 初始化代码 */module_init(initialization_function); 模块卸载函数 static void _exit cleanup_function(void) /* 释放资源 */ module_exit(cleanup_function); 3.2字符设备开发基本步骤 确定主设备号和次设备号 实现字符驱动程序实现file_operations结构体实现初始化函数,注册字符设备实现销毁

9、函数,释放字符设备 创建设备文件节点3.3主设备号和次设备号 主设备号是内核识别一个设备的标识。整数(占12bits),范围从0到4095,通常使用1到255 次设备号由内核使用,用于正确确定设备文件所指的设备。整数(占20bits),范围从0到1048575,一般使用0到255 设备编号的内部表达dev_t类型(32位):用来保存设备编号(包括主设备号(12位)和次设备号(20位)从dev_t获得主设备号和次设备号:MAJOR(dev_t);MINOR(dev_t);将主设备号和次设备号转换成dev_t类型:MKDEV(int major,int minor); 分配主设备号手工分配主设备号

10、:找一个内核没有使用的主设备号来使用。#include int register_chrdev_region( dev_t first, unsigned int count, char *name ); 动态分配主设备号:#include int alloc_chrdev_resion(dev_t *dev,unsigned int firstminor,unsigned int count,char *name); 释放设备号void unregister_chrdev_region(dev_t first, unsigned int count);3.4实现字符驱动程序 cdev 结构体

11、struct cdev dev_t beep_devno; /*设备号*/unsigned int *map;struct file_operations *ops; /*文件操作结构体*/ unsigned int count; ; file_operations 结构体字符驱动和内核的接口:在include/linux/fs.h定义字符驱动只要实现一个file_operations结构体并注册到内核中,内核就有了操作此设备的能力。 file_operations的主要成员:open:打开设备release:关闭设备read:从设备上读数据write:向设备上写数据ioctl:I/O控制函数

12、 ioctl函数为设备驱动程序执行“命令”提供了一个特有的入口点用来设置或者读取设备的属性信息。int ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); cmd 参数的定义不推荐用0x1,0x2,0x3之类的值Linux对ioctl()的cmd参数有特殊的定义构造命令编号的宏:_IO(type,nr)用于构造无参数的命令编号;_IOR(type,nr,datatype)用于构造从驱动程序中读取数据的命令编号;_IOW(type,nr,datatype)用于写入数据的命令;_I

13、OWR(type,nr,datatype)用于双向传输。type和number位字段通过参数传入,而size位字段通过对datatype参数取sizeof获得。 Ioctl函数模板int xxx_ioctl( struct inode *inode, struct f ile *filp, unsigned int cmd, unsigned long arg) . switch (cmd) case XXX_CMD1: . break; case XXX_CMD2: . break; default: /*不能支持的命令 */ return - ENOTTY; return 0; 3.5字符

14、设备驱动结构 4.蜂鸣器原理 4.1蜂鸣器的种类和工作原理 蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。多谐振荡器由晶体管或集成电路构成。当接通电源后(1.515V直流工作电压),多谐振荡器起振,输出1.52.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。 有源蜂鸣器和无源蜂鸣器的区别

15、:这个“源”字是不是指电源,而是指震荡源,即有源蜂鸣器内有振荡源而无源蜂鸣器内部没有振荡源。有振荡源的通电就可以发声,没有振荡源的需要脉冲信号驱动才能发声。4.2开发板上蜂鸣器原理图分析由原理图可以得知,蜂鸣器是通过GPD0_0 IO口使用PWM信号驱动工作的,而GPD0_0口是一个复用的IO口,要使用它得先把他设置成TOUT0 PWM输出模式。 5.总体设计5.1设计思路 Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载: (1)直接编译进Linux内核,随同Linux启动时加载; (2)编译成一个可加载和删除的模块,使用insmod加载(modprob

16、e和insmod命令类似,但依赖于相关的配置文件),rmmod删除。这种方式控制了内核的大小,而模块一旦被插入内核,它就和内核其他部分一样。 这次的蜂鸣器驱动就采用动态模块加载的方式5.2设计步骤 编写简单的字符设别驱动程序框架 编写控制蜂鸣器控制开关函数 编译模块,生成.ko 编写用户层测试程序 编译用户层测试程序,生成可执行程序beep_test 将生成的.ko 模块和应用层测试程序 beep_test 下载到目标板 用 insmod 装载模块 创建设备节点 mknod /dev/beep c 250 0 运行用户层测试程序 beep_test#./beep_test如果你的 beep_t

17、est 的属性不是可执行的,可以用 chmod 777 beep_test 将其设置成可执行程序。6、驱动及测试程序6.1beep.c#include#include#include#include #include #include#include#include#include struct cdev beep_cdev;dev_t beep_devno;unsigned int *map;int beep_open(struct inode *node,struct file *fp) unsigned int data; request_mem_region(0xE02000A0,4,

18、beep); map=ioremap(0xE02000A0,8); data=ioread32(map); data=data&(0x11); data=data&(0x12); data=data&(0x13); data=data|0x1; iowrite32(data,map); printk(beep_openn); return 0;void beep_start(void) unsigned int data; data=ioread32(map+0x1); data=data|0x1; iowrite32(data,map+0x1);void beep_stop(void) un

19、signed int data; data=ioread32(map+0x1); data&=0x1; iowrite32(data,map+0x1);int beep_close(struct inode *node,struct file *fp) return 0;ssize_t beep_read(struct file *fp,char _user *buff,size_t len,loff_t *lfot) char load100=hellon; printk(beep_readn); copy_to_user(buff,load,100); return 0;ssize_t b

20、eep_write(struct file *fp,const char _user *buff,size_t len,loff_t *lfot) char load100; printk(beep_writen); copy_from_user(load,buff,100); printk(%sn,load); return 0;int beep_ioctl(struct inode * node, struct file *fp, unsigned int cmd , unsigned long parm) printk(beep_ioctln); switch(cmd) case 0:

21、beep_stop(); break; case 1: beep_start(); break; return 0;struct file_operations fops= .open=beep_open, .release=beep_close, .read=beep_read, .write=beep_write, .ioctl=beep_ioctl;static int _init beep_init(void) int major; alloc_chrdev_region(&beep_devno,0,1,beep); major=MAJOR(beep_devno); printk(ma

22、jor %dn,major); cdev_init(&beep_cdev,&fops); beep_cdev.owner=THIS_MODULE; beep_cdev.dev=beep_devno; beep_cdev.ops=&fops; beep_cdev.count=1; cdev_add(&beep_cdev,beep_devno,1); return 0;static void _exit beep_exit(void) unregister_chrdev_region(beep_devno,1); cdev_del(&beep_cdev);module_init(beep_init

23、);module_exit(beep_exit);6.2beep_tset.c#include#includeint main(void) int fp; char buff100=happy !n; fp=open(/dev/beep,O_RDWR); while(1) ioctl(fp,1,0); sleep(1); ioctl(fp,0,0); sleep(1); close(fp); return 1; 7.运行结果及截图8.综合设计总结与思考 这次的实习项目是嵌入式驱动设计,使蜂鸣器正常发出声音。由于之前还没有完全真正的接触过嵌入式驱动的相关方面的设计,也没有项目经验,所以需要学习的

24、知识比较的多。有关驱动的知识我也很陌生。关于Linux系统,这是我们这学期正在学的课程,所以对于Linux还是有一点基础。之后,又在老师的讲解下,我们了解了做驱动需要掌握内核函数和模块函数,把它们联系起来一起运用到所编的代码中。当然,实际的操作的过程并不是一帆风顺的。实践中还是遇到了很多的问题,不过也正是通过这种实践,也才使得自己的动手能力得到加强。最终通过询问老师以及和同学进行讨论使得遇到的问题都得以解决了。该设计是在Linux系统下进行编译,这学期我们刚学习了Linux课程,这对本次的设计有一定的帮助。但是由于我们在学校学的计算机专业课知识与企业所需的技术是有所脱节的,所以,在刚接触这个设

25、计课题的时候,还是有点无从下手,后来,在老师详细的分析和讲解后,对本次的设计任务才比较明确。 Linux设备驱动属于内核的一部分,Linux内核的一个模块可以以两种方式被编译和加载,这次的蜂鸣器驱动就采用动态模块加载的方式。在设计过程中,首先,要确定主设备号和次设备号,实现字符驱动程序,还需要实现file_operations结构体、实现初始化函数等等。在实验过程中遇到很多问题,通过和同学交流和询问老师,最终艰难地完成了实验设计。通过本次见习,让我对Linux系统更加熟悉了,还学习了一些驱动的知识,这对以后的就业也会有所帮助,在此非常感谢老师和学校给我们这么珍贵的学习机会。这次实习我感觉自己对于驱动的知识有了很大的了解,这也使我们更加有信心在以后的工作中能够灵活的运用这方面的知识。使我们自己在此次实习中学到的知识和经验充分的发挥。教师评阅 考勤情况设计态度设计完成情况实验报告优良中差优良中差优良中差优良中差

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1