基于蓝桥杯单片机的温度与时钟基础显示

在蓝桥杯单片机中ds1302和ds18b20作为两个常考的模块其基础的应用十分重要。

这种写法适合c语言基础较为薄弱的同学。前面为讲解,后面为例程代码。

先看ds18b20

首先,通过官方给出的驱动,我们首先需要将#include <reg52.h>的头文件换成蓝桥杯单片机的

#include <STC15F2K60S2.H>的头文件,由于蓝桥杯单片机的运行环境是51的12倍,故我们需要将单总线延时函数扩大12倍。

改为

由于蓝桥杯单片机上只有一个ds18b20,通过手册,如图

我们可以知道温度转换的过程,可以将温度转化的函数补充完整。

此时读出的温度是十六进制数,我们需要将其转化为十进制数方便显示。

DS18B20的分辨率为0.0625。读出数据为正温度时,将LSB和MSB整合成的16位整数,直接乘以0.0625即可。读出数据为负温度时,则需要将LSB和MSB整合成的16位整数,取反加1后,再乘以0.0625。

保留两位小数---*0.0625

保留一位小数---*0.625

保留整数---*6.25

2.时钟(ds1302)

通过官方给出的驱动,我们首先需要将#include <reg52.h>的头文件换成蓝桥杯单片机的

#include <STC15F2K60S2.H>的头文件.

通过ds1302的手册

首先补充时钟读取函数

通过for循环不断对时分秒年月日星期去读取。

补充时钟设置函数

除了正常操作以外设置时钟时还需要先关闭写保护

ds1302的使用

首先需要在主函数中定义一个数组存储当前的时间

因为ds1302中时间是以二进制的形式存在的,所以数组里的时间也是以二进制的形式存在的。

然后在主函数中调用设置时钟函数,将数组中的时间存入ds1302中,完成时钟的初始化。

最后调用读取函数,读取ds1302中的时间,并将其转化为十进制,在数码管上显示。

下面是具体的应用,通过读取·ds18b20,ds1302,完成温度,时分秒,年月日的界面显示,并且界面3秒自动切换

main.c

#include <STC15F2K60S2.H>
#include <intrins.h>
/*************头文件的调用***********************/
#include "ds1302.h"
#include "onewire.h"

#define uc unsigned char
#define ui unsigned int
/****************时间时间的存放***********/
uc tac[7]={0x50,0x35,0x11,0x16,0x03,0x04,0x23};
/***********打开所需要的通道*********/
#define COM(X)  {P0 = X; P2 = (P2 & 0x1F | 0xC0);  P2 &= 0x1F;}
#define SEG(X)  {P0 = X; P2 = (P2 & 0x1F | 0xE0);  P2 &= 0x1F;}
#define BUZ(X)  {P0 = X; P2 = (P2 & 0x1F | 0xA0);  P2 &= 0x1F;}
#define LED(X)  {P0 = X; P2 = (P2 & 0x1F | 0x80);  P2 &= 0x1F;}
/***********数码管显示数组********************/
uc code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc6,0x8e,0x8C,0xC1,0x86,0xbf,0x88};//0-9,C,F,P,U,E,-
//10-C
//11-F
//12-P
//13-U
//14-E
//15--
/*************界面切换时的变量***********/
xdata uc k;
xdata ui count;
/**************延时函数*************/
void Delay100us()        //@12.000MHz
{
    unsigned char i, j;

    i = 2;
    j = 39;
    do
    {
        while (--j);
    } while (--i);
}
void Delay750ms()        //@12.000MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 35;
    j = 51;
    k = 182;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}
/*************数码管显示函数******************/
void OutputSMG(uc gqb,uc yxl)
{
 uc i;
 for(i=0;i<8;i++)
 {
 SEG(0xff);
 COM(0x01<<gqb);
 SEG(yxl);
 Delay100us();
 }
 COM(0x00);
 SEG(0x00);
}
/*******************时分秒显示函数**********/
void smg_SFM()
{
  uc F,S,M;
  readtime(tac);
  S=(tac[2]>>4)*10+(tac[2]&0X0F);//十六进制转十进制
  F=(tac[1]>>4)*10+(tac[1]&0X0F);//十六进制转十进制
  M=(tac[0]>>4)*10+(tac[0]&0X0F);//十六进制转十进制
  OutputSMG(0,tab[S/10]);
  OutputSMG(1,tab[S%10]);
  OutputSMG(2,tab[15]);//-
  OutputSMG(3,tab[F/10]);
  OutputSMG(4,tab[F%10]);
  OutputSMG(5,tab[15]);//-
  OutputSMG(6,tab[M/10]);
  OutputSMG(7,tab[M%10]);
}
/*******************年月日显示函数**********/
void smg_RYN()
{
  uc R,Y,N;
  readtime(tac);
  R=(tac[3]>>4)*10+(tac[3]&0X0F);
  Y=(tac[4]>>4)*10+(tac[4]&0X0F);
  N=(tac[6]>>4)*10+(tac[6]&0X0F);
  OutputSMG(0,tab[N/10]);
  OutputSMG(1,tab[N%10]);
  OutputSMG(2,tab[15]);//-
  OutputSMG(3,tab[Y/10]);
  OutputSMG(4,tab[Y%10]);
  OutputSMG(5,tab[15]);//-
  OutputSMG(6,tab[R/10]);
  OutputSMG(7,tab[R%10]);
}
/*******************温度显示函数**********/
void smg_wd()
{
  ui temp;
  temp=rd_temperature(); 
  temp=temp*0.625;
  OutputSMG(5,tab[temp/100]);
  OutputSMG(6,(tab[temp/10%10]&0x7f));
  OutputSMG(7,tab[temp%10]);
}
/*******************定时器2函数用于界面切换**********/
void Timer2Init(void)        //500微秒@12.000MHz
{
    AUXR |= 0x04;        //定时器时钟1T模式
    T2L = 0x90;        //设置定时初值
    T2H = 0xE8;        //设置定时初值
    AUXR |= 0x10;        //定时器2开始计时
    IE2|=0X04;
    EA=1;
}
void tim2()interrupt 12
{
   count++;
  if(count==4000)
  {
   count=0;
   k++;
  if(k>2)
  {k=0;}
  }
}
/************用于消除温度开机时的85显示*************/
void ds18b20_xxx()
{
   Delay750ms();
   rd_temperature();
}
/*******主函数********/
void main()
{
  LED(0XFF);
  BUZ(0X00);
 ds18b20_xxx();
 savetime(tac);
 Timer2Init();
  while(1)
  {
  switch(k)//界面切换
  {
  case 0:smg_RYN();break;//年月日
  case 1:smg_wd();break;//温度
  case 2:smg_SFM();break;//时分秒
  }
  }
}

ds18b20.c

/*
  程序说明: 单总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
  日    期: 2011-8-9
*/
#include "onewire.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //扩大12倍
{
  unsigned int i;
    while(t--)
  {for(i=0;i<12;i++);}
}

//通过单总线向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;
}

//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;
}
unsigned int rd_temperature(void)//自己补的温度读取函数
{
   unsigned int H,L;
   init_ds18b20();
   Write_DS18B20(0xcc);
   Write_DS18B20(0x44);
   Delay_OneWire(80);
   init_ds18b20();
   Write_DS18B20(0xcc);
   Write_DS18B20(0xbe);
   L=Read_DS18B20();
   H=Read_DS18B20();
   return (H<<8)+L;
} 

ds18b20.h

#ifndef __ONEWIRE_H
#define __ONEWIRE_H

#include <STC15F2K60S2.H>//改成15的头文件
#include <intrins.h>

unsigned int rd_temperature(void); 

#endif

ds1302.c

/*
  程序说明: DS1302驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include <STC15F2K60S2.H>
#include <intrins.h>

sbit SCK=P1^7;        
sbit SDA=P2^3;        
sbit RST = P1^3;   // DS1302复位                                                

void Write_Ds1302(unsigned  char temp) 
{
    unsigned char i;
    for (i=0;i<8;i++)         
    { 
        SCK=0;
        SDA=temp&0x01;
        temp>>=1; 
        SCK=1;
    }
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;     _nop_();  
     Write_Ds1302(address);    
     Write_Ds1302(dat);        
     RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
     unsigned char i,temp=0x00;
     RST=0;    _nop_();
     SCK=0;    _nop_();
     RST=1;    _nop_();
     Write_Ds1302(address);
     for (i=0;i<8;i++)     
     {        
        SCK=0;
        temp>>=1;    
         if(SDA)
         temp|=0x80;    
         SCK=1;
    } 
     RST=0;    _nop_();
     SCK=0;    _nop_();
    SCK=1;    _nop_();
    SDA=0;    _nop_();
    SDA=1;    _nop_();
    return (temp);            
}

void readtime(unsigned char *time)
{
    unsigned char i=0;
    unsigned char dat=0x81;
    for (i=0;i<7;i++) 
    {
       *(time+i)=Read_Ds1302_Byte (dat); //i对应的是偏移量
       dat=dat+2;
    }
}
void savetime(unsigned char *Time)
{
     unsigned char i=0;
    unsigned char dat=0x80;
    Write_Ds1302_Byte(0x8e,0x00);//禁止写保护  
    for (i=0;i<7;i++) 
    {
       Write_Ds1302_Byte( dat, *(Time+i) );   
       dat=dat+2;
    }
       Write_Ds1302_Byte(0x8e,0x80);//启用写保护  
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void readtime(unsigned char *time);
void savetime(unsigned char *Time);

#endif

如果对你有所帮助,还请点赞哦!

谢谢大家

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐诗宋詞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值