主题 : 基于ARM-contexA9蜂鸣器驱动开发 复制链接 | 浏览器收藏 | 打印
人生没有什么不可以!
级别: 侠客
UID: 133854
精华: 0
发帖: 110
金钱: 550 两
威望: 110 点
贡献值: 0 点
综合积分: 220 分
注册时间: 2017-07-26
最后登录: 2018-12-19
楼主  发表于: 2017-11-22 11:26

 基于ARM-contexA9蜂鸣器驱动开发

上次,我们写了一个LED的驱动程序,这一节,我们只需稍微改动一下就可以实现蜂鸣器的驱动,让我们来看看吧。
     还是跟之前一样,先找电路图,找到电路板上对应的引脚和相关联的寄存器。
     1、看电路图
     (1)蜂鸣器接口位于电路板的底板,看电路图可知道是高电平有效。

   (2)相对应的找到核心板的接口。由此可知,我们的蜂鸣器是GPD0_0

接下来找数据手册,嵌入式物联网等系统学习企鹅意义气呜呜吧久零就易,找到对应的寄存器,然后配置它就可以了。
  2、查数据手册,找到相关的寄存器,并配置
(1)找到GPD0CON,地址是0x114000A0,我们需要配置GPD0CON(0)为输出状态。也就是写0x1这个值到这个寄存器。
 

(2)找到GPD0DAT这个寄存器,用于配置蜂鸣器的高低电平,物理地址是0x114000A4,刚好与上一个差4个字节的偏移
我们只要对这个寄存器写1和写0,那么蜂鸣器就可以叫起来了,哈哈。是不是很简单?

3、开始写驱动程序。

[plain] view plain copy print?
1.
#include <linux/init.h>  
2.
3.
#include <linux/module.h>  
4.
5.
#include <linux/kernel.h>  
6.
7.
#include <linux/fs.h>  
8.
9.
#include <linux/io.h>  
10.
11.
#include <asm/uaccess.h>  
12.
13.
#include <asm/irq.h>  
14.
15.
#include <asm/io.h>  
16.
17.
#define DEV_NAME    "test-dev"  
18.
19.
//定义蜂鸣器配置IO的地址   
20.
21.
#define GPD0CON  0x114000A0  
22.
23.
volatile unsigned long *bell_config = NULL ;   
24.
25.
volatile unsigned long *bell_dat = NULL ;   
26.
27.
int bell_open(struct inode *inode, struct file *filp)  
28.
29.
{  
30.
31.
    printk("bell_open\n");  
32.
33.
    //清寄存器   
34.
35.
    *bell_config &= ~(0xf);  
36.
37.
    //设置io为输出   
38.
39.
    *bell_config |= (0x1);  
40.
41.
    return 0;  
42.
43.
}  
44.
45.
  
46.
47.
int bell_close(struct inode *inode, struct file *filp)  
48.
49.
{  
50.
51.
    printk("bell_close\n");  
52.
53.
    //关闭蜂鸣器   
54.
55.
    *bell_dat &= ~0x1 ;  
56.
57.
    return 0;  
58.
59.
}  
60.
61.
  
62.
63.
long bell_ioctl(struct file *filp, unsigned int request, unsigned long arg)  
64.
65.
{  
66.
67.
    //控制蜂鸣器的状态   
68.
69.
    switch(request)  
70.
71.
    {  
72.
73.
        case 0:  
74.
75.
            printk(KERN_EMERG"bell on\n");  
76.
77.
            *bell_dat |= 0x1 ;  
78.
79.
            break;  
80.
81.
  
82.
83.
        case 1:  
84.
85.
            printk(KERN_EMERG"bell off\n");  
86.
87.
            *bell_dat &=~0x1 ;  
88.
89.
            break;  
90.
91.
    }  
92.
93.
    return 0 ;  
94.
95.
}  
96.
97.
  
98.
99.
struct file_operations fops = {  
100.
101.
    .owner = THIS_MODULE ,  
102.
103.
    .open = bell_open,  
104.
105.
    .release = bell_close,  
106.
107.
    .unlocked_ioctl = bell_ioctl,  
108.
109.
};  
110.
111.
  
112.
113.
int major ;  
114.
115.
int test_init(void)  
116.
117.
{  
118.
119.
    printk("bell_init\n");  
120.
121.
    //注册设备   
122.
123.
    major = register_chrdev(major, DEV_NAME, &fops);  
124.
125.
    //映射IO   
126.
127.
    bell_config = (volatile unsigned long *)ioremap(GPD0CON , 16);  
128.
129.
    //加4个字节偏移到GP0DAT顺便映射该物理地址   
130.
131.
    bell_dat = bell_config + 1 ;      
132.
133.
    return 0;  
134.
135.
}  
136.
137.
  
138.
139.
void test_exit(void)  
140.
141.
{  
142.
143.
    printk("bell_exit\n");  
144.
145.
    //解除注册   
146.
147.
    unregister_chrdev(major, DEV_NAME);  
148.
149.
    //取消映射   
150.
151.
    iounmap(bell_config);  
152.
153.
}  
154.
155.
  
156.
157.
module_init(test_init);  
158.
159.
module_exit(test_exit);  
160.
161.
  
162.
163.
MODULE_LICENSE("GPL");  
164.
165.
MODULE_AUTHOR("Y.X.YANG");  
166.
167.
MODULE_VERSION("2016.1.16");</span>  
168.
4、写测试程序
[plain] view plain copy print?
1.
#include <stdio.h>  
2.
3.
#include <sys/types.h>  
4.
5.
#include <sys/stat.h>  
6.
7.
#include <fcntl.h>  
8.
9.
  
10.
11.
int main(int argc, char **argv)  
12.
13.
{  
14.
15.
    int fd;  
16.
17.
    //打开设备   
18.
19.
    fd = open("/dev/test-dev",O_RDWR) ;  
20.
21.
    if(-1 == fd)  
22.
23.
    {  
24.
25.
        printf("open fair!\n");  
26.
27.
        return -1 ;  
28.
29.
    }  
30.
31.
    while(1){  
32.
33.
        //打开蜂鸣器   
34.
35.
        ioctl(fd,1);  
36.
37.
        sleep(1);  
38.
39.
        //关闭蜂鸣器   
40.
41.
        ioctl(fd,0);  
42.
43.
        sleep(1);  
44.
45.
    }  
46.
47.
    return 0;  
48.
49.
}</span>  
50.
5、编写makefile
[plain] view plain copy print?
1.
obj-m   += bell.o  
2.
3.
  
4.
5.
ROOTFS = /disk/A9/filesystem  
6.
7.
KERNEL = /disk/A9/linux-3.5/  
8.
9.
all:  
10.
11.
    make -C $(KERNEL) M=`pwd` modules  
12.
13.
  
14.
15.
clean:  
16.
17.
    make -C $(KERNEL) M=`pwd` clean  
18.
19.
    rm -rf my_bell  
20.
21.
  
22.
23.
install:  
24.
25.
    make -C $(KERNEL) M=`pwd` modules_install INSTALL_MOD_PATH=$(ROOTFS)  
26.
27.
  
28.
29.
my_bell:  
30.
31.
    arm-linux-gcc my_bell.c -o my_bell  
32.
33.
</span>  
34.
老是记不住手机号15617590525