回头看我所写的文章,基本都是软件方面的,是个典型的“欺软怕硬”的人。然而,在最开始的时候,我学习的是硬件。在前面文章《我的2013–一起从心开始》一文中写道,我在大一暑假的时候开始了单片机的学习,在大二、大三期间做过些小东西。刚进入程序员的领域的时候,显然是单片机带我入了门。下面我将写写用单片机做过的一些东西,权当纪念。


本文介绍我大一暑假学完单片机后,在大二上学期为参加学校星火杯而完成的作品(最终没有参加比赛)。这个电子制作是关于用单片机显示时间的作品,其功能就用单片机控制LCD、LED来显示时间和温度。


功能描述

  • 显示精确度为0.1摄氏度的温度(低于0摄氏度和高于100摄氏度响铃)
  • 液晶时钟,断电后仍然继续走动,每月误差不到一分钟,无电源可工作10年左右,区分平年和闰年;
  • 指针式时钟(黄灯为时针,红色为分针,最小误差5分钟,整点报时)与考试计时器(计时2两小时)

电子元器件

  • 2个单片机最小系统 (单片机型号为STC89C52)
  • 双色发光二级管
  • 液晶显示屏
  • 按键
  • DS12C887时钟芯片
  • DS18b20温度传感器
  • 蜂鸣器(整点报时)
  • LED数码管(显示温度)

作品展示图

  • 由于所有电路都是由杜邦线连接,所以存在接触不良,导致有时不能正常显示,于是就没有参赛,下图为双色二极管的显示。

  • 下图为用1602液晶显示日期和时间

  • 下图为用数码管来显示温度
  • 下图为作品的布线,简直是乱成一团,要是用PCB就好了。

原文:http://blog.csdn.net/tengweitw/article/details/45895989
作者:nineheadedbird

附录:代码实现

对于硬件来说,给代码不给管脚图没啥意义,不过由于年代久远,我已经找不到当初设计的电路图了。但仍然给出代码图,希望能起到一点点的参考作用。

//--------------------------------温度显示程序 第一个芯片------------------------------------------------------------------//#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned intsbit ds=P2^2;unsigned int te;unsigned char code tabledu[]=
{
0x3f0x060x5b0x4f
0x660x6d0x7d0x07
0x7f0x6f0x770x7c
0x390x5e0x790x71
};
unsigned char code tabledu1[]=
{
0xbf0x860xdb0xcf
0xe60xed0xfd0x87
0xff0xef0xf70xfc
0x390x5e0x790x71
};unsigned char code tablewe[]=
{
0xfe0xfd0xfb0xf70xef0xdf
};void delayxms(unsigned int x)
{
unsigned int ij;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}void delayx2us(unsigned char t)
{
while(--t);
}void dsreset() // 复位
{
ds=1;
_nop_();
ds=0;
delayx2us(200);//注意时间
ds=1;
delayx2us(20);}void writetemp(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
ds = 0;
ds = dat&0x01;
delayx2us(25);
ds = 1;
dat>>=1;
}
delayx2us(25);
}unsigned char readtemp(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
ds = 0; // 给脉冲信号
dat>>=1;
ds = 1; // 给脉冲信号
if(ds)
dat|=0x80;
delayx2us(25);
}
return(dat);
}uint temp()
{
uint ab;
dsreset();
delayxms(1);
writetemp(0xcc);
writetemp(0x44);
delayxms(1);dsreset();
delayxms(1);
writetemp(0xcc);
writetemp(0xbe);
delayx2us(50);
a=readtemp();
b=readtemp();
a=a*10;
te=b*160+a/16;return te;
}void disp(long int num)
{
uchar cde;
c=num/100;
d=num%100/10;
e=num%10;P0=tabledu[c];
P1=0xfe;
delayxms(6);
P0=tabledu1[d];
P1=0xfd;
delayxms(6);
P0=tabledu[e];
P1=0xfb;
delayxms(6);
P0=0xcc;
P1=0xf7;
delayxms(2);}void main()
{while(1)
{
disp(temp());
if((temp()>=1000)||(temp()<=0))
beep=0;
else
beep=1;}//--------------------------------时钟显示程序 第二个芯片------------------------------------------------------------------//
#include<reg52.h>#define uchar unsigned char
#define uint unsigned int//流水灯锁存器
sbit wela1=P2^0;//1
sbit wela2=P2^1;//2
sbit wela3=P2^2;//1
sbit wela4=P2^3;//2//蜂鸣器
sbit beep=P2^4;//按键
sbit key1=P2^5;//功能选择键
sbit key2=P2^6;//+(时间、日期加)
sbit key3=P2^7;//-(时间、日期减)
sbit key4=P3^7;//模式键(平时或考试)//液晶接口
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit lcdwr=P3^6;//ds12c887接口
sbit dscs=P1^6;
sbit dsas=P1^7;
sbit dsrw=P3^0;
sbit dsds=P3^1;
sbit dsirq=P3^3;//定义变量
uchar hour minseccountriweekyuenianj;
//uchar counthcountmcountycountkloop1;
uchar code table1[]=" - - ";
uchar code table2[]=" : : ";
uchar code table3[]="SUNMONTUEWEDTHUFRISAT";//延迟函数
void delayxms(unsigned int x)
{
unsigned int ij;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}//--------------------1602液晶函数----------------------------------//液晶写命令
void write_com(unsigned char com)
{
lcdrs=0;
P0=com;
delayxms(5);
lcden=1;
delayxms(5);
lcden=0;
}//液晶写数据
void write_data(unsigned char date)
{
lcdrs=1;
P0=date;
delayxms(5);
lcden=1;
delayxms(5);
lcden=0;
}//液晶初始化
void lcdinit()
{
lcdwr=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);}// 液晶显示
void disp()
{
uchar i;write_com(0x80);
for(i=0;i<15;i++)
{
write_data(table1[i]);
delayxms(5);
}
write_com(0x80+0x40);
for(i=0;i<12;i++)
{
write_data(table2[i]);
delayxms(5);
}
}//写时间
void write_sfm(uchar addressuchar shu)
{
uchar shige;
shi=shu/10;
ge=shu%10;
write_com(0x80+0x40+address);
write_data(0x30+shi);
write_data(0x30+ge);
}//写日历
void write_calendar(uchar addressuchar shu)
{
uchar shige;
shi=shu/10;
ge=shu%10;
write_com(0x80+address);
write_data(0x30+shi);
write_data(0x30+ge);
}//-------------------------DS12C887程序----------------------------
//写时钟
void write_ds(uchar adduchar date)
{
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add;
dsas=0;
dsrw=0;
P0=date;
dsrw=1;
dsas=1;
dscs=1;
}//读时钟
uchar read_ds(uchar add)
{
uchar ds_date;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
dsas=0;
dsds=0;
P0=0xff;
ds_date=P0;
dsds=1;
dsas=1;
dscs=1;
return ds_date;
}//写星期
void write_week(uchar date)
{write_com(0x80+12);
write_data(table3[3*date]);
write_data(table3[3*date+1]);
write_data(table3[3*date+2]);
}//键盘检测
void keyscan() //键盘检测 key1 为功能键 key2为加 key3为减 :时间与日期的改变
{if(key1==0)
{
delayxms(10);
if(key1==0)
{
while(!key1);
count++;if(count==1)
{write_com(0x80+0x40+11);
write_com(0x0f);}if(count==2)
{write_com(0x80+0x40+8);
write_com(0x0f);}if(count==3)
{write_com(0x80+0x40+5);
write_com(0x0f);}
if(count==4)
{
write_com(0x80+13);
write_com(0x0f);
}
if(count==7)
{
write_com(0x80+10);
write_com(0x0f);
}
if(count==6)
{
write_com(0x80+7);
write_com(0x0f);
}
if(count==5)
{
write_com(0x80+4);
write_com(0x0f);
}if(count==8)
{count=0;
write_com(0x0c);
write_ds(0sec);
write_ds(2min);
write_ds(4hour);
}
}
}if(key2==0)
{
delayxms(10);
if(key2==0)
{
while(!key2);
if(count==1)
{
sec++;
if(sec==60)
sec=0;
write_ds(0sec);
write_sfm(10sec);
write_com(0x80+0x40+11);
}if(count==2)
{
min++;
if(min==60)
min=0;
write_ds(2min);
write_sfm(7min);
write_com(0x80+0x40+8);
}if(count==3)
{
hour++;if(hour==24)
hour=0;
write_ds(4hour);
write_sfm(4hour);
write_com(0x80+0x40+5);
}if(count==4)
{
week++;
if(week==7)
week=0;
write_week(week);
write_ds(6week);}if(count==5)
{
nian++;
if(nian==100)
nian=0;
write_ds(9nian);
write_calendar(3nian);
write_com(0x80+4);
}if(count==6)
{
yue++;
if(yue==13)
yue=1;
write_ds(8yue);
write_calendar(6yue);
write_com(0x80+7);
}if(count==7) // 判断闰年
{
ri++;
week++;
if(nian%4==0)
{
if((yue==4)||(yue==6)||(yue==9)||(yue==11))
{
if(ri==31)
ri=1;
}
else if(yue==2)
{
if(ri==30)
ri=1;
}
else
{
if(ri==32)
ri=1;
}
}if(nian%4!=0)
{
if((yue==4)||(yue==6)||(yue==9)||(yue==11))
{
if(ri==31)
ri=1;
}
else if(yue==2)
{
if(ri>=29)
ri=1;
}
else
{
if(ri==32)
ri=1;
}
}
write_ds(7ri);
write_calendar(9ri);
write_com(0x80+10);
delayxms(2);
if(week==7)
week=0;
write_week(week);
write_ds(6week);}}
}if(key3==0)
{
delayxms(10);
if(key3==0)
{
while(!key3);
if(count==1)
{
if(sec==0)
sec=59;
else
sec--;
write_ds(0sec);
write_sfm(10sec);
write_com(0x80+0x40+11);
}if(count==2)
{
if(min==0)
min=59;
else
min--;
write_ds(2min);
write_sfm(7min);
write_com(0x80+0x40+8);
}if(count==3)
{
if(hour==0)
hour=23;
else
hour--;
write_ds(4hour);
write_sfm(4hour);
write_com(0x80+0x40+5);
}
if(count==5)
{if(nian==0)
nian=99;
else
nian--;
write_ds(9nian);
write_calendar(3nian);
write_com(0x80+4);}
if(count==6)
{if(yue==1)
yue=12;
else
yue--;
write_ds(8yue);
write_calendar(6yue);
write_com(0x80+7);
}if(count==7) // 判断闰年
{
ri--;
week--;
if(nian%4==0)
{
if((yue==4)||(yue==6)||(yue==9)||(yue==11))
{
if(ri==0)
ri=30;
}
else if(yue==2)
{
if(ri==0)
ri=29;
}
else
{
if(ri==0)
ri=31;
}
}if(nian%4!=0)
{
if((yue==4)||(yue==6)||(yue==9)||(yue==11))
{
if(ri==0)
ri=30;
}
else if(yue==2)
{
if(ri==0)
ri=28;
}
else
{
if(ri==0)
ri=31;
}
}
write_ds(7ri);
write_calendar(9ri);
write_com(0x80+10);
delayxms(2);
if(week==-1)
week=7;
write_week(week);
write_ds(6week);}}
}
}//----------------初始化---------------------------------//
void init()
{
lcdinit();disp();
week=0;
nian=11;
yue=9;
ri=1;}//---------------------------流水灯-----------------------------------//
void lampinit()
{
P1=0xff;
wela1=1;
wela2=1;
wela3=1;
wela3=1;
wela1=0;
wela2=0;
wela3=0;
wela4=0;}
//----------------时钟用黄灯显示程序-------------------------------//
void clock()
{
if((hour==1)&&(hour==13))
{
P1=0xfd;
wela3=1;
wela3=0;
}if((hour==2)&&(hour==14))
{
P1=0xfb;
wela3=1;
wela3=0;
}if((hour==3)&&(hour==15))
{
P1=0xf7;
wela3=1;
wela3=0;
}if((hour==4)&&(hour==16))
{
P1=0xef;
wela3=1;
wela3=0;
}
if((hour==5)&&(hour==17))
{
P1=0xdf;
wela3=1;
wela3=0;
}
if((hour==6)&&(hour==18))
{
P1=0xfe;
wela4=1;
wela4=0;
}
if((hour==7)&&(hour==19))
{
P1=0xfd;
wela4=1;
wela4=0;
}
if((hour==8)&&(hour==20))
{
P1=0xfb;
wela4=1;
wela4=0;
}
if((hour==9)&&(hour=21))
{
P1=0xf7;
wela4=1;
wela4=0;
}
if((hour==10)&&(hour==22))
{
P1=0xef;
wela4=1;
wela4=0;
}
if((hour==11)&&(hour==23))
{
P1=0xdf;
wela4=1;
wela4=0;
}
if((hour==12)&&(hour==0))
{
P1=0xfe;
wela3=1;
wela3=0;
}if(min<5)
{
if((hour!=12)&&(hour!=24))
{
P1=0xfe;
wela1=1;
wela1=0;
}
}
//----------------分钟用红灯显示------------------------//if((min>=5)&&(min<10))
{
if((hour!=13)&&(hour!=1))
{
P1=0xfd;
wela1=1;
wela1=0;
}
}if((min>=10)&&(min<15))
{
if((hour!=14)&&(hour!=2))
{
P1=0xfb;
wela1=1;
wela1=0;
}
}if((min>=15)&&(min<20))
{
if((hour!=15)&&(hour!=3))
{
P1=0xf7;
wela1=1;
wela1=0;
}
}if((min>=20)&&(min<25))
{
if((hour!=16)&&(hour!=4))
{
P1=0xef;
wela1=1;
wela1=0;
}
}if((min>=25)&&(min<30))
{
if((hour!=17)&&(hour!=5))
{
P1=0xdf;
wela1=1;
wela1=0;
}
}if((min>=30)&&(min<35))
{
if((hour!=18)&&(hour!=6))
{
P1=0xfe;
wela2=1;
wela2=0;
}
}if((min>=35)&&(min<40))
{
if((hour!=19)&&(hour!=7))
{
P1=0xfd;
wela2=1;
wela2=0;
}
}if((min>=40)&&(min<45))
{
if((hour!=20)&&(hour!=8))
{
P1=0xfb;
wela2=1;
wela2=0;
}
}if((min>=45)&&(min<50))
{
if((hour!=21)&&(hour!=9))
{
P1=0xf7;
wela2=1;
wela2=0;
}
}if((min>=50)&&(min<55))
{
if((hour!=22)&&(hour!=10))
{
P1=0xef;
wela2=1;
wela2=0;
}
}
if(min>=55)
{
if((hour!=23)&&(hour!=11))
{
P1=0xdf;
wela2=1;
wela2=0;
}
}}
//---------------考试倒计时模式-----------------------//void test()
{
uchar hour1min1min2shi;
hour1=hour+2;
if(hour==24)
hour1=0;
if(hour==25)
hour1=1;min1=min+20;
if(min1>=60)
{
min1=min1-60;
hour1=hour1+1;
if(hour1==24)
hour1=0;
}shi=min1/10;
min1=shi*10;if((min==min1)&&(sec==0))
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xfe;
wela3=1;
wela3=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xfc;
wela1=1;
wela1=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xf8;
wela1=1;
wela1=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xf0;
wela1=1;
wela1=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xe0;
wela1=1;
wela1=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xc0;
wela1=1;
wela1=0;}
//-------------------------------------------------//
if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xfe;
wela2=1;
wela2=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xfc;
wela2=1;
wela2=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xf8;
wela2=1;
wela2=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xf0;
wela2=1;
wela2=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xe0;
wela2=1;
wela2=0;}if(min==min2)
{
min2=min+5;
if(min2==60)
min2=0;
P1=0xc0;
wela2=1;
wela2=0;}
//----------------------时间到后开始响铃------------------------------------------//
if(min==min2)
{P1=0;
wela1=1;
wela1=0;
beep=0;
delayxms(1000);
beep=1;
delayxms(1000);
beep=0;
delayxms(1000);
beep=1;
beep=0;
delayxms(1000);
beep=1;
delayxms(1000);
beep=0;
delayxms(6000);
delayxms(6000);
beep=1;lampinit();}
}//-----------------主函数--------------------------------------//
void main()
{
init();
while(1)
{keyscan();if(count==0)
{
sec=read_ds(0);
min=read_ds(2);
hour=read_ds(4);
week=read_ds(6);
nian=read_ds(9);
yue=read_ds(8);
ri=read_ds(7);
write_sfm(10sec);
write_sfm(7min);
write_sfm(4hour);
write_week(week);write_calendar(3nian);
write_calendar(6yue);
write_calendar(9ri);
write_calendar(120);}}}

【单片机】时钟及温度的显示相关推荐

  1. RTX51tiny 复杂应用---时钟、温度显示、按键解析

    keil工程下载地址:https://www.syjshare.com/res/3SXA00Q9 一.设计需求 在清翔51单片机开发板上,用带RTOS的方式实现下面的功能: 1. 板上有8个段码LED ...

  2. 基于51单片机万年历可调电子时钟闹钟温度(实物图+源码+仿真+原理图+论文)

     资料编号:038 硬件构成:51单片机+最小系统+LCD1602液晶显示模块+时钟模块+温度采集模块+蜂鸣器模块+按键模块 1.采用LCD1602液晶屏显示.DS1302时钟芯片和DS18B20温度 ...

  3. 基于单片机病房呼叫系统数码管显示房号设计-基于单片机工业生产现场的光照强度控制设计-基于单片机多功能智能台灯设计-基于单片机二维码LCD显示设计-基于单片机多功能时钟闹钟万年历控制系统设计【毕设分享】

    1641基于单片机病房呼叫系统数码管显示房号设计 设计思路:此设计实现的功能通过按键模拟房号,当按键按下时会将房号编号发送到数目管上进行显示,并通过声光进行提示.包含的电路有:数码管显示电路.按键电路 ...

  4. 单片机读取多路温度c语言,以51单片机为内核实现了两路温度采集与显示的温度控制器设计...

    1.引言 目前,温度控制器存在的问题是如何缩减成本,减少功耗,温度测量的准确性和多路温度的同时显示.本方案设计的实现基于C51单片机的两路温度控制器,做到成本最低化,精确度高,两路温度的显示和控制,能 ...

  5. c51时钟数码管显示流程图_基于单片机89C51的数码管显示时钟设计.doc

    基于单片机89C51的数码管显示时钟设计 基于单片机的数字时钟 摘 要单片机在多功能数字钟中的应用已是非常普遍的,人们对数字钟的功能及工作顺序都非常熟悉.但是却很少知道它的内部结构以及工作原理.由单片 ...

  6. STC单片机LCD1602四线驱动模式显示ADC采样电压和温度

    STC单片机LCD1602四线驱动模式显示ADC采样电压和温度

  7. Protues 基于51单片机的DS18B20温度采集:键盘输入温度上下限_超出设定温度范围报警_8数码管显示

    功能实现: 1.设计单片机与16按键的矩阵式键盘接口以及8数码管的接口电路,测试显示和按键功能. 2.设计单片机与DS18B20的接口电路,实现数字温度信息的采集,然后编程处理采集到的数据,得到温度值 ...

  8. 基于51单片机的时钟闹钟温度计LCD1602显示proteus仿真原理图PCB

    功能介绍: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示时间/当前温度 2.按键可进行闹钟设置和温度上下限设置 3.到达闹钟时间或温度超过阈值范围,蜂鸣器报警 4.到达闹钟 ...

  9. 51单片机计算器_基于51单片机的倒计时温度检测报警器

    基于51单片机的倒计时温度检测报警器 学习单片机断断续续半年了,在学长学姐的教学帮助下,完成了51单片机的入门学习,开始实践做项目,在一周时间内设计和制作出个人项目.起初,我设计和选择的是12864显 ...

最新文章

  1. python3.7.1安装教程详细_CentOS 7 安装python3.7.1的方法及注意事项
  2. 单链表-删除单链表L中第一个值为x的结点(双指针法)
  3. transmit failed error code:65
  4. python装饰器原理-Python装饰器原理与用法分析
  5. 直接管理内存——new和delete
  6. RedHat Linux 启动FTP
  7. Python: try finally 与 上下文管理器简介
  8. Magento首页不显示产品
  9. 自动控制原理第七版胡寿松pdf_自动控制原理简明笔记—(01)
  10. 会计计算机学什么软件有哪些,会计一般要学什么软件
  11. MySQL笔记: B站宋红康最新教程 (持续更新中)
  12. iphone5处理屏幕分辨率
  13. 【论文模型讲解】Vision Transformer
  14. detached entity passed to persist:xxx;
  15. 【转】脸识别技术发展及实用方案设计
  16. 整数规划(分支定界、匈牙利法)
  17. 【牛客刷题】上手用C语言写一个三子棋小游戏超详解哦(电脑优化)
  18. vscode好看的吸血鬼主题设置
  19. 大学计算机基础第三章试题,大学计算机基础理论知识前三章测试题.docx
  20. notepad转换json_Notepad++的Json格式化插件

热门文章

  1. 本地同城地方门户网这样运营轻轻松松拿到5W广告费
  2. 安装驱动显卡重启计算机,win7系统安装显卡驱动后电脑一直重启的解决方法
  3. 中文zh描述规则,原来中文下除了cmn外还有14种扩展
  4. OneNMP路由器、交换机监控
  5. 【JavaWeb学习】CSS(选择器)
  6. Luat Inside | 多功能YAP物联网终端机,你不会还不知道吧?
  7. 抖音自动人机拼图验证-selenium+pyautogui+opencv
  8. 关于无法连接到报表服务器http://localhost/reportserver的解决方案
  9. ACM-ICPC 2017 Asia QingDao:喜,抑或是悲?幸运,抑或是倒霉?退役!!!
  10. SmallJava V2.0 产品说明书(20210405)