hx711 linux驱动读不了数据

2019-07-16 07:49发布

本帖最后由 Stark扬 于 2018-10-31 15:11 编辑

hx711编写的linux字符设备驱动,读不了数据,使用的是手册上的例程修改的。不连数据线的时候,时钟脉冲输出正常25个脉冲。一旦连接上数据线,cpu输出的时钟脉冲数量就不对了。


补充内容 (2018-10-31 15:30):
/*头文件部分*/
#include "ym_weight.h"


/*设备号*/
static dev_t dev_no;

/*设备文件指针*/
static struct ym_weight_dev * weight_dev = NULL;


/*设备类结对象,用于自动生成设备节点*/
static struct class *led_class = NULL;

static int weight_open(struct inode * node, struct file * file) {
        printk("This is open! ");
        return 0;
}


/**
函数名:ReadCount
功能描述:读取硬件数据
返回值:读取成功返回读取数据
**/

unsigned int ReadCount(void)
{
    unsigned int Count = 0;
    unsigned char i;
        preempt_disable();
        //gpio_set_value(SPICL, 0);
        while(gpio_get_value(SPIIN));
        udelay(2);
        //local_irq_disable();
       
        for (i=0;i<24;i++)
        {
        gpio_set_value(SPICL, 1);
        Count=Count<<1;
                udelay(2);
       gpio_set_value(SPICL, 0);
        if(gpio_get_value(SPIIN)) Count++;
                udelay(2);
                //printk(KERN_ALERT"weight is %u ",Count);
    }
     gpio_set_value(SPICL, 1);
         udelay(2);
         //printk(KERN_ALERT"weight is %u ",Count);
     Count=Count^0x800000;
     gpio_set_value(SPICL, 0);
         DELAY;
         
   //local_irq_enable();
    preempt_enable();
    return(Count);
}



/**
函数名:weight_read
功能描述:读取数据实现
返回值:读取成功返回读取数据
**/

static ssize_t weight_read(struct file *file,char __user *buf,size_t count,loff_t *pos)
{
    unsigned int weight = 0;       
        weight = ReadCount();
       
        if (copy_to_user(buf,(void *)(&weight), sizeof(int)))
                return -EFAULT; //拷贝失败
               
        return 0;
}

/*设备文件操作集--函数指针集*/
struct file_operations weight_fops = {
                .owner = THIS_MODULE, //该文件操作集应用于当前驱动模块
                .open = weight_open,
                .read = weight_read,
                .llseek = weight_llseek,

};


static int dev_register(void) {
        /*1. 将文件操作集和设备文件绑定*/
        cdev_init(&(weight_dev->dev), &weight_fops);

        /*2. 单独初始化owner成员*/
        weight_dev->dev.owner = THIS_MODULE;

        /*3. 根据设备号和设备名注册设备到内核*/
        if (cdev_add(&(weight_dev->dev), dev_no, DEV_NUM) < 0) {

                printk(KERN_ALERT "dev_register failed! ");
                return -1;; //注册失败返回-1
        }

        /*4. 设备注册成功返回0*/
        return 0;
}

static int weight_hardware_init(void) {
        int ret = -1;
        ret = gpio_request(SPICL,"SPICL");
        if (ret !=0)
        printk(KERN_ALERT"SPICL request fail! ");
        ret = gpio_request(SPIIN,"SPIIN");
        if (ret !=0)
        printk(KERN_ALERT"SPIIN request fail! ");
       
        ret = gpio_direction_output(SPICL,0);
        if (ret !=0)
        printk(KERN_ALERT"SPICL set fail! ");
        ret = gpio_direction_input(SPIIN);
        if (ret !=0)
        printk(KERN_ALERT"SPIIN set fail! ");
        return ret;
}


static int ym_weight_device_create(void) {
        int ret = -1;
        /*用于和class结构体指针联合自动创建设备文件*/
        struct device *tmp = NULL;

        /*1. 创建设备类对象*/
        led_class = class_create(THIS_MODULE, CLASS_NAME);
        if (IS_ERR(led_class)) { //检测是否创建成功
                ret = PTR_ERR(led_class);
                printk(KERN_ALERT"Failed to create led class. ");

        }
        tmp = device_create(led_class, NULL, dev_no, NULL, "%s", FILE_NAME);
        if (IS_ERR(tmp)) {
                ret = PTR_ERR(tmp);
                printk(KERN_ALERT"Failed to create led device. ");
                goto destroy_class;
        }

        dev_set_drvdata(tmp, (void *) weight_dev);

        return 0;
        destroy_class: class_destroy(led_class);
        cdev_del(&(weight_dev->dev));
        return ret;
}

/**
函数名:ym_weight_init
功能描述:驱动加载函数,申请资源
返回值:加载成功返回0
**/
static int __init ym_weight_init(void)
    {
        /*用于检测加载过程中各函数的执行结果*/
        int ret = -1;

        /*1. 动态申请设备号*/
        ret = alloc_chrdev_region(&dev_no, 0, DEV_NUM, DEV_NAME);
        if (ret < 0) {
                printk(KERN_ALERT"Alloc_chrdev_region failed! ");
                goto fail;
        }

        /*2. 为设备文件分配一块内存空间并将该空间清零*/
        weight_dev = kzalloc(sizeof(struct ym_weight_dev), GFP_KERNEL);
        if (weight_dev == NULL) {
                ret = -ENOMEM;
                printk(KERN_ALERT"kmalloc failed! ");
                goto unregister;
        }

        /*3. 注册设备*/
        ret = dev_register();
        if (ret < 0) {
                printk(KERN_ALERT"cdev_add failed! ");
                goto clean_up;
        }

        /*4. 硬件相关的初始化*/
        ret = weight_hardware_init();
        if (ret < 0) {
                printk(KERN_ALERT"led_hardware_init failed! ");
                goto clean_up;
        }

        /*5. 自动创建设备文件节点*/
        ret = ym_weight_device_create();
        if (ret < 0) {
                printk(KERN_ALERT"device_create failed! ");
                goto clean_up;
        }

        /*6. 驱动成功加载返回0*/
        printk(KERN_ALERT"Succeed to initialize led device. ");
        return 0;

        /*设备注册失败,释放之前申请的资源--从释放为设备文件申请的内存空间开始(此时设备文件已成功申请到内存空间)*/
        clean_up: kfree(weight_dev);

        /*为设备文件申请内存失败,释放之前申请的资源--从释放设备号开始(此时设备号已经成功申请)*/
        unregister: unregister_chrdev_region(dev_no, DEV_NUM);

        /*设备号动态申请失败,终止驱动初始化*/
        fail:

        return ret;
}

static void __exit
ym_weight_exit(void) {
        /*1. 释放自动创建设备文件节点申请的资源*/
        if (led_class) {
                device_destroy(led_class, dev_no); //释放设备文件
                class_destroy(led_class); //释放设备类对象
        }
        /*2. 释放GPIO寄存器映射的地址*/
        //iounmap(led_dat);
        //iounmap(led_con);
        gpio_free(SPICL);
        gpio_free(SPIIN);

        /*3. 释放注册设备文件申请的资源*/
        if (weight_dev) {
                cdev_del(&(weight_dev->dev)); //注销内核中的设备文件
                kfree(weight_dev); //释放为设备文件分配的内存空间
        }
        /*4. 注销设备号*/
        unregister_chrdev_region(dev_no, DEV_NUM);
}
module_init(ym_weight_init);
module_exit(ym_weight_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Tom Wang");
MODULE_DESCRIPTION("driver of weight");
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
lee_st
1楼-- · 2019-07-16 12:26
 精彩回答 2  元偷偷看……
lalajie
2楼-- · 2019-07-16 17:11
例程程序看下,还有会不会是线的问题呢
lee_st
3楼-- · 2019-07-16 17:39
解决了
lee_st
4楼-- · 2019-07-16 21:10
挺好的

一周热门 更多>