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

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

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

 

 


 
  1. #include <linux/module.h>  
  2.   
  3. #include <linux/kernel.h>  
  4.   
  5. #include <linux/fs.h>  
  6.   
  7. #include <linux/init.h>  
  8.   
  9. #include <linux/miscdevice.h>  
  10.   
  11. #include <linux/delay.h>  
  12.   
  13. #include <asm/uaccess.h>  
  14.   
  15. #include <linux/device.h>  
  16.   
  17. #include <linux/cdev.h>  
  18.   
  19. #include <asm/irq.h>  
  20.   
  21. #include <mach/gpio.h>  
  22.   
  23. #include <plat/regs-gpio.h>  
  24.   
  25. #include <plat/gpio-cfg.h>  
  26.   
  27. #include <mach/hardware.h>  
  28.   
  29. #include <linux/io.h>  
  30.   
  31.    
  32.   
  33. #define BUZZER_MAJOR 240  
  34.   
  35.    
  36.   
  37. int buzzer_open(struct inode *inode, struct file *filp)  
  38.   
  39. {  
  40.   
  41.     unsigned int tmp;  
  42.   
  43.     tmp = readl(S3C64XX_GPFCON);  
  44.   
  45.     tmp = (tmp & ~(0xc0000000) | (0x40000000)); //set the GPIO output mode  
  46.   
  47.     writel(tmp, S3C64XX_GPFCON);  
  48.   
  49.     printk("
     
     
    $buzzeropen
     
    $$$\n");  
  50.   
  51. return 0;  
  52.   
  53. }  
  54.   
  55.    
  56.   
  57. ssize_t buzzer_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)  
  58.   
  59. {  
  60.   
  61.     printk("
     
     
    buzzerread
     
    $$$\n");  
  62.   
  63. return count;  
  64.   
  65. }  
  66.   
  67.    
  68.   
  69.    
  70.   
  71. ssize_t buzzer_write(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)  
  72.   
  73. {  
  74.   
  75.     char mbuf[10];  
  76.   
  77.     unsigned int tmp;  
  78.   
  79.     copy_from_user(mbuf,buf,count);  
  80.   
  81.       
  82.   
  83.     switch(mbuf[0])  
  84.   
  85.     {  
  86.   
  87.         case 0:  
  88.   
  89.             tmp = readl(S3C64XX_GPFDAT);  
  90.   
  91.             tmp |= (0x8000);  
  92.   
  93.             writel(tmp, S3C64XX_GPFDAT);  
  94.   
  95.             break;  
  96.   
  97.         case 1:  
  98.   
  99.             tmp = readl(S3C64XX_GPFDAT);  
  100.   
  101.             tmp &= ~(0x8000);   
  102.   
  103.             writel(tmp, S3C64XX_GPFDAT);  
  104.   
  105.             break;  
  106.   
  107.         default:  
  108.   
  109.             break;  
  110.   
  111.     }  
  112.   
  113.       
  114.   
  115.     printk("
     
     
    buzzerwrite
     
    $$$\n");  
  116.   
  117. return count;  
  118.   
  119. }  
  120.   
  121.    
  122.   
  123. int buzzer_release(struct inode *inode, struct file *filp)  
  124.   
  125. {  
  126.   
  127.     printk("
     
     
    buzzerrelease
     
    $$$\n");  
  128.   
  129. return 0;  
  130.   
  131. }  
  132.   
  133.    
  134.   
  135. struct file_operations my_fops = {  
  136.   
  137.     .owner = THIS_MODULE,  
  138.   
  139.     .open = buzzer_open,  
  140.   
  141.     .read = buzzer_read,  
  142.   
  143.     .write = buzzer_write,  
  144.   
  145.     .release = buzzer_release,  
  146.   
  147. };  
  148.   
  149.    
  150.   
  151. static int buzzer_init(void)  
  152.   
  153. {  
  154.   
  155.     int rc;  
  156.   
  157.     printk("Test buzzer dev\n");  
  158.   
  159.     rc = register_chrdev(BUZZER_MAJOR, "buzzer", &my_fops);  
  160.   
  161.     if(rc 0)  
  162.   
  163.     {  
  164.   
  165.         printk("register %s  dev error\n", "buzzer");  
  166.   
  167.         return -1;  
  168.   
  169.     }  
  170.   
  171.     printk("
     
     
    $ register buzzer dev OK\n");  
  172.   
  173. return 0;  
  174.   
  175. }  
  176.   
  177.    
  178.   
  179. static void buzzer_exit(void)  
  180.   
  181. {  
  182.   
  183.     unregister_chrdev(BUZZER_MAJOR, "buzzer");  
  184.   
  185.     printk("Good Bye!\n");  
  186.   
  187. }  
  188.   
  189.    
  190.   
  191. MODULE_LICENSE("GPL");  
  192.   
  193. module_init(buzzer_init);  
  194.   
  195. module_exit(buzzer_exit);  


 

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

 

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

 

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

 

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

 

[html] view plaincopy
 
  1. tmp = readl(S3C64XX_GPFCON);  
  2.   
  3. tmp = (tmp & ~(0xc0000000) | (0x40000000)); //set the GPIO output mode  
  4.   
  5. writel(tmp, S3C64XX_GPFCON);  

 

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

        代码基本和led没啥区别。

        接着就是makefile了:

[html] view plaincopy
 
  1. obj-m :=buzzer.o  


         然后建个makemod,代码如下

[html] view plaincopy
 
  1. make -C /home/eastmoon/work/linux2.6.28/ M=`pwd` modules  


 

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

 

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

[html] view plaincopy
 
  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. #define DEVICE "/dev/mybuzzer"  
  12.   
  13.    
  14.   
  15. int main(void)  
  16.   
  17. {  
  18.   
  19.     int fd, i;  
  20.   
  21.     char buf[10] = {0, 1};  
  22.   
  23.     fd = open(DEVICE, O_RDWR);  
  24.   
  25.     if(fd 0)  
  26.   
  27.     {  
  28.   
  29.         printf("Open /dev/mybuzzer file error\n");  
  30.   
  31.         return -1;  
  32.   
  33.     }  
  34.   
  35.       
  36.   
  37.     while(1)  
  38.   
  39.     {  
  40.   
  41.         write(fd, &buf[0], 1);  
  42.   
  43.         usleep(10000);  
  44.   
  45.         write(fd, &buf[1], 1);  
  46.   
  47.         usleep(10000);  
  48.   
  49.     }  
  50.   
  51.     close(fd);  
  52.   
  53. return 0;  
  54.   
  55. }  


        接着makefile

 


  1. CC = /usr/local/arm/4.2.2-eabi/usr/bin/arm-linux-gcc   
  2.   
  3.    
  4.   
  5. buzzerapp:buzzerapp.o  
  6.   
  7.        $(CC) -o buzzerapp buzzerapp.o  
  8.   
  9. buzzerapp.o:buzzerapp.c   
  10.   
  11.        $(CC) -c buzzerapp.c  
  12.   
  13.    
  14.   
  15. clean :  
  16.   
  17.        rm buzzerapp.o  


 

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

 

 

 

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

 

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

 

 

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