单片机
返回首页

DS18B20+LCD1602数字温度传感器

2016-09-29 来源:eefocus

/*STC89C52+LCD1602+DS18B20温度显示

  显示4位小数
  仅支持正温度
  DJNZ指令为两周期指令*/
   
RS BIT P2.4
RW BIT P2.5
E BIT P2.6

DQ BIT P1.7

COM DATA 30H
DAT DATA 31H
BAI DATA 32H
SHI DATA 33H
GEX DATA 34H
TH  DATA 35H
TL  DATA 36H
XI  DATA 37H

ORG 0000H
SJMP MAIN
ORG 0030H
MAIN:MOV SP,#40H
  LCALL INIT_LCD
  N1:LCALL TEMP_18B20//测温
    LCALL LCD18B20//合并整数 ,拆分小数
  LCALL BCD//数据拆解,将16进制转为BCD码
    LCALL DISP_LCD //温度显示
  LJMP N1

TEMP_18B20:LCALL INIT_18B20
     MOV COM,#0CCH
     LCALL WRITE_18B20
     MOV COM,#44H
     LCALL WRITE_18B20
     LCALL DELAY200MS
     LCALL INIT_18B20
     MOV COM,#0CCH
     LCALL WRITE_18B20
     MOV COM,#0BEH
     LCALL WRITE_18B20
     LCALL READ_18B20
     MOV TL,DAT
     LCALL READ_18B20
     MOV TH,DAT
     RET
     
INIT_18B20:SETB DQ
     NOP
     CLR DQ
     LCALL DELAY600US//延时600US            
     SETB DQ
     MOV R0,#20
  N2:NOP
     DJNZ R0,N2 //延时60US
     JB DQ,$
     LCALL DELAY600US //等待18B20响应完毕
     SETB DQ
     RET

WRITE_18B20:MOV A,COM
   MOV R2,#8 
  WR1:SETB DQ
   NOP
      CLR DQ
   NOP
   RRC A
   MOV DQ,C
   MOV R3,#30
   DJNZ R3,$    
   DJNZ R2,WR1
   SETB DQ//写完一个数据必须将DQ拉到,因为
   RET    //若最后一位C为低电平超过600US则DS18B20被复位
      
READ_18B20:MOV R2,#8
   RE01:SETB DQ
     NOP
     CLR DQ
     NOP
     SETB DQ
     MOV R3,#5
     DJNZ R3,$
     MOV C,DQ
     MOV R3,#23
     DJNZ R3,$
        RRC A
     DJNZ R2,RE01
     MOV DAT,A
     RET

LCD18B20:MOV R0,#04
   MOV A,TH
   N8:RL A
   DJNZ R0,N8
   MOV TH,A
   MOV A,TL
   SWAP A
   ANL A,#0FH
   ORL A,TH
   MOV TH,A//整数部分
   MOV A,#0FH
   ANL A,TL
   MOV TL,A//小娄部分
   RET

BCD:     MOV A,TH
   MOV B,#100
   DIV AB
   MOV BAI,A
   MOV A,B
   MOV B,#10
   DIV AB
   MOV SHI,A
   MOV GEX,B
   MOV A,TL
   MOV R0,#4
   MOV R1,#XI //四位小数由高到低分别在XI开始的单元中存储
   M1:MOV B,#10
   MUL AB
      MOV B,#16
   DIV AB
   MOV @R1,A
   INC R1
   MOV A,B
   DJNZ R0,M1
   RET

INIT_LCD:MOV COM,#00111000B
      LCALL WRITE_COM
   MOV COM,#00001110B
   LCALL WRITE_COM
   MOV COM,#00000110B
   LCALL WRITE_COM
   MOV COM,#00000001B
   LCALL WRITE_COM
   RET

DISP_LCD:MOV COM,#80H
   LCALL WRITE_COM
   MOV DPTR,#TABLE1
   MOV R1,#16
   MOV R0,#00
   M2:MOV A,R0
     MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   INC R0
   LCALL DELAY1MS
   DJNZ R1,M2
   MOV COM,#0C0H
   LCALL WRITE_COM
   MOV DPTR,#TABLE3
   MOV R1,#05H
   MOV R0,#00H
   M3:MOV A,R0
     MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   INC R0
   LCALL DELAY1MS
   DJNZ R1,M3
   MOV DPTR,#TABLE2
   MOV A,BAI
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   MOV A,SHI
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   MOV A,GEX
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   MOV A,#10
   MOV DPTR,#TABLE2
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   MOV R1,#04
   MOV R0,#XI
   M4:MOV A,@R0
     MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   LCALL DELAY1MS
   INC R0
   DJNZ R1,M4
   MOV A,#11
   MOVC A,@A+DPTR
   MOV DAT,A
   LCALL WRITE_DAT
   LCALL DELAY1MS
   RET     

WRITE_COM:CLR RS
    CLR RW
    MOV P0,COM
    LCALL DELAY3MS
    CLR E
    SETB E
    CLR E
    RET

WRITE_DAT:SETB RS
    CLR RW
    MOV P0,DAT
    LCALL DELAY3MS
    CLR E
    SETB E
    CLR E
    RET

DELAY200MS:   ;误差 0us
    MOV R7,#04H
DL6:
    MOV R6,#74H
DL5:
    MOV R5,#0D6H
    DJNZ R5,$
    DJNZ R6,DL5
    DJNZ R7,DL6
    NOP
    RET

DELAY3MS:   ;误差 0us
    MOV R6,#6FH
DL0:
    MOV R5,#0CH
    DJNZ R5,$
    DJNZ R6,DL0
    RET

DELAY1MS:   ;误差 0us
    MOV R7,#01H
DL4:
    MOV R6,#8EH
DL3:
    MOV R5,#02H
    DJNZ R5,$
    DJNZ R6,DL3
    DJNZ R7,DL4
    RET

DELAY600US:   ;误差 0us
    MOV R6,#03H
DL2:
    MOV R5,#62H
    DJNZ R5,$
    DJNZ R6,DL2
    RET

 

TABLE1: DB 'Digital thermomet'
TABLE2: DB '0123456789.C'
TABLE3: DB 'temp:'

  END

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include
#include
#define uint unsigned int
#define uchar unsigned char
sbit rs=P2^4;
sbit rw=P2^5;
sbit e=P2^6;
sbit dq=P1^7;
uchar bai,shi,ge,xi1,xi2,i;
uint temp;
uchar code table1[]={'0123456789.C'};
uchar code table2[]='Digital thermomet';
uchar code table3[]='temp:';

void delay(uchar t)   //误差 0us  1mS延时
{
    unsigned char a,b;
    for(t=1;t>0;t--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);
}

/**************DS18B20操作******************/
void init_ds18b20()
{
 dq=1;
 _nop_();
 dq=0;
 for(i=0;i<200;i++);//延时min=480uS ,max=960uS;
 dq=1;
 for(i=0;i<20;i++);//延时min=15uS,max=60uS.DS18B20等待15~60uS;
 while(dq); //dq为1表明无DS18B20
 for(i=0;i<200;i++)//延时300us使DS18B20输出应答完毕
 dq=1;
}

void WriteOneByte(uchar dat)
{
 uchar j;
 for(j=8;j>0;j--)
 {
  dq=1;
  _nop_();    //至少1mS延时
  dq=0;
  _nop_();
  dq=(bit)(dat&0x01);
  for(i=0;i<20;i++);//写周期最少为60uS,不能超过120uS
  dq=1;
  //for(i=0;i<1;i++); //可以没有
  dat>>=1;
 }
}

uchar ReadOneByte()
{
 uchar j,dat;
 for(j=0;j<8;j++)
 {
  dq=1;
  _nop_();  //至少1uS的恢复期
  dq=0;
  _nop_();
  dq=1;
  for(i=0;i<3;i++);//主机在15uS内读取DQ
  dat>>=1;
  if(dq==1)
   dat|=0x80;
  else
   dat|=0x00;
  for(i=0;i<15;i++);//一个读周期至少要60us
 } 
 return(dat);
}

void temp_ds18b20()
{
 uchar th,tl;
 uint x;
 float p;
 init_ds18b20();
 WriteOneByte(0xcc);
 WriteOneByte(0x44);
 delay(255);//等待转换最大为750ms,典型值为200mS
 init_ds18b20();
 WriteOneByte(0xcc);
 WriteOneByte(0xbe);
 tl=ReadOneByte();
 th=ReadOneByte();
 x=th;
 x<<=8;
 x|=tl;  //合并高低位
 p=x*0.0625; //实际转换温度值为p
 temp=p*100+0.5;//将小数转换为整数并保留两位小数,第三位小数四舍五入
}
/******************************************************/

/***********************数据转换***********************/
void datchx()
{
 uchar d,t;
 float g;
 g=temp/100.00;
 d=g;
 t=(g-d)*100;//整数与小数部分分离,t为小数,d为整数;
 bai=d/100;
 shi=(d%100)/10;
 ge=d%10;//整数分离
 xi1=t/10;
 xi2=t%10;
}
/****************************************************/
/******************LCD1602操作***********************/
void write_com(uchar dat)
{
 rs=0;
 rw=0;
 P0=dat;
 delay(3);
 e=0;
 e=1;
 e=0;
}

void write_dat(uchar dat)
{
 rs=1;
 rw=0;
 P0=dat;
 delay(3);
 e=0;
 e=1;
 e=0;
}

void init_lcd()
{
 write_com(0x38);
 write_com(0x0D);
 write_com(0x06);
 write_com(0x01);
}

void disp_lcd()
{
 write_com(0x80);
 for(i=0;i<16;i++)
 {
  write_dat(table2[i]);
  delay(5);
 } 
 write_com(0xc0);
 for(i=0;i<5;i++)
 {
  write_dat(table3[i]);
  delay(5);
 }
 write_dat(table1[bai]);
 write_dat(table1[shi]);
 write_dat(table1[ge]);
 write_dat(table1[10]);
 write_dat(table1[xi1]);
 write_dat(table1[xi2]);
 write_dat(table1[11]);
}
/****************************************************/
void main()
{
 SP=0x30;
 init_lcd();
 while(1)
 {
  temp_ds18b20();
  datchx();
  disp_lcd();
 }
}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • IGBT模块通过控制门极阻断过电流

  • 运算放大器IC741的基本工作原理及在电路中的实现方式

  • 比较常见的功率整流器和滤波电路

  • 基于M66T旋律发​​生器的电路图解析

  • 基于CA3193的热电偶放大器电路

  • 基于TDA1554的立体声放大器电路

    相关电子头条文章