热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

DS18B2064位序列码读取程序

/*******************************************************************

/*******************************************************************/

/*                                                                 */

/*51hei单片机开发系统演示程序 - DS18B20-64位序列码读取程序     */

/*                                                                  *

* LCD1602显示                                                     *

*                                                                 *

* 工作芯片:STC89C516      晶振频率:11.0592MHz                   *

*                                                                 *

/*******************************************************************/

/*读取DS18B20的64位序列码并显示在1602液晶上,如果读取正确结果,则在

液晶第一行显示DS18B20 OK,第二行显示序列码,如果读取失败,则在液晶上

显示DS18B20  ERR0R PLEASE CHECK ,用户可通过更改18B20接口自己外接。 */

#include

#include

#define uchar unsigned char

#define uint  unsigned int

sbit DQ = P2^2;  //定义DS18B20端口DQ 

sbit BEEP=P2^3 ; //蜂鸣器驱动线

bit  presence ;

sbit LCD_RS = P3^5;            

sbit LCD_RW = P3^6;

sbit LCD_EN = P3^4;

uchar code  cdis1[ ] = {"   DS18B20 OK   "};

uchar code  cdis2[ ] = {"                "};

uchar code  cdis3[ ] = {" DS18B20  ERR0R "};

uchar code  cdis4[ ] = {"  PLEASE CHECK  "};

unsigned char data  display[2] = {0x00,0x00};

                                   

unsigned char data  RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

unsigned char Temp;

unsigned char  crc;

void beep();

#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};

/*******************************************************************/

void delay1(int ms)

{

 unsigned char y;

  while(ms--)

 {

  for(y = 0; y<250; y++)

  {

   _nop_();

   _nop_();

   _nop_();

   _nop_();

  }

 }

}

/******************************************************************/

/*                                                                */

/*检查LCD忙状态                                                   */

/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。     */

/*                                                                */

/******************************************************************/

bit lcd_busy()

 {                         

    bit result;

    LCD_RS = 0;

LCD_RW =0;

    LCD_EN = 1;

    delayNOP();

    result = (bit)(P0&0x80);

    LCD_EN = 0;

    return(result);

 }

/*******************************************************************/

/*                                                                 */

/*写指令数据到LCD                                                  */

/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */

/*                                                                 */

/*******************************************************************/

void lcd_wcmd(uchar cmd)

{                         

 //  while(lcd_busy());

    LCD_RS = 0;

  LCD_RW = 0;

    LCD_EN = 0;

    _nop_();

    _nop_();

    P0 = cmd;

    delayNOP();

    LCD_EN = 1;

    delayNOP();

    LCD_EN = 0; 

delay1(5);

}

/*******************************************************************/

/*                                                                 */

/*写显示数据到LCD                                                  */

/*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */

/*                                                                 */

/*******************************************************************/

void lcd_wdat(uchar dat)

{                         

//   while(lcd_busy());

    LCD_RS = 1;

LCD_RW = 0;

    LCD_EN = 0;

    P0 = dat;

    delayNOP();

    LCD_EN = 1;

    delayNOP();

    LCD_EN = 0;

delay1(5);

}

/*******************************************************************/

/*                                                                 */

/*  LCD初始化设定                                                  */

/*                                                                 */

/*******************************************************************/

void lcd_init()

{

    delay1(15);  

    lcd_wcmd(0x01);      //清除LCD的显示内容

           

    lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据

    delay1(5);

    lcd_wcmd(0x38);        

    delay1(5);

    lcd_wcmd(0x38);        

    delay1(5);

    lcd_wcmd(0x0c);      //显示开,关光标

    delay1(5);

    lcd_wcmd(0x06);      //移动光标

    delay1(5);

    lcd_wcmd(0x01);      //清除LCD的显示内容

    delay1(5);

}

/*******************************************************************/

/*                                                                 */

/*  设定显示位置                                                   */

/*                                                                 */

/*******************************************************************/

void lcd_pos(uchar pos)

{                         

  lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量

}

/*******************************************************************/

/*                                                                 */

/*us级延时函数                                                     */

/*                                                                 */

/*******************************************************************/

void Delay(unsigned int num)

{

  while( --num );

}

/*******************************************************************/

/*                                                                 */

/*初始化ds1820                                                     */

/*                                                                 */

/*******************************************************************/

Init_DS18B20(void)



     DQ = 1;      //DQ复位

     Delay(8);    //稍做延时

     DQ = 0;      //将DQ拉低

     Delay(90);   //精确延时 大于 480us

     DQ = 1;       //拉高总线

     Delay(8);

     presence = DQ;    //读取存在信号

     Delay(100);

     DQ = 1;

    

     return(presence); //返回信号,0=presence,1= no presence

}

/*******************************************************************/

/*                                                                 */

/* 读一位(bit)                                                   */

/*                                                                 */

/*******************************************************************/

uchar read_bit(void)

{

unsigned char i;

DQ = 0;     //将DQ 拉低开始读时间隙

DQ = 1; // then return high

for (i=0; i<3; i++); // 延时15μs

return(DQ); // 返回 DQ 线上的电平值

}

/*******************************************************************/

/*                                                                 */

/* 读一个字节                                                      */

/*                                                                 */

/*******************************************************************/

 ReadOneChar(void)

{

unsigned char i = 0;

unsigned char dat = 0;

//for (i = 8; i > 0; i--)

//  {

//   read_bit();

//    DQ = 0; // 给脉冲信号

//     dat >>= 1;

//    DQ = 1; // 给脉冲信号

for (i=0;i<8;i++)

{   // 读取字节,每次读取一个字节

if(read_bit()) dat|=0x01<

//    if(DQ)

//     dat |= 0x80;

    Delay(4);

  }

    return (dat);

}

/*******************************************************************/

/*                                                                 */

/* 写一位                                                          */

/*                                                                 */

/*******************************************************************/

void write_bit(char bitval) {

DQ = 0;       // 将DQ 拉低开始写时间隙

if(bitval==1) DQ =1; // 如果写1,DQ 返回高电平

Delay(5);      // 在时间隙内保持电平值,

DQ = 1;             // Delay函数每次循环延时16μs,因此delay(5) = 104μs

/*******************************************************************/

/*                                                                 */

/* 写一个字节                                                      */

/*                                                                 */

/*******************************************************************/

 WriteOneChar(unsigned char dat)

{

  unsigned char i = 0;

  unsigned char temp;

//  for (i = 8; i > 0; i--)

//  {

   for (i=0; i<8; i++) // 写入字节, 每次写入一位

   {

//    DQ = 0;

//    DQ = dat&0x01;

//    Delay(5);

//    DQ = 1;

   temp = dat>>i;

   temp &= 0x01;

   write_bit(temp);

//    dat>>=1;

  

  }

  Delay(5);

}

/*******************************************************************/

/*                                                                 */

/* 读取64位序列码                                                  */

/*                                                                 */

/*******************************************************************/

 Read_RomCord(void)

{

     unsigned char j;

     Init_DS18B20();

 

     WriteOneChar(0x33);  // 读序列码的操作

     for (j = 0; j <8; j++)

{

 RomCode[j] = ReadOneChar() ;

}

}

/*******************************************************************/

/*                                                                 */

/*DS18B20的CRC8校验程序                                            */

/*                                                                 */

/*******************************************************************/

uchar CRC8()

{

   uchar i,x; uchar crcbuff;

  

   crc=0;

   for(x = 0; x <8; x++)

   {

    crcbuff=RomCode[x];

    for(i = 0; i <8; i++)

     {

      if(((crc ^ crcbuff)&0x01)==0)

      crc >>= 1;

       else {

              crc ^= 0x18;   //CRC=X8+X5+X4+1

              crc >>= 1;

              crc |= 0x80;

            }        

      crcbuff >>= 1;      

}

   }

     return crc; 

}

/*******************************************************************/

/*                                                                 */

/* 数据转换与显示                                                  */

/*                                                                 */

/*******************************************************************/

 Disp_RomCode()

{

   uchar j;

   uchar H_num=0x40;       //LCD第二行初始位置

   for(j=0;j<8;j++)

   {

    Temp = RomCode[j];

    display[0]=((Temp&0xf0)>>4);

    if(display[0]>9)

     { display[0]=display[0]+0x37;}

    else{display[0]=display[0]+0x30;}

    lcd_pos(H_num);            

    lcd_wdat(display[0]);        //高位数显示

    H_num++;

    display[1]=(Temp&0x0f);

    if(display[1]>9)

     {display[1]=display[1]+0x37;}

    else {display[1]=display[1]+0x30;}

    lcd_pos(H_num);            

    lcd_wdat(display[1]);        //低位数显示

    H_num++;

   }

/*******************************************************************/

/*                                                                 */

/* 蜂鸣器响一声                                                    */

/*                                                                 */

/*******************************************************************/

void beep()

  {

    unsigned char y;

    for (y=0;y<100;y++)

    {

      Delay(60);

      BEEP=!BEEP;                //BEEP取反

    }

    BEEP=1;                      //关闭蜂鸣器

Delay(40000);

  }

/*******************************************************************/

/*                                                                 */

/* DS18B20 OK 显示菜单                                             */

/*                                                                 */

/*******************************************************************/

void  Ok_Menu ()

{

    uchar  m;

    lcd_init();                //初始化LCD

           

    lcd_pos(0);                //设置显示位置为第一行的第1个字符

     m = 0;

    while(cdis1[m] != '\0')

     {                         //显示字符

       lcd_wdat(cdis1[m]);

       m++;

     }

    lcd_pos(0x40);             //设置显示位置为第二行第1个字符

     m = 0;

    while(cdis2[m] != '\0')

     {

       lcd_wdat(cdis2[m]);      //显示字符

       m++;

     }

}

/*******************************************************************/

/*                                                                 */

/* DS18B20 ERROR 显示菜单                                          */

/*                                                                 */

/*******************************************************************/

void  Error_Menu ()

{

     uchar  m;

     lcd_init();                //初始化LCD

  lcd_pos(0);                //设置显示位置为第一行的第1个字符

     m = 0;

     while(cdis3[m] != '\0')

     {                         //显示字符

       lcd_wdat(cdis3[m]);

       m++;

     }

     lcd_pos(0x40);             //设置显示位置为第二行第1个字符

     m = 0;

     while(cdis4[m] != '\0')

     {

       lcd_wdat(cdis4[m]);      //显示字符

       m++;

     }

}

/*******************************************************************/

/*                                                                 */

/* 主函数                                                          */

/*                                                                 */

/*******************************************************************/

void main()

 {

     P0 = 0xff;

     P2 = 0xff;

   while(1)

  {

     Ok_Menu ();

     Read_RomCord();    //读取64位序列码

     CRC8();            //CRC效验

     if(crc==0)         //CRC效验正确

{

 Disp_RomCode(); //显示64位序列码

   beep();

     }

     while(!presence)

{

 Init_DS18B20();

 delay1(1000);

}

     Error_Menu ();

do



  Init_DS18B20();

  beep();

     }

while(presence);

  }

}

/*******************************************************************/




推荐阅读
  • 本文详细介绍了Oracle RMAN中的增量备份机制,重点解析了差异增量和累积增量备份的概念及其在不同Oracle版本中的实现。通过对比两种备份方式的特点,帮助读者选择合适的备份策略。 ... [详细]
  • 本文详细探讨了如何处理包含多种分隔符的字符串分割问题,并提供了一个高效的C++实现方案。 ... [详细]
  • 本文详细解析 Skynet 的启动流程,包括配置文件的读取、环境变量的设置、主要线程的启动(如 timer、socket、monitor 和 worker 线程),以及消息队列的实现机制。 ... [详细]
  • 基于51单片机的多项目设计实现与优化
    本文探讨了基于51单片机的多个项目的设计与实现,包括PID控制算法的开关电源设计、八音电子琴仿真设计、智能抽奖系统控制设计及停车场车位管理系统设计。每个项目均采用先进的控制技术和算法,旨在提升系统的效率、稳定性和用户体验。 ... [详细]
  • ED Tree HDU4812 点分治+逆元
    这道题非常巧妙!!!我们进行点分治的时候,算出当前子节点的所有子树中的节点,到当前节点节点的儿子节点的距离,如下图意思就是当前节点的红色节点,我们要求出红色节点的儿子节点绿色节点, ... [详细]
  • 本文档旨在提供C语言的基础知识概述,涵盖常量、变量、数据类型、控制结构及函数定义等内容。特别强调了常量的不同类型及其在程序中的应用,以及如何正确声明和使用函数。 ... [详细]
  • 来自FallDream的博客,未经允许,请勿转载,谢谢。一天一套noi简直了.昨天勉强做完了noi2011今天教练又丢出来一套noi ... [详细]
  • 题面:P3178[HAOI2015]树上操作好像其他人都嫌这道题太容易了懒得讲,好吧那我讲。题解:第一个操作和第二个操作本质上是一样的&# ... [详细]
  • HDU 2537 键盘输入处理
    题目描述了一个名叫Pirates的男孩想要开发一款键盘输入软件,遇到了大小写字母判断的问题。本文提供了该问题的解决方案及实现方法。 ... [详细]
  • Day4今天继续复习搞基础课,加油!树形DP每一个节点都分为选和不选两种状态,选为f[i,1],不选为f[i,0]&# ... [详细]
  • 2022年4月15日的算法练习题,包括最长公共子序列和线段树的应用。 ... [详细]
  • 本题要求计算从起点到终点所有最短路径的总权重,使用SPFA算法进行求解。 ... [详细]
  • 离散数学与C语言在逻辑推理中的应用
    本文探讨了如何结合离散数学的知识和C语言编程技巧,解决具体的逻辑推理问题。通过实例分析,展示了从问题抽象到程序实现的完整过程。 ... [详细]
  • 本文介绍了进程的基本概念及其在操作系统中的重要性,探讨了进程与程序的区别,以及如何通过多进程实现并发和并行。文章还详细讲解了Python中的multiprocessing模块,包括Process类的使用方法、进程间的同步与异步调用、阻塞与非阻塞操作,并通过实例演示了进程池的应用。 ... [详细]
  • 深入解析C++ Atomic编程中的内存顺序
    在多线程环境中,为了防止多个线程同时修改同一数据导致的竞争条件,通常会使用内核级同步对象,如事件、互斥锁和信号量等。然而,这些方法往往伴随着高昂的上下文切换成本。本文将探讨如何利用C++11中的原子操作和内存顺序来优化多线程编程,减少不必要的开销。 ... [详细]
author-avatar
衴u神是欧豪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有