找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2366|回复: 1
收起左侧

ds18b20+lcm1602温度显示报警系统

[复制链接]
ID:568565 发表于 2019-6-25 08:28 | 显示全部楼层 |阅读模式
前两天做了一个ds18b20+lcm1602温度显示报警系统,将报告及源代码分享给大家学习,有什么问题还请指正


一、单片机简介
二、项目任务和要求
三、项目设计方案的总体设计框图
3.1硬件电路框图
3.2硬件电路概述
3.3主控电路
3.4显示电路
3.5报警温度调节电路
1、蜂鸣器
2、跑马灯
3.6温度传感器及DS18B20测温基本原理
3.7单片机硬件连接实物图
四、系统软件算法设计
五、总结与体会

附录
参考文献

单片机简介
   1.实验系统简介
本次课设单片机实验系统采用nKDE-51 单片机实验系统,nKDE-51 单片机实验教学系统采用模块化设计,以方便学生自由组合功能,设计实验。整个实验系统包括六个功能模块,分别为CPU板、基本IO板、模拟总线接口IO口、扩展总线接口IO板,字符点阵LCD/大容量 flash/GPRS 模块板和uart/以太网及电话接口拓展板。本次课设需要CPU板,lcm1602模块,温度传感器模块,流水灯模块、蜂鸣器模块以及数码管模块,所以该实验板完全满足课设的需要,具体用的各部分图如下:

CPU板部分如图:

IO口板部分和模拟总线部分板如下图

2.系统资源及功能简介
(1) 单片机端口的引出
MCS-51 系列单片机共有 4 个独立的 8 位并行 I/O 端口分别为 P0、P1、P2 和 P3在 CPU板上各通过两个8 芯单排插针引出,可通过杜邦插座连接到其它模块或器件。
(2) CPU 工作频率的选择
nKDE-51 系统提供了四种常用的晶振频率分别是 11.0592MHz、12MHz、18.432MHz 和
22.1184MHz。用户可通过跳线JP1 和 JP2来选择系统晶振的频率。如果用户还需要其它的晶振频率,本系统预留了一个焊接晶振的位置X5可供使用。
(3) CPU 工作模式的选择
MCS-51 单片机的工作方式可分为端口工作方式不扩展总线和扩展总线模式。在扩展总线模式单片机的P0口通过ALE信号控制外部地址锁存器复用为地址总线低8位地址和数据 总线,P2口提供高8位地址,同时P3.6和P3.7作为W R和R D信号。而当单片机工作在端口方式下时P0~P3的每一位都可以作为独立的端口引脚使用。 在 nKDE-51 系统中当实验中不使用扩展总线时,单片机的端口可通过表 1-1 所列出的插座引出。如果单片机实验需要使用扩展总线用户可使用系统提供的 40 芯连接电缆将J9和JX1连接起来。此时 P0、P2 和 P3.6、P3.7 等引脚已作为系统总线使用,不要再将它们用作普通的 I/O。JX2 和 JX3 的各引脚和 JX1 的对应引脚相连可以通过它们将总线连接到其它模块上。
单片机的ISP及串行口
电路连接nKDE-51系统使用 STC 公司的STC 12C5A60S2 作为 CPU。该 CPU 兼容标准51内核自带 64K字节的 Flash 程序存储器支持通过串行口进行在系统编程ISP以及程序调试单片机的串行口通过双向自锁开关 SW2 选择连接到 9 芯孔型插座 COM1 RS232 接口用于和 计算机通信进行 ISP 或程序调试或者连接到 J4、J8 及 J9用于进行 I/O 端口及 RS485 通信等实验.计算机必须通过实验系统提供的9 芯串口延长电缆和 COM1 相连。 当SW2 弹起时单片机的串行口连接到 COM1 , 当 SW2 按下时单片机串行口连接到 J4、J8 及J9。

项目任务及要求
1. 单片机P0.0和DS18B20的数据端相连;(实验八)
2. 编写单片机通过IO端口模拟单总线时序控制DS18B20的程序,读出温度;(实验八)
3. 在1602字符点阵液晶显示模块上显示实测温度(实验七)
4.蜂鸣器报警功能;(+5)
5.串口显示功能;(+5)
6.发光二极管流水灯报警功能,随着温度超过警戒值范围改变,流水灯的速率进行改变。(+5)
7.计数器功能记录超过警戒值的次数,单个或者八位数码管显示 计数。(+5)
1-3为基本功能部分,4-6为增加功能部分
创新部分: 比如:音乐播放实现声音报警等。

三、项目设计方案的总体设计框图

3.1硬件电路框图

3.2硬件电路概述
单片机P0.0和DS18B20的数据端相连,在1602字符点阵液晶显示模块上显示实测温度,P0.7和蜂鸣器相连,P0其余口接LED1-6。

3.3主控电路
主控电路主要使用 STC 公司的STC 12C5A60S2作为 CPU,控制整个系统的工作。

3.4显示电路
LCD显示器是一种用液晶材料制成的液晶显示器,它具有体积小、功耗低、字迹清晰、无电磁辐射、寿命长等优点,1602 字符点阵式LCM共有两个显示行,每行可显示16个字符,为最常用的一种字符式LCM,显示控制器为HD44780,通过HD44100进行规模的扩展。


3.5报警温度调节电路
1、蜂鸣器
当温度超过30度时,蜂鸣器会发出间隔的报警声响。

2、跑马灯

在30度以上时,跑马灯会常亮,28-30度时会随着温度的升高而加快。

3.6温度传感器及DS18B20测温基本原理
DS18B20 数字温度传感器提供9位(二进制)温度读数指示器件的温度数据经单线接口和CPU交互,因此CPU和DS18B20之间只需一条信号线和地址线即可进行通信。

原理图如下:

       3.7单片机硬件连接实物图



四、系统软件算法设计

   主程序 main.c
#include <reg51.h>
#include <intrins.h>
#include <stdio.h>
#include "lcm16x2p.h"
#include "DS18B20.h"
#define OSC 11059200            //晶振频率
#define BAUDRATE 9600    //波特率
#define LCM_DB P2
sbit BUZ_CON = P0^7;
sbit LED =P0;
sbit LCM_BLC=P1^3;

void main(void)
{
       unsigned char ucTH,ucTL,Ticks;             //中断程序            
       unsigned int i;
       unsigned char tmph,tmpl;
       Temp t;
       unsigned char strTemp[8];    //显示到屏幕的温度数据
       LCM_BLC = 0;                     //开背光
       TMOD = 0x21;                  //选择方式2作为波特率发生
       SCON = 0x50;                   //串口方式1,允许中断
       PCON |= 0x80;                  //SMOD=1
       TL1 = 256 -(OSC/12/16/BAUDRATE);
       TH1 = 256 -(OSC/12/16/BAUDRATE);
       TR1 = 1;                                  //启动定时器
       TI = 1;                                   //TI有效
//检测DS18B20温度传感器是否存在并复位传感器
       if(DSReset())
           printf("\r\Temp sensor ResetOK!");
       else  printf("\r\Temp Sensor Notready!");
    while(1){
          DSReset();                             //复位传感器
          Delay(12);
          DSWriteByte(SkipROM);                  //跳读 省时
          DSWriteByte(StartConvert);             //温度转换
          for(i=0;i<40000;i++);
          DSReset();
          Delay(12);
          DSWriteByte(SkipROM);
          DSWriteByte(ReadMemory);   //读RAM程序
          tmpl = DSReadByte();
          tmph = DSReadByte();
          printf("\r\nTemperature code HI=%02bX,LO=%02bX ",tmph,tmpl);
          DSReadTemp(&t);
//准备输出到显示屏的数据
        strTemp[0]=t.z/10+0x30;     //十位
        strTemp[1]=t.z%10+0x30;     //个位
        strTemp[2]='.';             //小数点
        strTemp[3]=t.x/1000+0x30;   //十分位
        strTemp[4]=(t.x/100)%10+0x30; //百分位
  strTemp[5]=(t.x/10)%10+0x30;//千分位
  strTemp[6]=t.x%10+0x30;            //万分位
        strTemp[7]='C';
              if(t.z>=30)
              printf("\nWarning!!!Temperature= %d.%04d ",t.z,t.x) ;  //大于30度温度警告
              else
        printf("\r\nTemperature = %d.%04d",t.z,t.x);

//小于26度LED灯全亮     
     if(t.z<26)  
     {
              P0=0x00;                    
              }
              else
              {
              P0=0xff;                     //灯灭
              }


//大于28度流水灯循环(慢)
              if(t.z>=28)
     {

              BUZ_CON=1;
              P0=0xfd;
              LCMDelay(60);
              P0=0xfb;
              LCMDelay(60);
              P0=0xf7;
              LCMDelay(60);
              P0=0xdf;
              LCMDelay(60);
//大于29度流水灯循环(快)            
              if(t.z>=29)
            {

              P0=0xfd;
              LCMDelay(10);
              P0=0xfb;
              LCMDelay(10);
              P0=0xf7;
              LCMDelay(10);
              P0=0xdf;
              LCMDelay(10);
              P0=0xbf;
              LCMDelay(10);
             }
//大于30度灯全亮。蜂鸣器响
              if(t.z>=30)
               {
                 BUZ_CON=0;
     LCMDelay(100);
                 P0=0x00;  


               }
       }
             else{
                BUZ_CON=1;         
                }
//初始化
        EA = 0;  //  停止所有中断
        Ticks = 0;
        ucTH =(65536-OSC/12/20)/256; //  计算 50ms 定时的时间常数
        ucTL =(65536-OSC/12/20)%256;
        TMOD = 0x21; // T0:模式 1,16 位定时器
        TH0 = ucTH;
        TL0 = ucTL;
        ET0 = 1; // T0 允许中断
        TR0 = 1; //  启动定时器
        EA = 1; //  打开总中断允许
//输出数据到显示屏
        LCMInit();                       //初始化LCM显示器
        LCMClear();                      //清屏
              if(t.z>=30){
              LCMDisplayString(0,0,"TempWarning!!!"); //大于29度警告   
              LCMDisplayString(1,0,"Temp:");   
              LCMDisplayString(1,6,strTemp);              
              }
              else{
       LCMDisplayString(0,0,"Temperature:");
       LCMDisplayString(1,0,strTemp);   
              }
        //闪烁(刷新)
        for(i = 0; i < 16;i++)
           LCMBlink(0,i,BLINK);
        for(i = 0; i < 16;i++)
           LCMBlink(1,i,BLINK);
    }
}


子程序ds18b20.h文件
#ifndef __DS18B20H__
#define __DS18B20H__
#define ReadROM 0x33
#define MatchROM 0x55
#define ReadMemory 0xBE
#define SkipROM 0xCC
#define SearchROM 0xF0
#define StartConvert 0x44   //变换指令
typedef struct{
    int z;  //整数部分
    int x;  //小数部分
}Temp;
extern unsigned char ucTH,ucTL,Ticks;    //外部引用
void Delay(unsigned int);
bit DSReset(void);
void DSWriteByte(char);
unsigned char DSReadByte(void);
void DSReadTemp(Temp *t);
#endif


ds18b20.c文件
#include "DS18B20.h"
#include <reg51.h>
#include <intrins.h>
sbit DQ = P0^0;
/*
Delay
通过循环计时
参数:int,表示要延时的 毫秒 数
*/
void Delay(unsigned int i)
{        i=i*12;
    while(i--);
}
/*
DSReset
复位DS18B20并返回是否存在
*/
bit DSReset(void)
{
    bit x;
    DQ = 1;
    Delay(8);
    DQ = 0;        // 主机拉低总线
    Delay(80);          // 延时约 500 个机器周期
    DQ = 1;               //  主机释放总线
    Delay(8);              //  延时 60 个机器周期
    x = DQ;
    Delay(20);
    if(x == 0)
      return 1;
    else return 0;
}
/*
DSWriteByte
向 DS18820  写入一个字节
*/
void DSWriteByte(unsigned char c)
{
    unsigned char ic;
       for( ic = 0; ic < 8;ic++ )
       {
           DQ = 0;              //主机拉低总线,开始写位
           DQ = c&0x01;
        Delay(5);           //延时60个机器周期
        DQ = 1;                       //释放总线
        c >>= 1;
       }
}
/*
DSReadByte
从温度传感器读出一个字节
返回:读出的字节
*/
unsigned char DSReadByte(void)
{
    unsigned char c,ic;
    c = 0;
    for(ic = 0; ic < 8;ic++)
       {
        DQ = 0;
        c >>= 1;              //右移
        DQ = 1;
        if(DQ )
            c |= 0x80;
        Delay(4);
    }
    return c;
}
/*
DSReadTemp
读出温度
参数:温度(由整数和小数部分构成)
*/
void DSReadTemp(Temp *t)
{
    unsigned char tmpl,tmph;
       DSReset();
    Delay(12);
       DSWriteByte(SkipROM);
       DSWriteByte(StartConvert);
       DSReset();
       Delay(12);
       DSWriteByte(SkipROM);
       DSWriteByte(ReadMemory);
       tmpl = DSReadByte();
       tmph = DSReadByte();
       t->z =(int)((tmph&0x07)<<4 | (tmpl&0xf0)>>4);
       t->x =(int)((tmpl&0x0f)*625);
}
/*
T0ISR
50ms中断服务程序
*/
void T0ISR(void) interrupt 1
{
       unsigned char ucTH,ucTL,Ticks;
       TH0 = ucTH;
       TL0 = ucTL;
       TR0 = 1;
       Ticks ++;
       if(Ticks == 20)
       {
    Ticks = 0;
       }
}

         lcm16x2p.h文件
#ifndef LCM16X2_H
#define LCM16X2_H
#define BUSYFLAG 0x80
#define BLINK 0X01
#define NOBLINE 0X00
unsigned char LCMReadState(void);
void LCMDelay(int);
void LCMWriteData(unsigned char);
void LCMWriteCmd(unsigned char);
void LCMClear(void);
void LCMInit(void);
    void LCMGotoXY(unsigned char,unsigned char);
void LCMDisplay(unsigned char,unsigned char,unsigned char);
void LCMDisplayString(unsigned char,unsigned char,unsigned char*);
void LCMBlink(unsigned char,unsigned char,unsigned char);
#endif
         llcm16x2p.c文件
#include <reg51.h>
  #include <intrins.h>
  #include "LCM16X2P.H"
  #define LCM_DB P2
  sbit LCM_RS = P1^0;
  sbit LCM_RW = P1^1;
  sbit LCM_E = P1^2;
  sbit LCM_BLC = P1^3;
  unsigned int data DelayConst = 140;

  // 延时程序
  void LCMDelay  (int ms)
  {
  unsigned int i,cnt;
  cnt = DelayConst * ms*12;
  for(i=0;i<cnt;i++);
  }

  //查询LCM忙的标志
  unsigned char LCMReadState(void)
  {
  unsigned char state;
   LCM_E = 0;
   LCM_RS = 0;
   LCM_RW = 1;
   LCM_E = 1;
   _nop_();
   _nop_();
   state = LCM_DB;
   LCM_E = 0;
   return state;

  }

  //clear  qingpin
  void LCMClear(void)
  {
  LCMDelay(12);
   LCM_E = 0;
   LCM_RS = 0;
   LCM_RW = 0;
   LCM_DB =        0x01;
   LCM_E = 1;
   _nop_();
   _nop_();
   LCM_E = 0;
   LCMDelay(12);

  }
  //writecmd   xierukongzhizi
void LCMWriteCmd(unsigned char cmd)
  {
  LCMDelay(1);
   LCM_E = 0;
   LCM_RS = 0;
   LCM_RW = 0;
   LCM_DB =        cmd;
   LCM_E = 1;
   _nop_();
   _nop_();
   LCM_E = 0;
  }

  //write data   xierushuju
  void LCMWriteData(unsigned char dc)
  {
  while (LCMReadState()&BUSYFLAG);
   LCM_RS = 1;
   LCM_RW = 0;
   LCM_DB =        dc;
   LCM_E = 1;
   _nop_();
   _nop_();
   LCM_E = 0;

  }
  // init  chushihua
  void LCMInit(void)
  {
  LCMDelay(720);
  LCMWriteCmd(0x38);
  LCMDelay(60);
  LCMWriteCmd(0x38);
  LCMDelay(12);
  LCMWriteCmd(0x38);
  while(LCMReadState()&BUSYFLAG);
  LCMWriteCmd(0x08);
  while(LCMReadState()&BUSYFLAG);
  LCMWriteCmd(0x01);
  while(LCMReadState()&BUSYFLAG);
  LCMWriteCmd(0x06);
  while(LCMReadState()&BUSYFLAG);
  LCMWriteCmd(0x0e);
  while(LCMReadState()&BUSYFLAG);

  }

  //gotoxy  yidongguangbiaodao x hang  y  lie

  void LCMGotoXY(unsigned char x, unsigned char y)
  {
  unsigned char cmd;
  if(x==0)
  {
  cmd = 0x80|y;
  }
  else
  {
  cmd =0x80 | 0x40 |y ;

  }
  LCMWriteCmd(cmd);
  while(LCMReadState() & BUSYFLAG);

  }

  //LCMDISPLAYchar    zhidingweizhixianshizifu
  void LCMDisplayChar(unsigned char x, unsigned char y,unsigned char ch)
  {
  LCMGotoXY(x,y);
  LCMWriteData(ch);
  }

  //xianshizifuchan
  void LCMDisplayString(unsigned char x,unsigned char y,unsigned char* str)
  {
  unsigned char ptr;
  ptr=0;
  while (*(str+ptr)!=0)
  {
  LCMDisplayChar(x,(y+ptr),*(str+ptr));
  ptr++;
  }
  }

  //LCMBLINK   zifushanshuo

  void LCMBlink(unsigned char x,unsigned char y, unsigned char cmd)
  {
  LCMGotoXY(x,y);
  if(cmd == BLINK)
  {
  LCMWriteCmd(0x0d);
  }
  else
  {
  LCMWriteCmd(0x0c);

  }
  }

  五、总结与体会
经过一周的学习与努力,温度显示系统的设计终于完成了,真正的学到了东西。学习了单片机这门,感觉是有点难。也不明白整个学习过程是怎样过来得,但是时间不等人。但是在学习中,我才发现学习单片机不仅仅仅需要软件的知识,还需要硬件的知识。没有相应的硬件知识,我连单片机怎样和电脑相连都不明白,我为我当初的想法感到羞愧。单片机是一门很好的学问,需要我去钻研它。一转眼,一个学期又进尾声了,本学期的单片机综合设计也在一周内完成了。
  说起设计,我认为最重要的就是做好设计的预习,认真的研究老师给的题目,其次,老师对实验的讲解要一丝不苟的去听去想,因为只有都明白了,做起设计就会事半功倍,如果没弄明白,就迷迷糊糊的去做设计,到头来一点收获也没有。最后,要重视程序的模块化,修改的方便,也要注重程序的调试,掌握其方法。在享受我们成果之时,不得不感慨单片机的重要性与高难度性,所以为期一周的单片机设计没有浪费我我们学到了很多知识,也让我对单片机有了更深一步的了解,虽然最后结果是出来了,可这与老师的精心指导是分不开的她引导我们的思路,本来一窍不通的我经过老师的点拨基本上通了,所以老师是功不可没的。总而言之,单片机设计对于我有很大的帮忙,我从中受益匪浅。

18b20及实物图

18b20及实物图

显示模块

显示模块

硬件框图

硬件框图

io口及拓展

io口及拓展
IMG_20190625_082108.png

温度显示报警代码及报告.zip

3.52 MB, 下载次数: 28, 下载积分: 黑币 -5

回复

使用道具 举报

ID:664223 发表于 2019-12-15 12:40 | 显示全部楼层
老哥硬件电路框图能发我一下吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表