微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 无线和射频 > 射频无线通信设计 > 6.DB410c开发板基于GPIO模型实现蜂鸣器功能测试。

6.DB410c开发板基于GPIO模型实现蜂鸣器功能测试。

时间:10-02 整理:3721RD 点击:
这个帖子主要理解如何自己实现一个简单驱动。
自己使用是某宝买来的无源蜂鸣器,它内部不带震荡源所以直流信号无法令其鸣叫,必须用2K~5K的方波去驱动它。广泛应用于计算机、报警器、电子玩具、汽车电子设备、定时器等电子产品中作发声器件。
驱动代码主要是参考论坛某人的大作,这个特意表示感谢。
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c-gpio.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/fs.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/cdev.h>
#include "buzzer_drv.h"
static int major;
static int minor;
struct cdev *buzzer; /* cdev 数据结构 */
static dev_t devno; /* 设备编号 */
static struct class *buzzer_class;
#define DEVICE_NAME "buzzer"
#define GPIO_BUZZER_PIN_NUM 12 //(2*32 + 12) /*gpio 2_12 */
static int buzzer_open(struct inode *inode,struct file *file )
{
        try_module_get(THIS_MODULE);
        gpio_direction_output(GPIO_BUZZER_PIN_NUM,1);
        return 0;
}
static int buzzer_release(struct inode*inode, struct file *file )
{
        module_put(THIS_MODULE);
        gpio_direction_output(GPIO_BUZZER_PIN_NUM,1);
        return 0;
}
#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,36)
static int buzzer_ioctl(struct file *filp,unsigned int cmd, unsigned long arg)
#else
static int buzzer_ioctl(struct inode*inode, struct file *file, unsigned int cmd, unsigned long arg)
#endif
{
                printk(KERN_INFO "buzzer_ioctl cmd=%d BUZZER_IOC_MAGIC=%d BUZZER_IOCTL_MAXNR=%d\n", cmd, BUZZER_IOC_MAGIC, BUZZER_IOCTL_MAXNR);
#if 0
        if(cmd != BUZZER_IOC_MAGIC) {
                 return -ENOTTY;
        }
        if(cmd > BUZZER_IOCTL_MAXNR) {
                 return -ENOTTY;
        }
        #endif
                printk(KERN_INFO "buzzer_ioctl cmd=%d BUZZER_ON=%d BUZZER_OFF=%d\n", cmd, BUZZER_ON, BUZZER_OFF);
        switch(cmd){
                 case BUZZER_ON:
                 gpio_set_value(GPIO_BUZZER_PIN_NUM,1);
                 break;
                 case BUZZER_OFF:
                 gpio_set_value(GPIO_BUZZER_PIN_NUM,0);
                 break;
                 default:
                 break;
        }
        return 0;
}
struct file_operations buzzer_fops = {
        .owner= THIS_MODULE,
        .open= buzzer_open,
        .release= buzzer_release,
        #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
        .unlocked_ioctl = buzzer_ioctl,
        #else
        .ioctl= buzzer_ioctl,
        #endif
};
static int __init buzzer_init(void)
{
        int ret;
        gpio_free(GPIO_BUZZER_PIN_NUM);
        if(gpio_request(GPIO_BUZZER_PIN_NUM, "buzzer_bee")) {
                 printk("request%s gpio faile \n", "led_bee");
                 return-1;
        }
        ret= alloc_chrdev_region(&devno, minor, 1, "buzzer"); /* 从系统获取主设备号 */
                 major= MAJOR(devno);
                 if(ret < 0) {
                 printk(KERN_ERR"cannot get major %d \n", major);
                 return-1;
        }
        buzzer= cdev_alloc(); /* 分配 buzzer 结构 */
        if(buzzer != NULL) {
                 cdev_init(buzzer,&buzzer_fops); /* 初始化 buzzer 结构 */
                 buzzer->owner= THIS_MODULE;
                 if(cdev_add(buzzer, devno, 1) != 0) { /* 增加 buzzer 到系统中 */
                          printk(KERN_ERR"add cdev error!\n");
                 goto error;
        }
        }else {
                 printk(KERN_ERR"cdev_alloc error!\n");
                 return-1;
        }
        buzzer_class = class_create(THIS_MODULE, "buzzer_class");
        if(IS_ERR(buzzer_class)) {
                 printk(KERN_INFO"create class error\n");
                 return-1;
        }
        device_create(buzzer_class,NULL, devno, NULL, "buzzer");
        return 0;
error:
        unregister_chrdev_region(devno,1); /* 释放已经获得的设备号 */
        return ret;
}
static void __exit buzzer_exit(void)
{
        cdev_del(buzzer);/* 移除字符设备 */
        unregister_chrdev_region(devno,1); /* 释放设备号 */
        device_destroy(buzzer_class,devno);
        class_destroy(buzzer_class);
}
module_init(buzzer_init);
module_exit(buzzer_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zxl_zxl");
代码几乎没有做任何变动,除非有必要,比如适合自己硬件的GPIO定义GPIO_BUZZER_PIN_NUM。还有一些相关头文件定义。
下面是测试程序代码。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include "buzzer_drv.h"
#define DEV_NAME "/dev/buzzer"
int main(int argc, char *argv[])
{
        int i;
        int fd = 0;
        fd = open (DEV_NAME, O_RDONLY);
        if(fd < 0) {
                perror("Open"DEV_NAME" Failed!\n");
                exit(1);
        }
        while(1){
                printf("BUZZER_ON then sleep 1 \n");
                ioctl(fd,BUZZER_ON);
                sleep(1);
                ioctl(fd,BUZZER_OFF);
                printf("BUZZER_ON then BUZZER_OFF 1 \n");
                sleep(1);
        }
        close(fd);
        return 0;
}
编译命令:make ARCH=arm64 CROSS_COMPILE=${DB410C_CROSSTOOL}
insmod buzzer_drv.ko加载驱动
./buzzer_test开始测试,可以听到蜂鸣器根据代码反复响,停。
蜂鸣器接入开发板pin24,gpio为12.


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top