热门标签 | 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);

  }

}

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




推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了基于c语言的mcs51单片机定时器计数器的应用教程,包括定时器的设置和计数方法,以及中断函数的使用。同时介绍了定时器应用的举例,包括定时器中断函数的编写和频率值的计算方法。主函数中设置了T0模式和T1计数的初值,并开启了T0和T1的中断,最后启动了CPU中断。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文介绍了汉诺塔问题的迭代算法实现,通过递归的方式将盘子从一个地方搬到另一个地方,并打印出移动的顺序。详细介绍了算法的思路和步骤,以及示例代码的运行结果。 ... [详细]
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社区 版权所有