搜索
bottom↓
回复: 1

ds18b20 驱动失败

[复制链接]

出0入0汤圆

发表于 2011-2-22 21:17:29 | 显示全部楼层 |阅读模式
程序网上参考的,也看了datasheet没有问题啊。

可是到这里

  while(Read_DS()==0)
  {
  printk(DEVICE_NAME " Convert....\n");
  msdelay(50);
  err++;
  if(err==10)
  {
  printk(DEVICE_NAME " Convert fail\n");
  return -1;
  }

  }
就过不去了。

老是转换失败。


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "DS18B20"
#define DS18B20_MAJOR 250 //这里要确定自己的这个主设备号 mknod /dev/DS18B20 c 250 0
#define DS_PIN S3C2410_GPB1 //这可以找一个自己方便的管脚,只要是引出的GPIO都可以
#define OUT S3C2410_GPB1_OUTP //设置成输出端口
#define IN S3C2410_GPB1_INP //设置成输入端口
#define DIS_UP 1
#define EN_UP 0
#define Search 0x00F0 //好型没怎么用啊!!
#define Read_ROM 0x0033 //just for one
#define Skip_ROM 0x00CC //跳rom的时序
#define Convert 0x0044 //ds18b20的固定时序,管脚识别到该信号开始对测到的温度进行转换
#define Write 0x004E //TH---TL---Config
#define Read 0x00BE //ds18b20的固定时序,管脚识别到该信号时开始从外界获取温度

#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) //初始化ds18b20
{
  unsigned int flag=1;
  int err=0;
  /*
  During the initialization sequence the bus master transmits (TX) the reset pulse by pulling the 1-Wire bus low for a minimum of 480us.
  The bus master then releases the bus and goes into receive mode (RX).  
  When the bus is released, the 5k pullup resistor pulls the 1-Wire bus high.
  When the DS18B20 detects this rising edge, it waits 15us to 60us and then transmits a presence pulse by pulling the 1-Wire bus low for 60us to 240us.
  */

  SetH();
  usdelay(2);
  SetL();
  usdelay(600); //560延时要大于480u
  SetH();
  usdelay(1); //稍作延时

  while(Read_DS()!=0) //ds18B20初始化成功会返回一个低电平,此时跳出循环,执行下面的操作
  {
  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;
  printk("The send data is %d\n",uidata);
  for(i=0;i<8;i++)
  {
  /*
  Both types of write time slots are initiated by the master pulling the 1-Wire bus low.
  To generate a Write 1 time slot, after pulling the 1-Wire bus low,
  the bus master must release the 1-Wire bus within 15us. When the bus is released, the 5k pullup resistor will pull the bus high.  
  To generate a Write 0 time slot, after pulling the 1-Wire bus low,
  the bus master must continue to hold the bus low for the duration of the time slot (at least 60us).
  */
  SetL();
  usdelay(3);
  if((uidata&1)!=0) //写1
  {
  SetH();
  usdelay(80); //保持高电平60us
  }
  else
  {
  usdelay(80); //写低电平直接保持
  SetH();
  }
  uidata>>=1;
  }

}

unsigned int ds_read(void) //接收一个字节数据
{
  unsigned int uidata=0;
  unsigned int i;
  for(i=0;i<8;i++)
  {
  SetL();
  /*
  A read time slot is initiated by the master device pulling the 1-Wire bus low for a minimum of 1us and then releasing the bus
  */
  usdelay(2); //2 3 保持至少1us
// s3c2410_gpio_setpin(DS_PIN,1); //放1
// s3c2410_gpio_cfgpin(DS_PIN,IN); //设置为输入
  SetH();
  /*
  Output data from the DS18B20 is valid for 15us after the falling edge that initiated the read time slot.
  */
  usdelay(7); //1 2 3 4 5(e)
  if(Read_DS()==1)
  uidata+=0x0100;  
  uidata>>=1;  
  /*
  All read time slots must be a minimum of 60us in duration with a minimum of a 1us recovery time between slots.
  */
  usdelay(65); //延时60us,满足读时隙的时间长度要求
  SetH(); //释放总线
  }
  printk("--- The recieve data is %d\n",uidata);
  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,tl;
  int err=0;
  ds_init(100,0,bit_12);
  th=tl=0;
  if(ds_start() != 0)
  {
  return -1;
  }
  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;
  }

  }

  if(ds_start() != 0)
  {
  return -1;
  }
  ds_send(Skip_ROM);
  ds_send(Read);
  tl=ds_read();
  th=ds_read();
   
  th<<=8;
  tl|=th;

  printk("the th data is %d\n",th);
  printk("the tl data is %d\n",tl);
  printk("read_tmp success\n");
  return tl;
}

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;
  }

  s3c2410_gpio_cfgpin(DS_PIN, OUT);
  s3c2410_gpio_setpin(DS_PIN, 1);
  printk(DEVICE_NAME " initialized\n");
  printk("<0>""initialized\n");

  return 0;
}

static void __exit ds18b20_exit(void)
{
  unregister_chrdev(DS18B20_MAJOR, DEVICE_NAME);
  printk(DEVICE_NAME " rmmodule\n");
}

module_init(ds18b20_init);
module_exit(ds18b20_exit);
MODULE_AUTHOR("benjamin_xc@163.com"); // 驱动程序的作者
MODULE_DESCRIPTION("DS18B20 Driver"); // 一些描述信息
MODULE_LICENSE("GPL");

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2011-2-24 22:17:03 | 显示全部楼层
程序问题
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 20:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表