使用AVR来驱动MAXIN的DS18B20

发布者:NanoScribe最新更新时间:2019-11-28 来源: 51hei关键字:AVR  驱动  DS18B20 手机看文章 扫描二维码
随时随地手机看文章

我最近正在研究使用AVR来驱动MAXIN的DS18B20,琢磨了几天,终于把它的驱动程序写好了.

使用IAR C++编译器


#ifndef DS18B20_H
#define DS18B20_H
/****************************************只需在源程序里定义以下宏
#define seDDS()  (seDB0())
#define clDDS()  (clDB0())
#define seDS()   (sePB0())
#define clDS()   (clPB0())
#define GetDS()  (GetPB0())
*********************************************/
/***********************************   函数说明  *********************
void DS18B20::DS18B20(void) 构造函数
void DS18B20::init()初始化DS18B20
char DS18B20::GetID()读取器件ID,成功返回1,并且器件的64位id号保存到DS18B20.id[4],里,失败返回0
char DS18B20::convter()读取温度,成功返回1,并且温度值保存到DS18B20.temp里,未就绪返回0。此程序需要调用数次才能正确转换
                       调用周期不得低于2ms
char DS18B20::GetPower()读取总线供电模式,正常返回1,寄生返回0
char DS18B20::SearchAlarm()读取报警,有报警返回1,没有返回0

****************************************************/
#define DS_ReadROM     0x33
#define DS_CopyROM     0x48
#define DS_MatchROM    0x55
#define DS_SkipROM     0xCC
#define DS_SearchROM   0xF0
#define DS_AlarmSearch 0xEC
#define DS_Convert     0x44
#define DS_ReadRAM     0xBE
#define DS_WriteRAM    0x4E
#define DS_ReadPower   0xB4
#define DS_9BIT           0
#define DS_10BIT          1
#define DS_11BIT          2
#define DS_12BIT          3
#include "c:incstatus.h"
#include "c:inccrc8.c"
#include "c:incdelay.c"
#include "c:incformat.h"
#include

class DS18B20
{
public:

  float temp;//           温度  
  int rel;//              温度偏移量
  char id[8];//           器件ID号
  char mode;//            转换模式9-12bit
  unsigned char TH;//     预警温度上限
  unsigned char TL;//     预警温度下限
  char power;//           0:寄生供电  1:电源供电
  char status;//          单线总线状态0: 无连接  1:已连接
  char sbuf[10];

private:

  char setup;
/****************************************复位总线***********************/
  char Reset_DS()
  {
    unsigned int x;
    seDS();
    seDDS();
    DELAY_80us();
    if(GetDS())
    {
      clDS();
      DELAY_600us();
      seDS();
      clDDS();
      for(x=0;x<30;)
      {
        if(GetDS())x++;
        else
        {
          for(x=0;x<30;)
          {
     if(GetDS())
            {
        seDDS();
        DELAY_600us();//
        return 1;
     }
     else
       x++;
            DELAY_10us();
   }
   clDDS();
   return 0;
        }
        DELAY_10us();//
      }
    }
    clDDS();
    return 0;
  }
/**************************************************写总线*******************/
  void Write_DS(unsigned dat,unsigned char wide)// dat:数据  wide:数据宽度(位数)
  {
    unsigned char i,sreg;
    seDDS();
    for(i=0;i    {
      sreg=SREG;
      SREG&=0x7F;//                      关中断
      if(dat&0x01)
      {
        clDS();
        DELAY_10us();
seDS();
        DELAY_80us();
      }
      else
      {
        clDS();
        DELAY_80us();
seDS();
        DELAY_10us();
      }
      SREG=sreg;//                       恢复中断 发生的中断将依次执行
      dat>>=1;
    }
  }
/***************************************************读总线*******************/
  unsigned char Read_DS(unsigned char wide)
  {
    unsigned char dat,i,sreg;
    for(i=dat=0;i    {
      if(GetDS())
      {
        sreg=SREG;
        SREG&=0x7F;
        clDS();
        seDDS();
        DELAY_10us();
        seDS();
        clDDS();
        dat>>=1;
        DELAY_10us();
        if(GetDS())dat|=0x80;
        seDDS();
        SREG=sreg;
        DELAY_80us();
      }
      else
      {
        setup=0;
      }
    }
    return dat;
  }

  char getid()
  {
    char i;
    for(i=0;i      if(id)
        return 1;
    return 0;
  }
public:
  char convert()//                           本程序调用周期至少2ms或以上
  {
    static unsigned char sbuf[9];
    static unsigned int i;
    switch(setup)
    {
    case 0:
      if(Reset_DS())//                   开始
      {
        status=1;
        setup++;
      }
      else
status=0;
      break;
    case 1:
      if(getid())
      {
        Write_DS(DS_MatchROM,8);//       匹配ROM
        for(i=0;i<8;i++)
          Write_DS(id,8);
      }
      else
      {
        Write_DS(DS_SkipROM,8);//       跳过匹配
      }
      Write_DS(DS_Convert,8);//         启动转换
      i=power?0:500;//         选择电源方式,以达到最快速度
      setup++;
      break;
    case 2:
      if(i)//                           延时
      {
        i--;
      }
      else if(Read_DS(8)==0xFF)//       等待转换结束
      {
        Reset_DS();
        if(getid())
        {
          Write_DS(DS_MatchROM,8);//    匹配ROM
          for(i=0;i<8;i++)
            Write_DS(id,8);
        }
        else
          Write_DS(DS_SkipROM,8);
        Write_DS(DS_ReadRAM,8);
        i=0;
        setup++;
      }
      break;
    case 3:
      sbuf=Read_DS(8);
      if(i>=9)
      {
        Reset_DS();
        if(GetCRC8(sbuf,8)==sbuf[8])//                    校验CRC
        {
          int i;
          i=sbuf[1]*0x100+sbuf[0];
          i+=rel;
          temp=i/16+(i%16)*0.125;
          setup=0;
          status=1;
          return 1;
        }
        setup=0;
      }
      break;
    }
    return 0;
  }
  char GetPower()
  {
    unsigned char x;
    if(Reset_DS())
    {
      Write_DS(DS_SkipROM,8);
      Write_DS(DS_ReadPower,8);
      x=Read_DS(8);
      Reset_DS();
      if(x)
        return 1;
    }
    return 0;
  }
/*************************************预警搜索****************************/
  char SearchAlarm()
  {
    if(Reset_DS())
    {
      Write_DS(DS_AlarmSearch,8);
      if(Read_DS(2)==0x80)//      读两个位
      {
        Reset_DS();
return 1;
      }
    }
    Reset_DS();
    return 0;
  }
//TH:高温限制  TL:低温限制    
//mode:转换模式  0:9bit(93.75ms)  1:10bit(187.5ms)  2:11bit(375ms)  3:12bit(750ms)  
//power:总线的电源模式
//ID:器件ID号
  char init()
  {
    unsigned char i,sbuf[9];
    if(Reset_DS())
    {
      if(getid())
      {
Write_DS(DS_MatchROM,8);
for(i=0;i<8;i++)
   Write_DS(id,8);
      }
      else
        Write_DS(DS_SkipROM,8);
      Write_DS(DS_WriteRAM,8);
      Write_DS(TH,8);
      Write_DS(TL,8);
      Write_DS(((mode&0x03)<<5)|0x1F,8);
      Reset_DS();
      if(getid())
      {
Write_DS(DS_MatchROM,8);
        for(i=0;i<8;i++)
   Write_DS(id,8);
      }
      else
        Write_DS(DS_SkipROM,8);
      Write_DS(DS_ReadRAM,8);
      for(i=0;i<9;i++)
        sbuf=Read_DS(8);
      if(GetCRC8(sbuf,8)==sbuf[8])//  校验CRC
      {
        if(sbuf[2]==TH&&sbuf[3]==TL)
        {
          Reset_DS();
          if(getid())
          {
            Write_DS(DS_MatchROM,8);
            for(i=0;i<8;i++)
                Write_DS(id,8);
          }
          else
            Write_DS(DS_SkipROM,8);
          Write_DS(DS_CopyROM,8);
          DELAY_200ms();
          Reset_DS();
          power=GetPower();
          Reset_DS();
          return 1;//                 完成
        }
      }
    }
    return 0;
  }
/*********************************************读取DS18B20的64位ROM******************/
  char GetID()
  {
    unsigned char i;
    unsigned char sbuf[8];
   if(Reset_DS())
   {
     Write_DS(DS_ReadROM,8);
     for(i=0;i<8;i++)
     {
       sbuf=Read_DS(8);
     }
     Reset_DS();
     if(GetCRC8(sbuf,7)==sbuf[7])//   校验CRC
     {
       for(i=0;i<8;i++)
         id=sbuf;//    拷贝数据到ROM
       return 1;
     }
   }
   return 0;
  }

  char* disp(char width=0)
  {
    int i=(int)temp;
    int j=(int)(temp*10);
    j%=10;
    if(temp<0)
      j=0-j;
    switch(width)
    {
    case 2:
      sprintf(sbuf,"%2d.%d",i,j);
      break;
    case 3:
      sprintf(sbuf,"%3d.%d",i,j);
      break;
    default:
      sprintf(sbuf,"%d.%d",i,j);
      break;
    }
    return sbuf;
  }

  DS18B20()
  {
    format(id,sizeof(id),0);
    mode=DS_12BIT;
    TH=100;
    TL=0;
    power=0;
    rel=0;
    status=0;
    setup=0;
    seDDS();
    seDS();
  }
};
#endif

[1] [1]
关键字:AVR  驱动  DS18B20 引用地址:使用AVR来驱动MAXIN的DS18B20

上一篇:avr单片机ds1302时钟程序详解
下一篇:AVR定时器1的相位修正PWM模式设置

推荐阅读最新更新时间:2024-11-09 10:49

18B20 驱动 MSP430
float get_temp(void); void reset_18B20(void); void send_18B20(char data); unsigned int read_18B20(void); #define ONE_WIRE_PIN BIT4 #define ONE_WIRE_IN P1IN #define ONE_WIRE_OUT P1OUT #define ONE_WIRE_DIR P1DIR float get_temp(void) { unsigned int temp; reset_18B20(); send_18B20(0xcc); //send CCH,Skip ROM com
[单片机]
linux i2c 设备测试,i2c-dev驱动测试代码
embed-linux version:linux-2.6.39-exp vmware-linux:ubuntu14.04 hardware: core chip at91sam9x25 cross-compile:arm-none-linux-gnueabi-gcc 4.5.2 code: #include stdio.h #include stdlib.h #include unistd.h #include sys/ioctl.h #include sys/types.h #include sys/stat.h #include fcntl.h //#include sys/select.h #include sys/tim
[单片机]
日本电产新宝推出用于无人搬运台车及自主移动机器人的驱动模块新产品 
日本电产新宝推出用于无人搬运台车及自主移动机器人的驱动模块新产品              日本电产新宝为新推出的、用于无人搬运台车(以下简称“AGV”)及自主移动机器人(以下简称“AMR”)的驱动模块产品进行了扩充,新增了直流24V规格的产品阵容。 随着物流业、制造业等仓储设施在自动化、省人化方面的市场需求不断增多,AGV及AMR行业发展趋势整体向好,2021年的市场规模为30亿美元, 据预测,其在2027年的市场规模将有望突破180亿美元。 新推出的驱动模块,除了原有的直流48V规格,还新增了24V规格的产品阵容,能在与外围设备使用较多的直流24V相同的电压环境下进行驱动 。驱动部采用了日本电产新宝擅长的应用
[机器人]
日本电产新宝推出用于无人搬运台车及自主移动机器人的<font color='red'>驱动</font>模块新产品 
基于STM32CUBEMX驱动TMOS模块STHS34PF80(4)----中断获取信号
概述 HS34PF80的数据准备信号提供了一种机制,允许设备在新的测量数据可读取时通知系统,并触发同步操作,通过正确配置相关寄存器,可以确保系统及时捕获和处理来自设备的新数据,从而提高整体性能和响应能力。 检测人体的存在和动作,并通过特定的通信接口发送检测结果。 最近在弄ST和瑞萨RA的课程,需要样片的可以加群申请:615061293 。 样品申请 https://www.wjx.top/vm/OhcKxJk.aspx# 视频教程 https://www.bilibili.com/video/BV1NF41117S6/ 参考Demo https://github.com/STMicroelectronics/STMems_S
[单片机]
基于STM32CUBEMX<font color='red'>驱动</font>TMOS模块STHS34PF80(4)----中断获取信号
Linux驱动之USB总线驱动程序框架简析
通用串行总线(USB)是主机和外围设备之间的一种连接。USB总线规范有1.1版和2.0版,当然现在已经有了3.0版本。USB1.1支持两种传输速度:低速为1.5Mbps,高速为12Mbps。USB2.0的传输速度可以高达480Mbps。USB2.0向下兼容USB1.1,可以将USB1.1的设备连接到USB2.0控制器上,也可以把USB2.0的设备连接到USB1.1控制器上。S3C2440的USB主机控制器支持USB1.1总线规范。 USB总线的拓扑结构如下图所示:USB主机控制器(USB Host Controller)通过根集线器(Root Hub)与其他USB设备相连。集线器也属于USB设备,通过它可以在一个USB接口上扩展出
[单片机]
Linux<font color='red'>驱动</font>之USB总线<font color='red'>驱动</font>程序框架简析
AVR32 MCU上的ABDAC外设音频播放设计
  AVR32 MCU 上的 ABDAC 外设非常适合生成音频播放。本文介绍了如何执行此操作,并包含指向生成正弦波输出的示例驱动程序的链接。   许多嵌入式应用程序越来越多地具有音频播放功能,无论是响应用户输入的简单音频反馈还是全高速流音频。通过使用通用时钟接口,Atmel AVR32 MCU 上的 ABDAC 能够支持广泛的播放频率。   功能说明   ABDAC 是一个非常简单的外围设备,它的使用很简单。它需要通用时钟系统提供的时钟信号,以及通道的数据输入。图 1 中的框图给出了该模块的概述。有关 ABDAC 外设的详细说明,请参见器件的数据表。      图 1:时钟和数据路径框图。   通用时钟   ABDAC
[单片机]
<font color='red'>AVR</font>32 MCU上的ABDAC外设音频播放设计
linux-2.6.32在mini2440开发板上移植 按键驱动程序移植
编者:按键驱动程序涉及到linux中断程序的编写。 1、按键原理图。 2、驱动程序的编写移植。 在/linux-2.6.32.2/drivers/char/目录下创建一个新的驱动程序文件mini2440_buttons.c,内容及详细注释如下: span style= font-size: 18px; #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include linux/poll.h #include linux/irq.h #include
[单片机]
linux-2.6.32在mini2440开发板上移植 按键<font color='red'>驱动</font>程序移植
数据驱动时代,自动驾驶开发如何造「飞轮」?
随着 L2+ 自动驾驶 逐步渗透,行业向高阶自动驾驶发起新一轮进攻。 整个算法架构也随之不断演进: 从独立模型过渡到多任务学习;从 传感器 数据后融合到前融合;从规则主导转变为 深度学习 ;… 另外,端到端成为各车企、Tier1 绕不开的技术关键词。 比如理想发布「端到端+VLM」的全新模型架构,打出快慢系统的组合拳,能让 AI 做出拟人化的驾驶行为。 而这些模型性能的进阶,是基于底层开发工具链足够强大。 具体要求是,能够向更高效的网络设计与算法优化不断靠拢。 这是 NVIDIA 的优势。 在近期《汽车之心·行家说》NVIDIA 专场中,作为全球领先的 AI 计算助推者,以自动驾驶开发平台和 数字孪
[汽车电子]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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