单片机 温度实训报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机实训报告
题目 : 1602显示万年历和温度系部 :
专业:
班级:
姓名 :
学号 :
指导教师 :
2011年12月15日
目录
一、引言 (3)
1.1、意义 (3)
1.2、系统功能 (3)
1.3、成员工作 (3)
二、使用硬件 (4)
三、使用原理图 (5)
四、完成万年历和温度的程序 (7)
五、感悟 (14)
六、致谢 (15)
七、参考文献 (16)
八、老师的评语 (16)
引言
1.1、意义
目前单片机的应用可以说是相当的广泛,已经渗透到我们生活中的各个领域。

从高端导弹的导航装置,飞机上各种仪表的控制,自动控制领域的机器人,以及自动化过程的实时和数据处理,到我们日常生活的各种智能IC卡系统,安全保障系统,录象机,摄象机,手机,电视,以及可控玩具,等等,都是单片机“惹的祸”。

而且,目前我国的单片机教育已经向高中教育发展,可见在不久的将来,单片机对于工科学生而言就会象电路基础原理一样成为基础课。

所以我们要跟着时代的步伐前进,学好单片机。

1.2、系统功能
在单片机中,基本上有三类信息在流动,一类是数据,即各种原始数据1、中间结果、程序等。

这样要由外部设备通过“口”进入单片机,再存放在存贮器中,在运算处理过程中,数据从存贮器读入运算器进行运算,运算的中间结果要存入存贮器中,或最后由运算器经“出入口”输出。

用户要单片机执行的各种命令(程序)也以数据的形式由存贮器送入控制器,由控制器解读(译码)后变为各种控制信号,以便执行如加、减、乘、除等功能的各种命令。

所以,这一类信息就称为控制命令,即由控制器去控制运算器一步步地进行运算和处理,又控制存贮器的读(取出数据)和写(存入数据)等。

所以芯片就达到某种功能,就给设备带来效果。

1.3、成员工作
写程序:张俊兵
调试:张俊兵
设计报告:张俊兵
使用硬件
单片机18b20
LCD1602
USB供电线串口线
使用原理图1.1、单片机使用的原理图
1.2、仿真图
完成万年历和温度的程序#include<reg52.h>
#include<intrins.h>
#include<DS18B20.h>
sbit RS=P0^0;
sbit E=P0^2;
sbit RW=P0^1;
sbit BEEP=P1^7;
#define Data P2
#define KEY P3
#define uchar unsigned char
int hour,min,sec,tcnt,a,h,m,day,month,yearl,yearh;
int z,j;
#define NO_key 0x7f
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt;
uscnt=us>>1;
while(--uscnt);
}
void DelayMs(unsigned char ms)//delay Ms
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
void WriteCommand(unsigned char c)
{
DelayMs(5);//short delay before operation
E=0;
RS=0;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
}
void WriteData(unsigned char c)
{
DelayMs(5); //short delay before operation
E=0;
RS=1;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
RS=0;
}
void InitLcd()
{
DelayMs(15);
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动位置
WriteCommand(0x0c); //显示开及光标设置
WriteCommand(0x01); //显示清屏
}
int set_xy(int x,int y)//to set current position {
if((y<0)|(y>1)|(x<0)|(x>15))
return 0;
else
{
if(y==0)
{
WriteCommand(0x80+x);
}
else
{
WriteCommand(0xc0+x);
}
}
return 1;
}
int wr_char(unsigned char dat,int x,int y)
{
if(!set_xy(x,y))//write a char to some position return 0;
WriteData(dat);
return 1;
}
int wr_str(unsigned char *str,int x,int y)
{
if(!set_xy(x,y))
return 0;//to write a string to some position while(*(str++))
WriteData(*(str-1));
return 1;
}
int wr_int1(int num,int x,int y)
{
unsigned char seg[1];
if(!set_xy(x,y))
return 0;
if(num<0)
{
WriteData('-');
num=-num;
}
seg[0]=num;
WriteData(seg[0]+'0');
return 1;
}
int wr_int(int num,int x,int y)
{
unsigned char seg[2];
if(!set_xy(x,y)) //to write a interger to some position return 0;
if(num<0)
{
WriteData('-');
num=-num;
}
seg[1]=num/10;
num=num%10;
seg[0]=num;
WriteData(seg[1]+'0');
WriteData(seg[0]+'0');
return 1;
}
void delay(unsigned int cnt)
{
while(--cnt);
}
unsigned char Key_Scan(void)
{
unsigned char i,n;
unsigned char key_temp;
KEY=0xf0;
if((KEY&0xf0)!=0xf0)
{
delay(10000);
if((KEY&0xf0)!=0xf0)
{
for(i=0;i<4;i++)
{
KEY=~(1<<i);
n=KEY;
n&=0xf0;
if(n!=0xf0)
{
switch(n)
{
case(0x70):key_temp=15-(3-i)*4;break;
case(0xb0):key_temp=14-(3-i)*4;break;
case(0xd0):key_temp=13-(3-i)*4;break;
case(0xe0):key_temp=12-(3-i)*4;break;
default:key_temp=NO_key;
}
return key_temp;
}
}
}
}
return NO_key;
}
void check_wendu(void)
{
unsigned int b,c,d;
d=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差b=d/100; //计算得到十位数字
c=d/10-b*10; //计算得到个位数字
z=d/10; //计算得到整数位
j=d-b*100-c*10; //计算得到小数位
if(z<0){z=0;j=0;} //设置温度显示上限
if(z>99){z=99;j=9;} //设置温度显示上限
}
main()
{
unsigned char opear;
InitLcd();
DelayMs(15);
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
wr_str(" : : ",0,0);
wr_str(" : ",0,1);
wr_str(" - - ",6,1);
wr_str(" . ",9,0);
while(1)
{
opear=Key_Scan();
if(opear!=NO_key)
{
switch(opear)
{
case(0):hour++;
if(hour==24)
{
hour=0;
day++;
}
wr_int(hour,0,0);
break;
case(1):min++;
if(min==60)
{
min=0;
hour++;
}
wr_int(min,3,0);
break;
case(2):h++;if(h==24)h=0;wr_int(h,0,1);break; case(3):m++;
if(m==60)
{
m=0;
h++;
}
wr_int(m,3,1);
break;
case(4):day++;
if(day==31)
{
day=0;
month++;
}
wr_int(day,14,1);
break;
case(5):month++;
if(month==13)
{
month=1;
yearl++;
}
wr_int(month,11,1);
break;
case(6):yearl++;
if(yearl==100)
{
yearl=0;
yearh++;
}
wr_int(yearl,8,1);
break;
case(7):yearh++;
if(yearh==100)
{
yearh=20;
}
break;
}
}
if(hour==h&&min==m)
{
BEEP=0;
}
else
{
BEEP=1;
}
if(a==1)
{a=0;
check_wendu();
if(z<99&&j<9)
{
wr_int(z,9,0);
wr_int1(j,12,0);
}
wr_int(yearh,6,1);
wr_int(yearl,8,1);
wr_int(month,11,1);
wr_int(day,14,1);
wr_int(hour,0,0);
wr_int(min,3,0);
wr_int(sec,6,0);
wr_int(h,0,1);
wr_int(m,3,1);
}
}
}
void t0 (void)interrupt 1 using 0
{
tcnt++;
if(tcnt==4000)
{
tcnt=0;
sec++;
a=1;
wr_int(sec,6,0);
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hour++;
if(hour==24)
{
hour=0;
day++;
if(month==2&&((yearl==0&&yearh%4==0)||(yearl!=0&&yearh%4==0))&&day==30)day=1;
else if(month==2&day==29)day=1;
else if((month==4||month==6||month==9||month==11)&&day==31)day=1;
else if(day==32)day=1;
if(day==1)
{
month++;
if(month==13)
{
month=1;
yearl++;
if(yearl==100)
yearl=0;
yearh++;
if(yearh==100)
yearh=20;
}
}
}
}
}
}
}
DS18B20调用的程序:
#ifndef __DS18B20_H__
#define __DS18B20_H__
#include <reg52.h>
sbit DQ=P3^7; //定义DS18B20总线I/O
/*****延时子程序*****/
void Delay_DS18B20(int num)
{
while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
Delay_DS18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay_DS18B20(80); //精确延时,大于480us
DQ = 1; //拉高总线
Delay_DS18B20(14);
x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败 Delay_DS18B20(20);
}
/*****读一个字节*****/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
Delay_DS18B20(4);
}
return(dat);
}
/*****写一个字节*****/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delay_DS18B20(5);
DQ = 1;
dat>>=1;
}
}
/*****读取温度*****/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
t=b;
t<<=8;
t=t|a;
tt=t*0.0625;
t= tt*10+0.5; //放大10倍输出并四舍五入
return(t);
}
感悟
当今时代,是一个新技术层出不穷的时代。

在电子领域,尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统正以前所未见的速度被单片机智能控制系统所取代。

大部分的高等工科学校都已开设了单片机课程。

单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。

目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。

过去习惯于传统电子领域的工程师、技术员正面临着全新的挑战,如不能在较短时间内学会单片机,势必会被时代所遗弃,只有勇敢地面对现实,挑战自我,加强学习,争取在较短的时间内将单片机技术融会贯通,才能跟上时代的步伐。

习单片机并不象学习传统数字电路或模拟电路那样比较直观,原因是除了“硬件”之外还存在一个“软件”的因素。

正是这个“软件”因素的存在,使得许多初学者怎么也弄不懂单片机的工作过程,怎么也不明白为什么将几个数送来送去,就能控制一盏灯亮/灭?能控制一个电机变速?由此对单片机产生一种“神奇”、“敬畏”甚至“恐惧”感,阻碍了学习单片机的热情与兴趣,这就有社会上“单片机难学”一说。

今天我们开始实训,通过C语言编程序,通过ISP软件把程序烧写给AT89C52,能在LCD1602显示时间、闹铃、万年历、温度,在第二天就实现了功能,但还没有达到我想要的要求,在以后,我会加以改正,从而弥补我的缺点。

习单片机的最有效方法是理论与实践并重
对于我来说,如果按教科书式的学法,上来就是一大堆指令、名词,学了半天还搞不清这些指令起什么作用,能够产生什么实际效果,那么也许用不了几天就会觉得枯燥乏味而半途而废。

所以学习与实践结合是一个好方法,边学习、边演练,循序渐进,这样用不了几次就能将用到的指令理解、吃透、扎根于脑海,甚至“根深蒂固”。

也就是说,学习完某几条指令后(一次数量不求多,只求懂),接下去就该做实验了,通过实验,感受刚才的指令产生了控制效果,眼睛看得见(灯光)、耳朵听得到(声音),更能深刻理解指令是怎样转化成信号去控制电子产品的。

说句过分的话,单片机与其说是学出来的,还不如说是做实验练出来的,何况做实验本身也是一种学习过程。

因此边学边练的学习方法,效果特别好,
学习单片机要合理安排学习时间持之以恒
学习单片机可不能“三天打鱼、二天晒网” ,要有持之以恒的毅力与决心,学习完几条指令后,就应及时做实验,融会贯通,而不要等几天或几个星期有时间后再做实验,这样效果不好甚至前学后忘。

另外要有打“持久战” 的心理准备,不要兴趣来时学上几天,无兴趣时凉上几星期。

学习单片机很重要的一点就是持之以恒。

学习单片机要使用循环学习法使之根深蒂固
根据现代科学的研究,对只短暂学过一遍的知识,充其量只比浮光掠影稍好。

因此,较好的方法是,过一段时间后(1~2个月)再重新做一遍,这样反复循环几次就能彻底弄懂消
化,永不忘却。

有道是:若人生能细看《水浒传》10遍,那么里面的故事内容、人物场情将永生不忘。

学习单片机要进行适当投资购买实验器材及书籍资料
进单片机世界的大门里,稍懂硬件原理通过实践能力理解软件的作用,让他们知道在单片机组成的系统中硬件与软件的区分并不绝对,硬件能做的工作一般情况下软件也能完成,软件的功能也可用硬件替代。

感觉到真正找到了一种理想化的器件,真正感受、体会到现代单片机的强大作用,从而投身于单片机的领域中。

只要我肯努力、下功夫、多实践,一定会成功的。

致谢
光阴似箭,岁月如梭。

大二的上学期即将结束了,回想在学院过得生活,在这里让我学到了许许多多的知识,在这里给我带来了许多的快乐。

在这里慢慢让我走出了社会。

在十五周里,单片机实训,老师对我们进行了指导一周.他不仅在理论上进行指导,在实践中帮助我们; 老师在实训中对我们不懂问题,会指导我们, 我们班的大部分的同学都会做,从而使我们达到更高的水平,.我们的同学也是虚心的学习,从而来报效祖国。

在以后,我们要和老师共同面对学习上的问题。

使每个问题弄懂。

在这里说一句,老师,你辛苦了!
参考文献
[1]、51单片机最小系统原理图
[2]、51单片机应用基础的课本
老师的评语。

相关文档
最新文档