本文通过TQ2440开发板上可外接的GPIO口GPG14连接蜂鸣器,通过控制GPG14引脚的高低电平的输出和高低电平输出之间的时间间隔来使蜂鸣器发出不同的声音。
1.打开S3C2440的底板原理图找到GPIO,如下图所示:
使用万用表先找到VDD5V那个引脚,然后对照图找到GPG14,将蜂鸣器的正极连上GPG14,负极连上GND接地。
Ubuntu下搭建TQ2440的程序下载环境
Ubuntu 12.04(32位)下TQ2440开发板环境搭建
2.蜂鸣器驱动程序源代码My_Beep.c:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h> //定义s3c2410的GPIO
#include <mach/hardware.h> //定义操作s3c2410的GPIO的函数
#include <linux/device.h> //自动创建设备文件应该包含的头文件
#define DEVICE_NAME "My_Beep" //加载模块后执行cat/proc/devices中看到的设备名称
#define Beep_MAJOR 104 //主设备号
#define Beep_High 1
#define Beep_Low 0
static int My_Beep_open(struct inode *inode,struct file *file)
{
s3c2410_gpio_cfgpin(S3C2410_GPG14,S3C2410_GPG14_OUTP);//配置GPG14为输出功能
printk("My_Beep open\n");
return 0;
}
static int My_Beep_ioctl(struct inode * inode, struct file * file,unsigned int cmd)
{
switch(cmd)
{
case Beep_High:
s3c2410_gpio_setpin(S3C2410_GPG14, 1);//设置GPG14引脚为输出电平为1
return 0;
case Beep_Low:
s3c2410_gpio_setpin(S3C2410_GPG14, 0);//设置GPG14引脚为输出电平为0
return 0;
default:
return -1;
}
}
//定义文件操作 file_operations
static struct file_operations My_Beep_fops =
{
.owner = THIS_MODULE,
.open = My_Beep_open,
.ioctl = My_Beep_ioctl,
};
static struct class *Beep_class;
static int __init My_Beep_init(void)
{
int ret;
printk("My_Beep start\n");
//注册字符设备驱动程序
//参数为主设备号、设备名字、file_operations结构
//这样主设备号就与file_operations联系起来
ret = register_chrdev(Beep_MAJOR, DEVICE_NAME, &My_Beep_fops);
if(ret < 0)
{
printk("can't register major number\n");
return ret;
}
//注册一个类,使mdev可以在"/dev/目录下建立设备节点"
Beep_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(Beep_class))
{
printk("failed in My_Beep class.\n");
return -1;
}
device_create(Beep_class, NULL, MKDEV(Beep_MAJOR,0), NULL, DEVICE_NAME);
printk(DEVICE_NAME "initialized\n");
return 0;
}
static void __exit My_Beep_exit(void)
{
unregister_chrdev(Beep_MAJOR, DEVICE_NAME);
device_destroy(Beep_class, MKDEV(Beep_MAJOR,0));//注销设备节点
class_destroy(Beep_class);//注销类
}
module_init(My_Beep_init);
module_exit(My_Beep_exit);
MODULE_LICENSE("GPL");
源码分析:
本驱动程序通过linux系统内核中对S3C2410 GPIO操作的函数来实现对GPG14引脚输出功能和引脚高低电平输出功能的配置。
s3c2410_gpio_cfgpin(S3C2410_GPG14,S3C2410_GPG14_OUTP) 这行代码实现了配置GPG14为输出模式的功能。s3c2410_gpio_cfgpin这个函数定义在内核源码中的hardware.h头文件中,使用此函数需要包含头文件 #include<mach/hardware.h> 。
S3C2410_GPG14是GPIO的编号,S3C2410_GPG14_OUTP是端口的功能,他们都定义在内核源码的regs-gpio.h头文件中。