问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

以AT89C51单片机和DS18B20实现温度检测显示并报警的程序和电路图,显示用M016L液晶模块显示

发布网友 发布时间:2022-04-26 09:02

我来回答

1个回答

热心网友 时间:2023-10-09 03:20

汇编语言程序:

 

;*********************************************************************

;程序适合单个DS18B20和MCS-51单片机的连接,晶振为12MHz

;测量的温度范围-55℃~+99℃,温度精确到小数点后一位 

;*********************************************************************

TEMPER_L    EQU    30H       ;存放从DS18B20中读出的高、低位温度值

TEMPER_H    EQU    31H

TEMPER_NUM  EQU    32H       ;存放温度转换后的整数部分

TEMPER_POT  EQU    33H       ;存放温度转换后的小数部分

FLAG0       EQU    34H       ;FLAG0存放温度的符号 

DQ           EQU    P1.0      ;DS18B20数据线

RS   BIT   P1.7              ;LCD1602控制线定义

RW   BIT   P1.6

E    BIT   P1.5

SkipDs18b20    EQU    0CCH   ;DS18B20跳过ROM命令

StartDs18b20   EQU    44H    ;DS18B20温度变换命令     

ReadDs          EQU    0BEH   ;DS18B20读暂存器命令

 

       ORG 0000H

       SJMP MAIN

       ORG 0040H

 MAIN:MOV SP,#60H

    ACALL  LCD_INIT

    MOV   A,#80H            ;lcd第1行第1列开始显示temperature:

    ACALL  WC51R

    MOV   A,#'t'                 

    ACALL  WC51DDR

    MOV   A,#'e'                

    ACALL  WC51DDR

    MOV   A,#'m'                

    ACALL  WC51DDR

    MOV   A,#'p'                

    ACALL  WC51DDR

    MOV   A,#'e'                 

    ACALL  WC51DDR

    MOV   A,#'r'                 

    ACALL  WC51DDR

    MOV   A,#'a'                

    ACALL  WC51DDR

    MOV   A,#'t'                

    ACALL  WC51DDR

    MOV   A,#'u'                 

    ACALL  WC51DDR

    MOV   A,#'r'                 

    ACALL  WC51DDR

    MOV   A,#'e'                

    ACALL  WC51DDR

    MOV   A,#':'                

    ACALL  WC51DDR

REP:LCALL GET_TEMPER    ;读出转换后的温度值

     LCALL TEMPER_COV

    MOV   A,#0c6H           ;lcd第2行第7列开始显示温度

    ACALL  WC51R

    MOV   A,FLAG0           ;显示符号

    ACALL  WC51DDR

    MOV   A,TEMPER_NUM      ;温度整数拆分成十位和个位显示

    MOV   B,#10

    DIV   AB

    ADD   A,#30H

    CJNE  A,#30H,REP1       ;如果十位为0不显示

    MOV   A,#20H

REP1:ACALL  WC51DDR

    MOV   A,B

    ADD   A,#30H       

     ACALL  WC51DDR

    MOV   A,#'.'            ;显示小数点 

     ACALL  WC51DDR

    MOV   DPTR,#TABLE

    MOV   A,TEMPER_POT      ;显示小数部分

    MOVC  A,@A+DPTR

     ACALL  WC51DDR     

     LJMP REP

;DS18B20复位程序

DS18B20_INIT:SETB  DQ

    NOP

    NOP

    CLR     DQ

    MOV R7,#9

INIT_DELAY: CALL    DELAY60US

    DJNZ    R7,INIT_DELAY

    SETB    DQ

    CALL    DELAY60US

    CALL    DELAY60US

    MOV     C,DQ

     JC  ERROR

    CALL    DELAY60US

    CALL    DELAY60US

    CALL    DELAY60US

    CALL    DELAY60US

    RET

ERROR:CLR   DQ

     SJMP    DS18B20_INIT

     RET

;读DS18B20一个字节到累加器A程序

READ_BYTE:  MOV     R7,#08H

    SETB    DQ

    NOP

    NOP

LOOP:CLR    DQ

     NOP

    NOP

    NOP

    SETB    DQ

    MOV     R6,#07H

    DJNZ    R6,$

    MOV     C,DQ

    CALL    DELAY60US

    RRC     A

    SETB    DQ

    DJNZ    R7,LOOP

    CALL    DELAY60US

    CALL    DELAY60US

    RET

;累加器A写到DS18B20程序

WRITE_BYTE: MOV     R7,#08H

    SETB    DQ

    NOP

    NOP

LOOP1:CLR  DQ

     MOV     R6,#07H

    DJNZ    R6,$

    RRC     A

    MOV     DQ,C

    CALL    DELAY60US

    SETB    DQ

    DJNZ    R7,LOOP1

    RET

DELAY60US:MOV   R6,#1EH

    DJNZ    R6,$

    RET

;读温度程序

GET_TEMPER: CALL    DS18B20_INIT    ;DS18B20复位程序

     MOV     A,#0CCH                 ;DS18B20跳过ROM命令

    CALL    WRITE_BYTE

    CALL    DELAY60US

    CALL    DELAY60US

    MOV     A,#44H                  ;DS18B20温度变换命令

    CALL    WRITE_BYTE

    CALL    DELAY60US

CALL    DS18B20_INIT            ;DS18B20复位程序

    MOV         A,#0CCH                 ;DS18B20跳过ROM命令

    CALL    WRITE_BYTE

    CALL    DELAY60US

    MOV         A,#0BEH                 ;DS18B20读暂存器命令

    CALL    WRITE_BYTE

    CALL    DELAY60US

    CALL    READ_BYTE               ;读温度低字节

    MOV     TEMPER_L,A

    CALL    READ_BYTE               ;读温度高字节

    MOV     TEMPER_H,A

    RET     

;将从DS18B20中读出的温度拆分成整数和小数

TEMPER_COV:

    MOV    FLAG0,#'+'                  ;设当前温度为正

    MOV    A,TEMPER_H

    SUBB    A,#0F8H

    JC      TEM0                   ;看温度值是否为负?不是,转

    MOV    FLAG0,#'-'                  ;是,置FLAG0为'-'

    MOV    A,TEMPER_L

    CPL    A

    ADD    A,#01

    MOV    TEMPER_L,A

    MOV    A,TEMPER_H

    CPL    A

    ADDC   A,#00

    MOV    TEMPER_H,A

TEM0:

    MOV    A,TEMPER_L            ;存放小数部分到TEMPER_POT     

    ANL    A,#0FH

    MOV    TEMPER_POT,A

    MOV    A,TEMPER_L             ;存放小数部分到TEMPER_NUM

    ANL    A,#0F0H

    SWAP   A

    MOV    TEMPER_NUM,A

    MOV    A,TEMPER_H

    SWAP    A

    ORL    A,TEMPER_NUM

    MOV    TEMPER_NUM,A       

    RET

    ;LCD初始化子程序

LCD_INIT:MOV  A,#00000001H  ;清屏

    ACALL  WC51R

    MOV   A,#00111000B  ;使用8位数据,显示两行,使用5×7的字型

    LCALL  WC51R

    MOV   A,#00001100B   ;显示器开,光标关,字符不闪烁

    LCALL  WC51R

    MOV   A,#00000110B   ;字符不动,光标自动右移一格

    LCALL  WC51R

    RET

    ;检查忙子程序

    F_BUSY:PUSH  ACC    ;保护现场

    MOV   P2,#0FFH

    CLR  RS

    SETB  RW

WAIT:   CLR   E

    SETB  E

    JB   P2.7,WAIT      ;忙,等待

    POP   ACC               ;不忙,恢复现场

    RET

    ;写入命令子程序

WC51R:  ACALL  F_BUSY

    CLR   E

    CLR  RS

    CLR  RW

    SETB  E

    MOV  P2,ACC

    CLR  E

    RET

    ;写入数据子程序

WC51DDR:ACALL  F_BUSY

    CLR   E

    SETB  RS

    CLR  RW

    SETB  E

    MOV  P2,ACC

    CLR  E

    RET

TABLE: DB   30H,31H,31H,32H,33H,33H,34H,34H

        DB   35H,36H,36H,37H,38H,38H,39H,39H  ;小数温度转换表

    END

 

C语言程序:

//程序适合单个DS18B20和MCS-51单片机的连接,晶振为12MHz

//测量的温度范围-55℃~+99℃,温度精确到小数点后一位 

 

#include <REG52.H>

#define uchar unsigned char

#define uint unsigned int

sbit  DQ =P1^0;                       //定义端口

sbit  RS=P1^7;

sbit  RW=P1^6;

sbit  EN=P1^5;

union{

    uchar c[2];

    uint x;

}temp;

uchar flag;//flag为温度值的正负号标志单元, "1"表示为负值,"0"时表示为正值。 

uint cc,cc2;//变量cc中保存读出的温度值   

float cc1;

uchar buff1[13]={"temperature:"};

uchar buff2[6]={"+00.0"};

//检查忙函数

void  fbusy()

{

    P2 = 0xff;

    RS = 0;

    RW = 1;

    EN = 1;

    EN = 0;

    while((P2 & 0x80))

    {

    EN = 0; 

    EN = 1;     

    }

}

//写命令函数

void  wc51r(uchar  j)

{

    fbusy();

    EN = 0;

    RS = 0;

    RW = 0;

    EN = 1;

    P2 = j;

    EN = 0;

}

//写数据函数

void  wc51ddr(uchar  j)

{

    fbusy();        //读状态;

    EN = 0;

    RS = 1;

    RW = 0;

    EN = 1;

    P2 = j;

    EN = 0;

}

void  init()

{

wc51r(0x01);         //清屏

wc51r(0x38);         //使用8位数据,显示两行,使用5*7的字型

wc51r(0x0c);         //显示器开,光标开,字符不闪烁

wc51r(0x06);         //字符不动,光标自动右移一格

}

void delay(uint useconds)                 //延时程序

{

  for(;useconds>0;useconds--);

}

uchar ow_reset(void)                       //复位

{

  uchar presence;

  DQ = 0;                               // DQ 低电平

  delay(50);                           // 480ms

  DQ = 1;                                // DQ 高电平

  delay(3);                             // 等待

  presence = DQ;                       // presence 信号

  delay(25);

  return(presence);                     // 0允许, 1禁止

}                                         

uchar read_byte(void)                    //从单总线上读取一个字节

{

  uchar i;

  uchar value = 0;

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

  {

    value>>=1;

    DQ = 0;

    DQ = 1;

    delay(1);

    if(DQ)value|=0x80;

    delay(6);

  }

  return(value);

}

void write_byte(uchar val)       //向单总线上写一个字节

{

  uchar i;

  for (i=8; i>0; i--)             // 一次写一字节

  {

    DQ = 0;

    DQ = val&0x01;

    delay(5);

    DQ = 1;

    val=val/2;

  }

  delay(5);

}

 

void Read_Temperature(void)     //读取温度

{

  ow_reset();

  write_byte(0xCC);               // 跳过 ROM

  write_byte(0xBE);               // 读

  temp.c[1]=read_byte();

  temp.c[0]=read_byte();

  ow_reset();

  write_byte(0xCC);

  write_byte(0x44);               // 开始 

  return;

}

void main()                        //主程序

{

uchar  k;

delay(10);

  EA=0;

  flag=0;

  init();

wc51r(0x80);                      //写入显示缓冲区起始地址为第1行第1列

for (k=0;k<13;k++)              //第一行显示提示信息"current temp is:"

    { wc51ddr(buff1[k]);}

while(1)

 {

  delay(10000); 

  Read_Temperature();             //读取双字节温度

  cc=temp.c[0]*256.0+temp.c[1];

  if  (temp.c[0]>0xf8) {flag=1;cc=~cc+1;}else flag=0;

  cc1=cc*0.0625;              //计算出温度值

 

  cc2=cc1*100;                  //放大100倍,放在整型变量中便于取数字

  buff2[1]=cc2/1000+0x30;if ( buff2[1]==0x30) buff2[1]=0x20;//取出十位,转换成字符,如果十位是0不显示。

  buff2[2]=cc2/100-(cc2/1000)*10+0x30;//取出个位,转换成字符

  buff2[4]=cc2/10-(cc2/100)*10+0x30;//取出小数点后一位,转换成字符

  if (flag==1) buff2[0]='-';else buff2[0]='+';

  wc51r(0xc5);            //写入显示缓冲区起始地址为第2行第6列     

  for (k=0;k<6;k++)         //第二行显示温度

    { wc51ddr(buff2[k]);}

}

}

 

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
ups快递客服电话24小时 贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 潮的组词有哪些的 谁知道GB牧场物语3金手指的密码???告诉我好吗??? 有鱼骨线的拉丁舞裙谁穿过? 没有根的垂盆草,压在土里能不能活呢? 新唐M0516,即(NuMicro M0516) 单片机怎样下载程序? 潮的组词。 做西餐鱼类是必须得剃鱼骨吗? &quot;欲潮未遂 微潮年华&quot;是什么意思? 移植多肉的时候,用湿土好还是移植后再浇水好? 请问自行车狼主t580好还是千里达m016好呢? 在微潮的NH4HCO3固体中拌入电石粉末,溢出的气体主要有( ) 鱼骨粒怎么做 潮和朝的组词 武汉微潮网络科技有限公司怎么样? 鱼骨纹和虎斑纹区别 微潮色是什么颜色? 魔兽世界瘟疫海岸那个任务怎么做啊..让我收集鱼骨怎么收集啊 微潮色是什么意思理发是发根和发尾颜色不一样吗 浙江微潮影视文化有限公司怎么样? 打算选择适合的染发颜色,要如何选择呢? 潮怎么组词? 潮可以组成什么词语 这个是美短曼基康吗,短腿,怎么认虎纹和鱼骨纹呀? \ chao 潮的组词 组词。潮,贯,嘲,淌。 DAPPER是潮牌吗? 9岁的小孩适合学习编程吧? 9岁学编程,该学什么语言? 少儿编程课到底几岁开始学?给9岁的孩子报核桃编程的课可以么? 我家孩子9岁了学什么编程比较好? C9童创编程教育青少儿编程怎么样? 看广州市中心的小码王少儿编程非常火,孩子有必要学少儿编程么? 少儿编程的九大能力在我们课程中怎么体现的? 想做药品注册,是去药厂好还是专门做注册的公司好呢? 注射用药注意事项 要做对人有益的事,要做光,做盐。做盐是什么意思? 药物常用注射法有哪些? 豫卫药注字(97)116号伸筋壮骨胶囊是真药吗? 猪屎干结用什么药注 大头两角三年福建版怎么区分