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,那些总线了,有点小难度的那些。接下里好好看看书吧还是。。。。。。

  • 相关阅读:
    start pyhton project(2)
    java.lang.ClassFormatError: Truncated class file
    linux 查看计算机信息命令
    VS2010UltimTrialCHS 版注册码
    VS2008打包安装程序,实现覆盖安装设置
    WPF移动不规则渐变色窗体
    C#下移动无边框窗体(直接粘贴可用)
    TCP通信过程中时时监测连接是否已断开
    WIN7下使用DotNetBar,关闭Aero效果,使用Office2007Form皮肤
    【原创】企业级工作流管理系统评价依据或标准
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300087.html
Copyright © 2011-2022 走看看