锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

基于单片机的温度记录器

时间:2022-12-25 20:30:00 hr温度传感器

1、试题

(1)功能简述

设备根据用户设定的时间间隔自动收集和存储温度数据,并具有收集提醒、数字管显示等功能。系统硬件部分主要由按钮电路、电源电路组成 RTC 由时钟、传感器电路和显示电路组成。系统框图如图所示 1 所示:

83d0dfd2d6ea1a65fd8807df09a94072.png

(2)设计任务及要求

1. 数码管显示

1.1 设备上电后,自动进入参数设置界面(图 1) 此时,通过按键 S4 切换 4 温度采集间隔时间分别为 1 秒、 5 秒、 30 秒和 60 秒;


按下按键 S5.确认采集间隔并退出参数设置界面(图 1)进入时钟显示界面(图 2)并开始采集温度。

要求:时钟显示界面(图) 下面,提示符 1、 2 以 1 秒是间隔闪烁

1.2 当设备按照用户设定的采集间隔采集到 10 数据后,指示灯 L1 闪烁提示温度采集已完成,此时进入数字管温度采集显示界面(图 3):


此时,按下 S6, L1 按时间顺序熄灭,切换显示设备内存储的温度数据;按下 S7 按钮进入参数设置界面(图) 1),待用户输入温度采集间隔之后,可以进行下一次的温度采集工作。
说明:索引是指按照采集时间顺序(00-09)显示的当前温度的编号。
2. 温度检测功能

使用 DS18B20 温度传感器完成温度测量功能。

3. RTC

使用 DS1302 完成时钟芯片 RTC 相关功能。

4. 说明设备工作模式

(1) 默认 RTC 时间:23 时 59 分 50 秒;
(2) 默认温度数据采集间隔 1 秒;
(3) 设备在不同的显示界面下,与界面无关的按钮无效;
(4) 最大存储容量的温度数据:10 个

2、试题分析

实时钟DS1302:记住一些细节的变化(根据官方库文件修改):



此外,还添加了实时钟初始化函数和读取函数。
对于DS18B02(温度获取函数):
unsignedcharget_wendu(){ unsignedchartemp,high,low; Init_DS18B20(); Write_DS18B20(0XCC); Write_DS18B20(0X44); Delay_OneWire(200); Init_DS18B20(); Write_DS18B20(0XCC); Write_DS18B20(0XBE);  low=Read_DS18B20(); high=Read_DS18B20();  temp=(low>>4)|(high<<4);  returntemp; }

3、代码

ds1302.c

#include"ds1302.h" unsignedchartime[]={50,59,23,0,0,0,00}; /********************************************************************/ /*单字节写入一字节数据*/ voidWrite_Ds1302_Byte(unsignedchardat) { unsignedchari; SCK=0; for(i=0;i<8;i  ) { if(dat&0x01)//等价于if((addr&0x01)==1) { SDA_SET;//#defineSDA_SETSDA=1/*电平置高*/ } else { SDA_CLR;//#defineSDA_CLRSDA=0/*电平置低*/ } SCK_SET; SCK_CLR; dat=dat>>1; } } /********************************************************************/ /*单字节读取字节数据*/ unsignedcharRead_Ds1302_Byte(void) { unsignedchari,dat=0; for(i=0;i<8;i  ) { dat=dat>>1; if(SDA_R)//等价于if(SDA_R==1)#defineSDA_RSDA/*电平读取*/ { dat|=0x80; } else { dat&=0x7F; } SCK_SET; SCK_CLR; } returndat; }  /********************************************************************/ /*向DS1302单字节写入一字节数据*/ voidDs1302_Single_Byte_Write(unsignedcharaddr,unsignedchardat) {  RST_CLR;/*RST脚置低,实现DS1302初始化*/
    SCK_CLR;            /*SCK脚置低,实现DS1302的初始化*/

    RST_SET;            /*启动DS1302总线,RST=1电平置高 */
    addr = addr & 0xFE;  
    Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/   
    Write_Ds1302_Byte((dat/10<<4)|(dat%10));     /*写入数据:dat*/
    RST_CLR;                 /*停止DS1302总线*/
}

/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr) 
{ 
    unsigned char temp,dat1,dat2;
    RST_CLR;            /*RST脚置低,实现DS1302的初始化*/
    SCK_CLR;            /*SCK脚置低,实现DS1302的初始化*/

    RST_SET;    /*启动DS1302总线,RST=1电平置高 */   
    addr = addr | 0x01;  
    Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
    temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/

    dat1=temp/16;
    dat2=temp%16;
    temp=dat1*10+dat2;      
    SD=0;
    return temp;
}

void ds1302_init(){
unsigned char add,i;
add=0x80;
Ds1302_Single_Byte_Write(0x8e,0x00);
for(i=0;i<7;i++)
{
  Ds1302_Single_Byte_Write(add,time[i]);
  add+=2;
}
Ds1302_Single_Byte_Write(0x8e,0x80);  
}

void ds1302_read(){
unsigned char add,i;
add=0x81;
Ds1302_Single_Byte_Write(0x8e,0x00);
for(i=0;i<7;i++)
{
  time[i]=Ds1302_Single_Byte_Read(add);
  add+=2;
}
Ds1302_Single_Byte_Write(0x8e,0x80); 
}

ds1302.h

#ifndef  __DS1302_H__
#define  __DS1302_H__

#include
#include
/********************************************************************/ 
sbit SCK=P1^7;        
sbit SD=P2^3;        
sbit RST=P1^3;
/********************************************************************/ 
/*复位脚*/
#define RST_CLR    RST=0   /*电平置低*/
#define RST_SET    RST=1   /*电平置高*/
/*双向数据*/
#define SDA_CLR    SD=0    /*电平置低*/
#define SDA_SET    SD=1    /*电平置高*/
#define SDA_R    SD  /*电平读取*/    
/*时钟信号*/
#define SCK_CLR    SCK=0   /*时钟信号*/
#define SCK_SET    SCK=1   /*电平置高*/
/********************************************************************/ 
#define ds1302_sec_addr            0x80        //秒数据地址
#define ds1302_min_addr            0x82        //分数据地址
#define ds1302_hr_addr            0x84        //时数据地址
#define ds1302_date_addr        0x86        //日数据地址
#define ds1302_month_addr        0x88        //月数据地址
#define ds1302_day_addr            0x8A        //星期数据地址
#define ds1302_year_addr        0x8C        //年数据地址

#define ds1302_control_addr        0x8Ee       //写保护命令字单元地址
#define ds1302_charger_addr        0x90        //涓电流充电命令字地址             
#define ds1302_clkburst_addr    0xBE        //日历、时钟突发模式命令字地址

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

/********************************************************************/ 
/*单字节写入一字节数据*/
extern void Write_Ds1302_Byte(unsigned char dat);
/********************************************************************/ 
/*单字节读出一字节数据*/
extern unsigned char Read_Ds1302_Byte(void);

/********************************************************************/ 
/********************************************************************/ 
/*向DS1302单字节写入一字节数据*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);

extern unsigned char time[];
extern void ds1302_init();
extern void ds1302_read();

#endif     
/********************************************************************/
//                END FILE
/********************************************************************/

onewire.c

#include "onewire.h"

//单总线延时函数
void Delay_OneWire(unsigned int t)
{
  t=12*t;
  while(t--);
}

//DS18B20芯片初始化
bit Init_DS18B20(void)
{
    bit initflag = 0;
    DQ = 1;
    Delay_OneWire(12);
    DQ = 0;
    Delay_OneWire(80); 
    DQ = 1;
    Delay_OneWire(10); 
    initflag = DQ;    
    Delay_OneWire(5);

    return initflag;
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        DQ = 0;
        DQ = dat&0x01;
        Delay_OneWire(5);
        DQ = 1;
        dat >>= 1;
    }
    Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
    unsigned char i;
    unsigned char dat;

    for(i=0;i<8;i++)
    {
        DQ = 0;
        dat >>= 1;
        DQ = 1;
        if(DQ)
        {
            dat |= 0x80;
        }       
        Delay_OneWire(5);
    }
    return dat;
}

unsigned char get_wendu(){
unsigned char temp,high,low;
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0X44);
Delay_OneWire(200);
Init_DS18B20();
Write_DS18B20(0XCC);
Write_DS18B20(0XBE);

low=Read_DS18B20();
high=Read_DS18B20();

temp=(low>>4)|(high<<4);

return temp;
}

onewire.h

#ifndef _ONEWIRE_H
#define _ONEWIRE_H

#include "stc15f2k60s2.h"

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//IC引脚定义
sbit DQ = P1^4;

//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
unsigned char get_wendu();
#endif

text.c

#include
#include "ds1302.h"
#include "onewire.h"
#define uchar unsigned char
#define uint unsigned int

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar flag1=0;
uchar flag2=0;
uchar led=0;
uchar count=0;
uchar wendu=0;
uchar tt=0;
uchar caiji_wendu[10];
uchar n=0;
uchar jiange=0;
uchar f1,f2,f3,f4,f5,f6,f7,f8;

void delayms(uchar ms);
void delay();
void display12(uchar f1,uchar f2);
void display34(uchar f3,uchar f4);
void display56(uchar f5,uchar f6);
void display78(uchar f7,uchar f8);
void keyscan();
void allinit();
void Time0_init();

void main(){
ds1302_init();
allinit();
Time0_init();

while(1)
{    
    wendu=get_wendu();
    keyscan();
    switch(count)
    {
      case 1:jiange=1;break;
      case 2:jiange=5;break;
      case 3:jiange=30;break;
      case 4:jiange=60;count=0;break;
    }

    if(flag1==0)
    {
      f1=11;f2=11;f3=11;f4=11;f5=11;f6=10;f7=jiange/10;f8=jiange%10;
    }

    if(flag1==1)
     {
        ds1302_read();
        if(time[0]%2==1)
        {
          f1=time[2]/10;f2=time[2]%10;f3=10;
          f4=time[1]/10;f5=time[1]%10;f6=10;
          f7=time[0]/10;f8=time[0]%10;
        }
        else
        {
          f1=time[2]/10;f2=time[2]%10;f3=11;
          f4=time[1]/10;f5=time[1]%10;f6=11;
          f7=time[0]/10;f8=time[0]%10;  
        }
      }
      display12(f1,f2);
      display34(f3,f4);
      display56(f5,f6);
      display78(f7,f8);
   }
}


void keyscan(){
if(P30==0)         //s7
{
  delayms(5);
  if(P30==0)
  {
    flag1=0;
  }
while(!P30);
}

 if(!P31==0)   //s6
{
  delayms(5);
  if(P31==0)
  {
    led=0;
  }
while(!P31);
}

  if(P32==0)      //s5
{
  delayms(5);
  if(P32==0)
  {
    if(flag1==0)
    {
       flag1=1;
       tt=0;
       count=1; 
  }
}
}

 if(P33==0)       //s4
{
   delayms(5);
   if(P33==0)
   {
      count++;
    }
while(!P33);
}

}

void allinit(){
P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
P2=0XC0;P0=0XFF;P2=0XFF;P0=0XFF;
}

void delayms(uchar ms){
uchar i,j,k;
for(k=ms;k>0;k--)
{
   i=12;
   j=169;
   do
   {
     while(j--);
   }
   while(i--);
}
}

void delay(){
uchar i,j;
for(i=10;i>0;i--)
for(j=200;j>0;j--);
}

void display12(uchar f1,uchar f2){
P2=0XC0;P0=0X01;P2=0XFF;P0=tab[f1];
delay();
P2=0XC0;P0=0X02;P2=0XFF;P0=tab[f2];
delay();
}

void display34(uchar f3,uchar f4){
P2=0XC0;P0=0X04;P2=0XFF;P0=tab[f3];
delay();
P2=0XC0;P0=0X08;P2=0XFF;P0=tab[f4];
delay();
}

void display56(uchar f5,uchar f6){
P2=0XC0;P0=0X10;P2=0XFF;P0=tab[f5];
delay();
P2=0XC0;P0=0X20;P2=0XFF;P0=tab[f6];
delay();
}

void display78(uchar f7,uchar f8){
P2=0XC0;P0=0X40;P2=0XFF;P0=tab[f7];
delay();
P2=0XC0;P0=0X80;P2=0XFF;P0=tab[f8];
delay();
}

void Time0_init(){
TMOD=0X01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
EA=1;
ET0=1;
}

void Time0_service() interrupt 1
{
  TH0=(65536-5000)/256;
  TL0=(65536-5000)%256;
  tt++;
  if((tt==jiange*200)&&(flag1==1))
  {
    tt=0;
    caiji_wendu[n]=wendu;
    n++;
    if(n==10)
    {
      n=0;
      led=1;
      flag1=2;
      f1=10;f2=0;f3=0;
      f4=11;f5=11;f6=10;
      f7=caiji_wendu[0]/10;f8=caiji_wendu[0]%10;
    }
  }

  if((flag1==2)&&(tt==200))
    {
      tt=0;
      if(led==1)
      {
      if(flag2==0)
      {
        flag2=1;
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
        P00=0;
      }
      else if(flag2==1)
      {
        flag2=0;
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
        P00=1;
      }
     }
     else if(led==0)
     {
       P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;
       P00=1;
       f1=10;f2=n/10;f3=n%10;
       f4=11;f5=11;f6=10;
       f7=caiji_wendu[n]/10;f8=caiji_wendu[n]%10;
       n++;
       if(n==10)
       {
         flag1=3;
         n=0;
       }
     }
   }
}
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章