zoukankan      html  css  js  c++  java
  • 和菜鸟一起学OK6410之蜂鸣器buzzer字符驱动

            夕阳的谢幕,随之而出的明月,虽然刚刚回过家,但是还是想念,想念大海,想念妈妈烧的菜,也许真的是一个人久了吧。双休日,连个说话的人都没有,只是自己一个人,闷闷地看着书,写着Blog,天气太热,也懒得出去逛。收拾收拾心情,开始继续OK6410吧。

            昨天把led灯实现了,今天就玩个蜂鸣器吧,然后那些小的,简单的外围就告一段落了,接着再好好看看ldd3linux内核等吧。打好基础再来写下自己之所学。

    好了,开始蜂鸣器吧。还是一样,先上驱动的代码:

     

     

    #include <linux/module.h>
    
    #include <linux/kernel.h>
    
    #include <linux/fs.h>
    
    #include <linux/init.h>
    
    #include <linux/miscdevice.h>
    
    #include <linux/delay.h>
    
    #include <asm/uaccess.h>
    
    #include <linux/device.h>
    
    #include <linux/cdev.h>
    
    #include <asm/irq.h>
    
    #include <mach/gpio.h>
    
    #include <plat/regs-gpio.h>
    
    #include <plat/gpio-cfg.h>
    
    #include <mach/hardware.h>
    
    #include <linux/io.h>
    
     
    
    #define BUZZER_MAJOR 240
    
     
    
    int buzzer_open(struct inode *inode, struct file *filp)
    
    {
    
        unsigned int tmp;
    
        tmp = readl(S3C64XX_GPFCON);
    
        tmp = (tmp & ~(0xc0000000) | (0x40000000)); //set the GPIO output mode
    
        writel(tmp, S3C64XX_GPFCON);
    
        printk("$$$$$$$$$$$buzzer_open$$$$$$$$$\n");
    
    return 0;
    
    }
    
     
    
    ssize_t buzzer_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
    
    {
    
        printk("$$$$$$$$$$buzzer_read$$$$$$$$$\n");
    
    return count;
    
    }
    
     
    
     
    
    ssize_t buzzer_write(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
    
    {
    
        char mbuf[10];
    
        unsigned int tmp;
    
        copy_from_user(mbuf,buf,count);
    
        
    
        switch(mbuf[0])
    
        {
    
            case 0:
    
                tmp = readl(S3C64XX_GPFDAT);
    
                tmp |= (0x8000);
    
                writel(tmp, S3C64XX_GPFDAT);
    
                break;
    
            case 1:
    
                tmp = readl(S3C64XX_GPFDAT);
    
                tmp &= ~(0x8000); 
    
                writel(tmp, S3C64XX_GPFDAT);
    
                break;
    
            default:
    
                break;
    
        }
    
        
    
        printk("$$$$$$$$$$buzzer_write$$$$$$$$$\n");
    
    return count;
    
    }
    
     
    
    int buzzer_release(struct inode *inode, struct file *filp)
    
    {
    
        printk("$$$$$$$$$$buzzer_release$$$$$$$$$\n");
    
    return 0;
    
    }
    
     
    
    struct file_operations my_fops = {
    
        .owner = THIS_MODULE,
    
        .open = buzzer_open,
    
        .read = buzzer_read,
    
        .write = buzzer_write,
    
        .release = buzzer_release,
    
    };
    
     
    
    static int buzzer_init(void)
    
    {
    
        int rc;
    
        printk("Test buzzer dev\n");
    
        rc = register_chrdev(BUZZER_MAJOR, "buzzer", &my_fops);
    
        if(rc < 0)
    
        {
    
            printk("register %s  dev error\n", "buzzer");
    
            return -1;
    
        }
    
        printk("$$$$$$$$$ register buzzer dev OK\n");
    
    return 0;
    
    }
    
     
    
    static void buzzer_exit(void)
    
    {
    
        unregister_chrdev(BUZZER_MAJOR, "buzzer");
    
        printk("Good Bye!\n");
    
    }
    
     
    
    MODULE_LICENSE("GPL");
    
    module_init(buzzer_init);
    
    module_exit(buzzer_exit);
    
    


     

            和led灯一样,蜂鸣器也是通过控制GPIO口来控制的。原理图如下:

             那么pwm_tout1对应的GPIO口是那一个呢?再看原理图:

            是GPF15,那么就只要控制GPF15这个GPIO口就好了,详细看看他的寄存器吧

            控制寄存器是31-30这两位,因为输出,所以设置为01就好了,具体代码就是:

     

        tmp = readl(S3C64XX_GPFCON);
    
        tmp = (tmp & ~(0xc0000000) | (0x40000000)); //set the GPIO output mode
    
        writel(tmp, S3C64XX_GPFCON);
    
    


            然后看看他的数据寄存器吧。和led一样的。好了。

            代码基本和led没啥区别。

            接着就是makefile了:

        obj-m :=buzzer.o
    
    


             然后建个makemod,代码如下

    make -C /home/eastmoon/work/linux2.6.28/ M=`pwd` modules
    
    


     

            然后只要source makemod就可以编译成buzzer.ko

     

            好了,驱动部分搞定了,那么接着就是要写应用程序了

    #include <stdio.h>
    
    #include <sys/types.h>
    
    #include <sys/stat.h>
    
    #include <fcntl.h>
    
     
    
    #define DEVICE "/dev/mybuzzer"
    
     
    
    int main(void)
    
    {
    
        int fd, i;
    
        char buf[10] = {0, 1};
    
        fd = open(DEVICE, O_RDWR);
    
        if(fd < 0)
    
        {
    
            printf("Open /dev/mybuzzer file error\n");
    
            return -1;
    
        }
    
        
    
        while(1)
    
        {
    
            write(fd, &buf[0], 1);
    
            usleep(10000);
    
            write(fd, &buf[1], 1);
    
            usleep(10000);
    
        }
    
        close(fd);
    
    return 0;
    
    }
    
    


            接着makefile

     

    CC = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-gcc 
    
     
    
    buzzerapp:buzzerapp.o
    
           $(CC) -o buzzerapp buzzerapp.o
    
    buzzerapp.o:buzzerapp.c 
    
           $(CC) -c buzzerapp.c
    
     
    
    clean :
    
           rm buzzerapp.o
    
    


     

               完成,也不知道可不可以成功,那么就下载到板子上看看结果吧:

     

     

            注册成功。然后接着mknod设备文件

            节点也出来了/dev/mybuzzer。就这就运行下应用程序好了

     

             蜂鸣器也发出声音了,OK,搞定了。这样,OK6410,嵌入式linux也算是入了小门了。剩下的就是什么SPI啊,I2C啊,USB,那些总线了,有点小难度的那些。接下里好好看看书吧还是。。。。。。

  • 相关阅读:
    luogu 1865 数论 线性素数筛法
    洛谷 2921 记忆化搜索 tarjan 基环外向树
    洛谷 1052 dp 状态压缩
    洛谷 1156 dp
    洛谷 1063 dp 区间dp
    洛谷 2409 dp 月赛题目
    洛谷1199 简单博弈 贪心
    洛谷1417 烹调方案 dp 贪心
    洛谷1387 二维dp 不是特别简略的题解 智商题
    2016 10 28考试 dp 乱搞 树状数组
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300087.html
Copyright © 2011-2022 走看看