3109|4

68

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

DS18B20传感器问题 [复制链接]

我下了个DS18B20的驱动程序,按到arm板上后进行读数,能复位,但就是在发出温度转换信号后那里卡住了,读不出数。
驱动程序如下:



#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "DS18B20"
#define DS18B20_MAJOR 229
#define DS_PIN S3C2410_GPF0
#define OUT S3C2410_GPF0_OUTP
#define IN S3C2410_GPF0_INP
#define DIS_UP 1
#define EN_UP 0

#define Search 0x00F0
#define Read_ROM 0x0033 //just for one
#define Skip_ROM 0x00CC

#define Convert 0x0044
#define Write 0x004E //TH---TL---Config
#define Read 0x00BE

#define bit_9 0x001F
#define bit_10 0x003F
#define bit_11 0x005F
#define bit_12 0x007F

#define uint16 unsigned int
//unsigned int ROM_DATA[8];
void usdelay(unsigned int i) //延时 i us 对于不同系统可能会有所差别,请适当修改
{
        unsigned int j;
        for(i=i;i>0;i--)
        for(j=90;j>0;j--);
}
void msdelay(unsigned int i) //延时 i us
{
        for(i=i;i>0;i--)
        usdelay(1000);
}
void SetL(void)
{
        s3c2410_gpio_cfgpin(DS_PIN,OUT);
        s3c2410_gpio_setpin(DS_PIN,0);
}
void SetH(void)
{
        s3c2410_gpio_cfgpin(DS_PIN,OUT);
        s3c2410_gpio_setpin(DS_PIN,1);
}
unsigned int Read_DS(void)
{
        unsigned int i;
        s3c2410_gpio_cfgpin(DS_PIN,IN);
        s3c2410_gpio_pullup(DS_PIN,EN_UP);
        __asm("nop");
        __asm("nop");
        __asm("nop");
        i=s3c2410_gpio_getpin(DS_PIN);
        if(i!=0)
                i=1;
        return i;
}

unsigned int ds_start(void)
{
        unsigned int flag=1;
        int err=0;
        SetL();
        usdelay(500); //560
        SetH();
        usdelay(1);
        while(Read_DS()!=0)
        {
        // printk(DEVICE_NAME "Wait....\n");
                usdelay(5);
                err++;
                        if(err==20)
                        {
                           printk(DEVICE_NAME "start fail\n");
                          
                           return -1;
                        }
        }
    printk(DEVICE_NAME "start sucess\n");

        flag=0;
        SetH();
        usdelay(400);
        return flag;
}
void ds_send(unsigned int uidata)
{
        unsigned int i;
        for(i=0;i<8;i++)
        {
                SetL();
                if((uidata&1)!=0)
                {
                   usdelay(3); //3
                   SetH();
                   usdelay(80);
                }
                else
                {
                   usdelay(80);
                   SetH();
                   usdelay(5); //
                }
                uidata>>=1;
        }
}
unsigned int ds_read(void)
{
        unsigned int uidata=0;unsigned int i;
        for(i=0;i<8;i++)
        {
                SetL();
                usdelay(4); //2 3
                SetH();
                usdelay(7); //1 2 3 4 5(e)
                if(Read_DS()==1)
                   uidata+=0x0100;
                uidata>>=1;
                SetH();
                usdelay(65);
        }
        return uidata;
}
void ds_init(unsigned int TH,unsigned int TL,unsigned int bit_nmb)
{
        SetH();
        usdelay(80);
        if(ds_start()==0)
        {

                ds_send(Skip_ROM); //复位
                ds_send(Write); //跳过ROM匹配
                ds_send(TH); //TH
                ds_send(TL); //TL
                ds_send(bit_nmb); //转换位数
        }
}
unsigned int read_tem(void)
{
        unsigned int th=0,tl=0;int err=0;
        ds_init(100,0,bit_12);
        th=tl=0;
        ds_start();
        ds_start();
        ds_start();
        ds_send(Skip_ROM);
        ds_send(Convert);
        msdelay(50);
        while(Read_DS()==0)
        {
        // printk(DEVICE_NAME "Convert....\n");
                msdelay(50);
                err++;
                if(err==10)
                {
                   printk(DEVICE_NAME "convert fail\n");
                   return -1;
                }
        }
        ds_start();
        ds_start();
        ds_send(Skip_ROM);
        ds_send(Read);
        tl=ds_read();
        th=ds_read();
        ds_start();
        ds_start();
        th<<=8;
        tl|=th;
        return tl;
}
/*
void read_ROM(void)
{
unsigned int i;
ds_start();
ds_send(Read_ROM);
for(i=0;i<8;i++)
ROM_DATA=ds_read();
}
*/

static int ds18b20_ioctl(
        struct inode *inode,
        struct file *file,
        unsigned int cmd,unsigned long arg)
{
        return 0;
}

static ssize_t ds18b20_read(struct file *pFile, uint16 __user *pData, size_t count, loff_t *off )
{
    uint16 tmp,ret;
   

    tmp =read_tem();
    ret=copy_to_user(pData, &tmp, sizeof(tmp));    //将读取得的DS18B20数值复制到用户区
        if(ret>0)
        {
                printk("copy data failed\n");
                return -1;
        }

    return 0;
}

static struct file_operations ds18b20_fops = {
        .owner = THIS_MODULE,
        .ioctl = ds18b20_ioctl,
        .read = ds18b20_read,
};
static int __init ds18b20_init(void)
{
        int ret;
        ret = register_chrdev(DS18B20_MAJOR, DEVICE_NAME, &ds18b20_fops);
        if (ret < 0) {
           printk(DEVICE_NAME " can't register major number\n");
           return ret;
        }
        devfs_mk_cdev(MKDEV(DS18B20_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, DEVICE_NAME);

        s3c2410_gpio_cfgpin(DS_PIN, OUT);
        s3c2410_gpio_setpin(DS_PIN, 1);

        printk(DEVICE_NAME " initialized\n");
        return 0;
}
static void __exit ds18b20_exit(void)
{
        devfs_remove(DEVICE_NAME);
        unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);
        printk(DEVICE_NAME " rmmodule\n");
}
module_init(ds18b20_init);
module_exit(ds18b20_exit);

MODULE_DESCRIPTION("DS18B20 Driver");   // 一些描述信息
MODULE_LICENSE("GPL");                              // 遵循的协议



运行到unsigned int read_tem(void)函数那是出现了printk(DEVICE_NAME "convert fail\n")这句的终端语句,然后就返回了-1,没有读出正确温度,读出了-1。

这是什么问题?


while(Read_DS()==0)
        {
        // printk(DEVICE_NAME "Convert....\n");
                msdelay(50);
                err++;
                if(err==10)
                {
                   printk(DEVICE_NAME "convert fail\n");
                   return -1;
                }
        }
这个循环为什么没过去呢?

我换了另一个驱动程序后,因为那个驱动没有这个循环,它读出的全是0,这又说明了什么?

是不是我的接口有问题,还是传感器出了问题?

我这没有调试的工具,所以也不知道具体原因,希望有经验的朋友来讲解一下!谢谢啦!

最新回复

问题解决  详情 回复 发表于 2009-8-14 22:47
点赞 关注

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
上班一直在看代码所以不好意思我没有看你的代码,脑袋发胀了。我想你可以检查一下时序对不对,ds1820温度转换过程(一个ds18b20)是:发命令复位->发命令跳过Match ROM->发命令进行转换->CPU等待转换结束->发命令复位->发命令跳过Match ROM->发命令读取温度,注意有两个复位。你看一下你的代码是不是这样的。
顺便提一下建议:贴代码的时候顺便写一下你的程序构想,看代码很枯燥的。
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
引用 1 楼 cokewei 的回复:
发命令复位->发命令跳过Match ROM->发命令进行转换->CPU等待转换结束->发命令复位->发命令跳过Match ROM->发命令读取温度


是这样的,程序里是这样写的,但就是在“->CPU等待转换结束”这一布上出了问题,程序在这里等不到信号,循环了10次后就跳出了,没有向下进行。下面的函数中跳出,输出了红色的那条语句。

unsigned int read_tem(void)
{
unsigned int th=0,tl=0;int err=0;
ds_init(100,0,bit_12);
th=tl=0;
ds_start();
ds_start();
ds_start();
ds_send(Skip_ROM);
ds_send(Convert);
msdelay(50);
while(Read_DS()==0)
{
// printk(DEVICE_NAME "Convert....\n");
msdelay(50);
err++;
if(err==10)
{
  printk(DEVICE_NAME "convert fail\n");
  return -1;
}
}
ds_start();
ds_start();
ds_send(Skip_ROM);
ds_send(Read);
tl=ds_read();
th=ds_read();
ds_start();
ds_start();
th < <=8;
tl|=th;
return tl;
}

 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

4
 
我用的是2440板子的GPF1这个口,这个口的时序好吗?它好想有上拉电阻,VDD33V。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

5
 
问题解决
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表