博文

目前显示的是标签为“beep”的博文

C编程控制PC蜂鸣器方法2

在《C编程控制PC蜂鸣器》一文中,我们了解并使用了通过IO端口控制的方式操作硬件,而有些时候这对于一些朋友来说太模糊了,很容易让人迷糊,这次采用最基本的write系统调用来写入input_event数据实现相同功能。 这里涉及到的input_event可参考《C编程实现键盘LED闪烁方法2》一文,还有接下来要先加载pcspkr驱动,这个问题可查阅《Shell命令控制蜂鸣器发声》一文了解。 首先,执行sudo modprobe pcspkr命令加载驱动,然后查看/proc/bus/input/devices文件,我这边会有如下内容: I: Bus=0010 Vendor=001f Product=0001 Version=0100 N: Name=”PC Speaker” P: Phys=isa0061/input0 S: Sysfs=/devices/platform/pcspkr/input/input17 U: Uniq= H: Handlers=kbd event15 B: PROP=0 B: EV=40001 B: SND=6 这就是加载Linux内核drivers/input/misc/pcspkr.c文件对应的pcspkr驱动后所生成的。 而我们对应的input_event设置中,其type设置为EV_SND,而code可设置为SND_TONE和SND_BELL,其中前者只接受value为20至32767之间的值,其他值均为无声,后者接受0时无声,其他值时均会转为1000。 接下来上代码吧,你可以从代码中看到我们的处理: #include <stdio.h> #include <linux/input.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define PCSPKR_EVENT_PATH "/dev/input/event15" int main(int argc,char * argv[]) { unsigned int val; int fd = 0; struct input_event ev; e...

C编程控制PC蜂鸣器

在《I/O映射之I/O端口》一文中,我们实现了在Linux内核驱动里实现IO端口操作8254定时计数器芯片里的寄存器来实现PC主机蜂鸣器的控制,那么在C语言里是不是一样也能用io控制函数来操作呢?当然是可以的,只不过作为应用程序,其需要使用iopl或ioperm函数先获得IO操作的权限,其函数原型如下: 1.iopl - change I/O privilege level #include <sys/io.h> int iopl(int level); 2.ioperm - set port input/output permissions #include <unistd.h> /* for libc5 */ #include <sys/io.h> /* for glibc */ int ioperm(unsigned long from, unsigned long num, int turn_on); 其中,iopl修改程序运行时操作io的权限级别,默认是0,最大是3;而ioperm是设置从from开始的num个io端口turn_on状态。(详细看man) 有了《I/O映射之I/O端口》一文和上面的内容学习,接下来用C来实现就很容易了,其中关于inb等函数头可使用man inb命令查阅,下面上代码吧: #include <stdio.h> #include <unistd.h> #include <sys/io.h> /* The clock frequency of the i8253/i8254 PIT */ #define PIT_TICK_RATE 1193182ul void beep(unsigned int val) { unsigned int count = 0; if (val > 20 && val < 32767) count = PIT_TICK_RATE / val; iopl(3); if (count) { outb_p(0xB6, 0x43); ...

Shell命令控制蜂鸣器发声

在《I/O映射之I/O端口》一文中我们实现了在Linux驱动里通过IO端口操作PC机蜂鸣器发声,那么在Shell脚本里能否实现呢? 首先,我们先确认下自己的Ubuntu13.10里有没有安装beep这个命令?如果没有则使用如下命令进行安装: sudo apt-get install beep 安装好后,先看下其帮助信息吧,主要是下面这句: beep [–verbose –debug] [-e device –device device] [-f N] [-l N] [-r N] [-d N] [-D N] [-s] [-c] 其中, –verbose或–debug选项开启调试信息输出功能; -e device或–device device选项设定event设备,未指定则尝试/dev/tty0和/dev/vc/0两设备; -f N表示beep的频率为N Hz,0<N<20000; -l N表示beep多久,为N毫秒; -r N表示beep重复次数,默认为1; -d N和-D N表示两次重复间的延时为N毫秒,其中d则表示最后一次重复不发生该延时,而D则表示每次都有该延时; -s和-c表示beep时需从stdin读取,s表示每读一行,c表示每读一字符。 好了,下面还是先测试下有没有声音出来吧: beep -f 300.7 -r 2 -d 100 -l 400 我们用man beep里的例子进行测试,但声音没有出来?查了下,发现驱动没有加载: lsmod grep pcspkr 上面这条命令返回空,确认Linux kernel的配置里CONFIG_INPUT_PCSPKR=m,那就更肯定是没加载了,继续查,最后发现在/etc/modprobe.d/blacklist.conf文件里居然有如下这句: blacklist pcspkr 看来是每次启动时都被黑名单过滤掉了,我们手动加载下吧: sudo modprobe pcspkr 这时再执行上面的beep命令就有声音出来了,如果你需要在Shell脚本里使用beep命令,记得用上/usr/bin/beep这个绝对路径,别只用命令,还有如果该Shell脚本要每次启动都能成功执行,那么上面的blacklist一句记得注释掉。 参考网址: http...