蜂鸣器驱动程序设计.docx
- 文档编号:6095428
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:16
- 大小:185.73KB
蜂鸣器驱动程序设计.docx
《蜂鸣器驱动程序设计.docx》由会员分享,可在线阅读,更多相关《蜂鸣器驱动程序设计.docx(16页珍藏版)》请在冰豆网上搜索。
蜂鸣器驱动程序设计
蜂鸣器驱动
课程设计
专业:
xxxxxxxxxxxxxx
班级:
xxxxxxxxx
学号:
xxxxxxxxx
姓名:
xxxx
设计题目:
蜂鸣器驱动程序设计
2016年12月
5.tiny210开发板调试..............................................................................................................9
6.综合设计总结与思考.............................................................................................10
1.任务
1.目标:
编写按键蜂鸣器驱动程序函数与测试文件,实现上位机与tiny210-SDK开发板的连接,利用函数实现对蜂鸣器通过按键来启动与关闭。
2.环境:
①软件环境:
windows7系统和VMwareWorkstation软件
②硬件环境:
tiny210开发板,内核部分Linux-3.0.8,交叉编译版本arm-linux-gcc-4.5.1-v6-vfp1
Linux系统介绍:
Linux是一种自由开发源码的类Unix操作系统,存在这许多不同的Linux版本,但它们都使用了Linux内核。
Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。
Linux是一个领先的操作系统,世界上运算最快的10台超级计算机运行的都是Linux操作系统。
严格来说,Linux这个词本身只表示Linux内核,但实际上人们已经习惯了用Linux来形容整个基于Linux内核,并且使用GNU工程各种工具和数据库的操作系统。
Linux得名于天才程序员林纳斯·托瓦兹。
tiny210开发板中模块介绍:
①PWM蜂鸣器模块
PWM(脉冲宽度调制)简单的讲是一种变频技术之一,是靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率。
来看看我们实际生活中的例子,我们的电风扇为什么扭一下按扭,风扇的转速就会发生变化;调一下收音机的声音按钮,声音的大小就会发生变化。
这些都是PWM的应用,都是通过PWM输出的频率信号进行控制的。
②蜂鸣器的种类和工作原理
蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。
有的压电式蜂鸣器外壳上还装有发光二极管。
多谐振荡器由晶体管或集成电路构成。
当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。
电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。
接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。
振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
有源蜂鸣器和无源蜂鸣器的区别:
这个“源”字是不是指电源,而是指震荡源,即有源蜂鸣器内有振荡源而无源蜂鸣器内部没有振荡源。
有振荡源的通电就可以发声,没有振荡源的需要脉冲信号驱动才能发声。
3.需求:
要实现PC与tiny210开发板的通信,要求在PC机上的VMwareWorkstation软件的RedHatEnterpriseLinux环境下编写程序,包含蜂鸣器驱动程序和测试文件。
利用交叉编译器arm-linux-gcc-4.5.1-v6-vfp1生成目标文件,最后讲目标文件下载到开发板,并且驱动蜂鸣器根据按键的不同完成启动或者停止的操作。
2.总体设计
1.处理流程:
2.模块介绍:
①按键模块:
通过按键来操作蜂鸣器的启动与停止。
②蜂鸣器模块:
通过加载蜂鸣器驱动模块到内核,驱动蜂鸣器。
①按键模块:
A.正确驱动主设备号和次设备号
B.实现字符设备驱动程序
C.实现file-operation结构
D.实现初始化函数,注册字符设备
E.实现卸载函数,释放字符设备
F.创建文件节点
②按键模块:
G.正确驱动住设备号和次设备号
H.实现字符设备驱动程序
I.实现file-operation结构
J.实现初始化函数,注册字符设备
K.实现卸载函数,释放字符设备
L.创建文件节点
模块设计:
(1)beep.c
#include
#include
#include
#include
#include
#include
#include
staticintbeep_major=0;
staticdev_tbeep_devno;
staticstructcdevbeep_cdev;
staticint*pload=NULL;
#defineBEEPNUM3
staticintstr_len(char*str)
{
intcount=0;
while(*str!
='\0')
{
count++;
str++;
}
returncount;
}
ssize_tbeep_read(structfile*fp,char__user*buff,size_tcount,loff_t*fps)
{
charstring[20]="HELLO,EVERYONE\n";
intretur=0;
printk("%s\n",__FUNCTION__);
retur=copy_to_user(buff,string,str_len(string)+1);
returnretur;
}
ssize_tbeep_write(structfile*fp,constchar__user*buff,size_tcount,loff_t*fps)
{
charstring[100];
intretur=0;
printk("%s",__FUNCTION__);
retur=copy_from_user(string,buff,count);
printk("kernal---->%s\n",string);
returnretur;
}
intbeep_open(structinode*nodep,structfile*fp)
{
unsignedintvalue=0;
printk("%s\n",__FUNCTION__);
pload=ioremap(0XE02000A0,16);//convertregisterphysicaladdresstovirtualaddress
value=ioread32(pload);
value&=~0x1<<3;
value&=~0x1<<2;
value&=~0x1<<1;
value|=0x1<<0;
iowrite32(value,pload);
return0;
}
intbeep_release(structinode*nodep,structfile*fp)
{
printk("%s\n",__FUNCTION__);
return0;
}
voidbeep_start(void)
{
unsignedintvalue=0;
value=ioread32(pload+1);//readdataregister
value|=0x1<<0;
iowrite32(value,pload+1);
}
voidbeep_stop(void)
{
unsignedintvalue=0;
value=ioread32(pload+1);//readdataregister
value&=~0x1<<0;
iowrite32(value,pload+1);
}
longbeep_unlocked_ioctl(structfile*fp,unsignedintcmd,unsignedlongparam)
{
printk("%s\n",__FUNCTION__);
switch(cmd)
{
case0:
//beepstop
beep_stop();
break;
case1:
//beepstart
beep_start();
break;
}
return0;
}
staticstructfile_operationsbeep_ops=
{
.open=beep_open,
.release=beep_release,
.read=beep_read,
.write=beep_write,
.unlocked_ioctl=beep_unlocked_ioctl
};
staticvoidalloc_beep_dev_num(void)
{
if(beep_major>0)
{
beep_devno=MKDEV(beep_major,0);
register_chrdev_region(beep_devno,BEEPNUM,"beep");
}
else
{
alloc_chrdev_region(&beep_devno,0,BEEPNUM,"beep");
beep_major=MAJOR(beep_devno);
}
printk("beep_major=%d\n",beep_major);
}
staticvoidinitial_cdev(void)
{
cdev_init(&beep_cdev,&beep_ops);
beep_cdev.owner=THIS_MODULE;
beep_cdev.ops=&beep_ops;
beep_cdev.dev=beep_devno;
beep_cdev.count=BEEPNUM;
cdev_add(&beep_cdev,beep_devno,BEEPNUM);//registeracdevvariabletolinuxkernel
}
staticint__initbeep_init(void)
{
printk("%s\n",__FUNCTION__);
alloc_beep_dev_num();//getdevicenumber
initial_cdev();//initialandregistercdevvariable
return0;
}
staticvoid__exitbeep_exit(void)
{
printk("%s\n",__FUNCTION__);
unregister_chrdev_region(beep_devno,BEEPNUM);
cdev_del(&beep_cdev);
return;
}
module_init(beep_init);
module_exit(beep_exit);
3.PWM蜂鸣器字符设备驱动
1.蜂鸣器模块介绍及结构图
开发板上蜂鸣器原理图分析
由原理图可以得知,蜂鸣器是通过GPD0IO口使用PWM信号驱动工作的,而GPD0口是一个复用的IO口,要使用它得先把他设置成TOUT0PWM输出模式。
GPD0参数
要让蜂鸣器发声,需要两大要素:
①将蜂鸣器接到正确的端口并且设置为输出口,②将端口设置为高电平
要使蜂鸣器发声,就是要让GPD0作为输出端,同时该端口要设为高电平。
也就是说GPD0设置为01为输出,让GPDDAT的最后一位设置为1则该端口就置成了高电平。
2模块代码分析:
2.1打开设备模块
intbeep_open(structinode*nodep,structfile*fp)
{
unsignedintvalue=0;
printk("%s\n",__FUNCTION__);
pload=ioremap(0XE02000A0,16);//convertregisterphysicaladdresstovirtualaddress
value=ioread32(pload);
value&=~0x1<<3;
value&=~0x1<<2;
value&=~0x1<<1;
value|=0x1<<0;
iowrite32(value,pload);
return0;
}
此函数实现了怎么去打开设备,在设备文件上的第一个操作,并不要求驱动程序一定要实现这个方法。
如果该项为NULL,设备的打开操作永远成功。
Open方法是驱动程序用来为以后的操作完成初始化准备工作的。
在大部分驱动程序中,open完成如下工作:
初始化设备,标明次设备号。
2.2关闭设备模块
intbeep_release(structinode*fnode,structfile*fs)
{
printk("%s\n",__FUNCTION__);
return0;
}
当设备文件被关闭时调用这个操作。
与open相仿,release也可以没有,此处关闭函数为beep_release。
Release方法的作用正好与open相反,它应该:
关闭设备。
本驱动程序要进行读和写。
ssize_tbeep_read(structfile*fp,char__user*buff,size_tcount,loff_t*fps)
{
charstring[20]="HELLO,EVERYONE\n";
intretur=0;
printk("%s\n",__FUNCTION__);
retur=copy_to_user(buff,string,str_len(string)+1);
returnretur;
}
ssize_tbeep_write(structfile*fp,constchar__user*buff,size_tcount,loff_t*fps)
{
charstring[100];
intretur=0;
printk("%s",__FUNCTION__);
retur=copy_from_user(string,buff,count);
printk("kernal---->%s\n",string);
returnretur;
}
2.3开启蜂鸣器
voidbeep_start(void)
{
unsignedintvalue=0;
value=ioread32(pload+1);//readdataregister
value|=0x1<<0;
iowrite32(value,pload+1);
}
2.4关闭蜂鸣器
voidbeep_stop(void)
{
unsignedintvalue=0;
value=ioread32(pload+1);//readdataregister
value&=~0x1<<0;
iowrite32(value,pload+1);
}
恢复GPD0口为IO口输出功能,由原理图可知直接给低电平可让蜂鸣器停止工作。
2.5ioctl控制模块
longbeep_unlocked_ioctl(structfile*fp,unsignedintcmd,unsignedlongparam)
{
printk("%s\n",__FUNCTION__);
switch(cmd)
{
case0:
//beepstop
beep_stop();
break;
case1:
//beepstart
beep_start();
break;
}
return0;
}
应用程序向设备发送命令,设备接受到命令并进行解析,并做相应的设置并启动设备工作或停止工作。
如果输入的参数大于0,就让蜂鸣器开始工作,不同的参数,蜂鸣器的频率也不一样。
2.6重要数据结构模块
在Linux字符设备驱动程序设计中,有3种非常重要的数据结构:
Structfile
Structinode
Structfile_operations
StructFile代表一个打开的文件。
系统中每个打开的文件在内核空间都有一个关联的structfile。
它由内核在打开文件时创建,在文件关闭后释放。
重要成员:
loff_t*fp/*文件读写位置*/
structfile_operations*fp
StructInode用来记录文件的物理上的信息。
因此,它和代表打开文件的file结构是不同的。
一个文件可以对应多个file结构,但只有一个inode结构。
重要成员:
dev_t:
设备号
structfile_operations一个函数指针的集合,定义能在设备上进行的操作。
结构中的成员指向驱动中的函数,这些函数实现一个特别的操作,对于不支持的操作保留为NULL。
staticstructfile_operationsbeep_ops=
{
.open=beep_open,
.release=beep_release,
.read=beep_read,
.write=beep_write,
.unlocked_ioctl=beep_unlocked_ioctl,
}
2.7
在linux内核中,字符设备使用structcdev来描述。
字符设备的注册可分为如下3个步骤:
分配cdev
初始化cdev
添加cdev
Structcdev的分配可使用cdev_alloc函数来完成。
Structcdev的初始化使用cdev_init函数来完成。
structcdev的注册使用cdev_add函数来完成。
2.8设备注销模块
staticvoid__exitbeep_exit(void)
{
printk("%s\n",__FUNCTION__);
unregister_chrdev_region(beep_devno,BEEPNUM);
cdev_del(&beep_cdev);
return;
}
此函数实现该混杂设备的注销。
4.蜂鸣器驱动测试模块和截图
1、模块代码:
#include
#include
#include
#include
intmain(void)
{
intfp=0;
inti=0;
fp=open("/dev/beep",O_RDWR,0x777);
if(fp<=0)
{
printf("failinopeningbeepdevicefile\n");
return0;
}
while(i<5)
{
ioctl(fp,1,0);
sleep
(1);
ioctl(fp,0,0);
sleep
(1);
i++;
}
close(fp);
return0;
}
测试程序解析:
该测试程序先执行打开设备文件,往设备中写入命令和参数来实现对蜂鸣器的控制。
蜂鸣器的开启与关闭间隔及蜂鸣器的频率取决于往设备里写的命令与参数。
运行结果及截图
beep_open蜂鸣器开始工作,beep_release蜂鸣器停止工作
五.tiny210开发板调试
1.tiny210开发板测试步骤:
(1)连接开发板电源。
(2)用串口将PC和tiny210开发板相连。
(3)打开SecureCRT软件,点击快速连接,配置端口
协议:
Serial
端口:
comn(看自己的端口号)
波特率:
115200
数据位:
8
奇偶校验:
none
停止位:
1
勾掉RTS/CTS选项
(4)点击连接
(5)打开开发板电源
(6)SecureCRT软件会出现一些选项,选择b,rootsystem
(7)输入指令rz,将beep.ko和pp加载到根文件系统里,再输入指令,将beep测试程序加载到根文件系统。
(8)在SecureCRT里输入insmodbeep.ko,将驱动程序加载到内核模块中。
(9)在SecureCRT里输入chmod777beep,改变可执行程序的权限。
(10)在SecureCRT里输入./pp。
观看实验现象
六.综合设计总结与思考
这一次易嵌的培训实习,老师给我们安排的设计题目是蜂鸣器驱动程序的设计及开发。
第一天培训的时候,老师教我们安装VMwareWorkstation软件,由于电脑问题软件装来装去弄了好几遍,虽然花费了不少时间,但也更深刻地记住了软件如何安装和调试的。
软件装好后实现虚拟操作环境,首先在虚拟环境中学会编辑简单的C语言(100以内数字输入以及冒泡法排序)及其编译,通过简单的编程,掌握了软件最基本的调试方法和步骤。
蜂鸣器设计是最主要也是最难理解的,程序语句相对于基本功没那么扎实的我们来说比较难理解,需要先弄清每个模块的功能,然后再去理解每个模块语句的含义,基础太差语句理解的较困难。
经过后两天半老师细心的讲解才有了大致的理解,也初步把学习的课程知识应用到实际操作中,明白课程学习的重要性以及C语言在本专业的重要性,以后学习中还是要多花些时间在编程上,好好提高自己的专业技能。
第一次接触linux操作,会有很多不理解的地方,也是因为对新知识的不了解,通过本次试训自己也在思考自己以后的就业方向以及课程学习的重点,好好利用课余时间多学点知识。
考勤情况
设计态度
设计完成情况
实验报告
优
良
中
差
优
良
中
差
优
良
中
差
优
良
中
差
成绩:
WelcomeTo
Download!
!
!
欢迎您的下载,资料仅供参考!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 蜂鸣器 驱动程序 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)