单片机实验报告_第1页
单片机实验报告_第2页
单片机实验报告_第3页
单片机实验报告_第4页
单片机实验报告_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、51单片机实验报告学 院 计通学院 专业班级    物联1401     姓    名    廖攀     学    号   41458027          2016年12月一、实验要求:以STC89开发板为硬件平台, 开发温度采集、动态数码管显示、按键响应、与PC串口通讯的综合程序,

2、实现以下功能:1) PC上的串口调试助手通过串口给STC89开发板发送“GetTemp”命令2)  STC89开发板从串口接收到“GetTemp”命令后启动温度传感器DS18B20的测温程序获取当前温度,测试完成时将所测得温度数据显示在动态数码管上。(动态数码管在温度获取之前应该显示“NOTEMP”, 只有在获取温度后才显示温度值)3)  动态数码管显示出温度数据后, 请通过按键触发STC89开发板通过串口回送步骤2所测的温度数据给PC上串口调试助手,同时恢复动态数码管显示为“NOTEMP”。为保证每个同学的实验都独立完成,要求回送的数据包含自己的学号,即如果你的学号是20

3、150809,当前温度值是19.6摄氏度,那么在PC上的串口调试助手应该显示:ID:20150809, Temp:19.6degC.二、程序设计思路:该实验是一个综合实验,需要结合很多的知识来解决。具体来说可以分成这三个方面,第一个方面是用温度传感器DS18B20测量外界的温度,这个课本第十六章有十分详细的操作过程,第二个方面是如何运用串口助手来解决串口问题,第三个方面是实验中会出现一些中断,需要注意很多细节。具体实验过程先使用温度传感器DS18B20测量出外界的温度(可以参考教科书317-321,也可以参考实验课学到的实验16),然后在此基础上运用起串口(可以参考实验课所学到的实验15),最

4、后整合起来,实现所有功能。原理图: CPU管脚电路 晶振电路(2)数码管部分 1、数码管显示(1)数码管的显示原理数码管的显示原理是靠点亮内部的发光二极管来发光,下面就来我们讲解一个数码管是如何亮起来的。数码管内部电路如下图所示,从右图可看出,一位数码管的引脚是10个,显示一个8字需要7个小段,另外还有一个小数点,所以其内部一共有8个小的发光二极管,最后还有一个公共端,生产商为了封装统一,单位数码管都封装10个引脚,其中第3和第8引脚是连接在一起的。而它们的公共端又可分为共阳极和共阴极,中间图为共阴极内部原理图,右图为共阳极内部原理图。上图展出了常用的两种数码管的引脚排列和内部结构。总所周知,

5、点亮发光二极管就是要给予它足够大的正向压降。所以点亮数码管其实也就是给它内部相应的发光二极管正向压降。如上图左(一共a、b、c、d、e、f、g、DP 八段),如果要显示“1”则要点亮b、c 两段LED;显示“A”则点亮a、b、c、e、f、g 这六段LED;我们还知道,既然LED 加载的是正向压降,它的两端电压必然会有高低之分:如果八段LED 电压高的一端为公共端,我们称之为共阳极数码管(如上图中);如果八段LED 电压低的一段为公共端,则称之为共阴极数码管(上图右)。所以,要点亮共阳极数码管,则要在公共端给予高于非公共端的电平;反之点亮共阴极数码管,则要在非公共端给予较高电平。动态显示是多个数

6、码管,交替显示,利用人的视觉暂停作用使人看到多个数码管同时显示的效果。数码管(3)DS18B20温度传感器部分(1)工作原理DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。初始时,温度寄存器被预置成-55,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1,这个过程重复进行,直到计数器2计数到0时便停止。初始时,计数器1预置的是与-55相对应的一个预置值。以后计数器1每一个循环的预置数都由斜率累加器提供。为了补偿振荡器

7、温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1计数器所需要的计数个数。DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25进行比较,若低于0.25,温度寄存器的最低位就置0;若高于0.25,最低位就置1;若高于0.75时,温度寄存器的最低位就进位然后置0。这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5,四舍五入最大量化误差为±1/2LSB,即0.25。温度寄存器中的温度值以9位数据格式

8、表示,最高位为符号位,其余8位以二进制补码形式表示温度值。测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。DS18B20测量温度时使用特有的温度测量技术。DS18B20内部的低温度系数振荡器能产生稳定的频率信号;同样的,高温度系数振荡器则将被测温度转换成频率信号。当计数门打开时,DS18B20进行计数,计数门开通时间由高温度系数振荡器决定。芯片内部还有斜率累加器,可对频率的非线性度加以补偿。测量结果存入温度寄存器中。一般情况下的温度值应该为9位,但因符号位扩展成高8位,所以最后以16位补码形式读出。 (4)串口通信部分(1)串行通信方式串行通

9、信是将数据字节分成一位一位的形式在一条传输线上逐个地传送,此时只需要一条数据线,外加一条公共信号地线和若干控制信号线。因为一次只能传送一位,所以对于一个字节的数据,至少要分S位才能传送完毕。串行通信的必要过程是:发送时,要把并行数据变成串行数据发送到线路上去,接收时,要把串行信号再变成并行数据,这样才能被计算机及其他设备处理。串行通信传输线少,长距离传送时成本低,且可以利用电话网等现成的设备,但数据的传送控制比并行通信复杂。(2)同步串行通信方式我们采用的是同步串行通信的方式,同步通信时要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间隔”的整数

10、倍,同时传送的字符间不留间隙,即保持位同步关系,也保持字符同步关系。(3)波特率单片机或计算机在串口通信时的速率用波特率表示,它定义为每秒传输二进制代码的位数,即1波特=1位/秒,单位是bps(位/秒)。如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的波特率为10位X 240个/秒=2400bps.串行接口或终端直接传送串行信息位流的最大距离与传输速率及传输线的电气特性也有关。当传输线使用每0.3m(约1英尺)有50pF电容的非平衡屏蔽双绞线时,传输距离随传输速率的增加而减小。当比特率超过1000 bps时,最大传输距离迅速下降,如9600 bp

11、s时最大距离下降到只有76m(约250英尺)。因此我们在做串口通信实验选择较高速率传输数据时,尽量缩短数据线的长度,为了能使数据安全传输,即使是在较低传输速率下也不要使用太长的数据线。4:实验代码/* 实验名 :温度显示实验* 个人信息 :物联1401 廖攀 41458027* 实验效果 :使用单片机串口助手,输入GetTemp,此时数码管显示外界温度,同时将温度反馈到电脑。*/#include<reg51.h>#include"temp.h"#include"string.h" #define DIGP0 sbit LSA=P22;sbit

12、 LSB=P23;sbit LSC=P24;sbit K2=P30;unsigned char code DIG_CODE18=0x06,0x66,0x3f,0x06,0x06,0x5b,0x4f,0x6d;/定义19和英文字母的显示(显示000000)unsigned char Num=0;unsigned char code C="0123456789."unsigned char A10;unsigned int disp8=0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f;unsigned char receiveData8;unsig

13、ned char code danpianji="ID:41458027 Temp:"unsigned char m=0;void LcdDisplay(int);void Timer0Configuration();void UsartConfiguration();void DigDisplay1();void Delay(unsigned int n);void Turn();/* 函数名 : main* 函数功能 : 主函数* 输入 : 无* 输出 : 无*/void main() unsigned char i; Timer0Configuration();/调用

14、计时器UsartConfiguration(); /启用计时器 for(i=0;i<8;i+)dispi=DIG_CODEi+10;while(strcmp(receiveData,"GetTemp") void DigDisplay1();while(1)LcdDisplay(Ds18b20ReadTemp(); if(K2=0) Delay(1);if(K2=0) break; A6 ='d' A7 = 'c'A8 ='g'A9 = 'C' Turn(); /* 函数名 : LcdDisplay()*

15、 函数功能 : LCD显示读取到的温度* 输入 : v* 输出 : 无*/void LcdDisplay(int temp) /lcd显示温度 unsigned char datas = 0, 0, 0, 0, 0; /定义数组float tp; if(temp< 0) disp2 = 0x40; temp=temp-1;temp=temp;tp=temp;temp=tp*0.0625*100+0.5; else disp2 = 0;tp=temp; temp=tp*0.0625*100+0.5; disp0 = 0; disp1 = 0; disp3 = DIG_CODEtemp /

16、10000;disp4 = DIG_CODEtemp % 10000 / 1000;disp5 = DIG_CODEtemp % 1000 / 100 | 0x80;disp6 = DIG_CODEtemp % 100 / 10;disp7 = DIG_CODEtemp % 10;A0 =temp / 10000+'0'A1 = temp % 10000 / 1000+'0'A2 =temp % 1000 / 100+'0'A3 = '.'A4 = temp % 100 / 10+'0'A5 = temp % 10

17、+'0' /* 函数名 : DigDisplay() interrupt 1* 函数功能 : 中断数码管显示* 输入 : 无* 输出 : 无*/void DigDisplay() interrupt 1/定时器在工作方式二会自动重装初,所以不用在赋值。/TH0=0X9c;/给定时器赋初值,定时1ms/TL0=0X00;DIG=0; /消隐switch(Num) /位选,选择点亮的数码管case(7):LSA=0;LSB=0;LSC=0; break;case(6):LSA=1;LSB=0;LSC=0; break;case(5):LSA=0;LSB=1;LSC=0; break

18、;case(4):LSA=1;LSB=1;LSC=0; break;case(3):LSA=0;LSB=0;LSC=1; break;case(2):LSA=1;LSB=0;LSC=1; break;case(1):LSA=0;LSB=1;LSC=1; break;case(0):LSA=1;LSB=1;LSC=1; break;DIG=dispNum; /段选,选择显示的数字。Num+;if(Num>7)Num=0;/* 函数名 : Timer0Configuration()* 函数功能 : 设置计时器* 输入 : 无* 输出 : 无*/void Timer0Configuration

19、()TMOD=0X22; /选择为定时器模式,工作方式2,仅用TRX打开启动。TH0=0X9C; /给定时器赋初值,定时100usTL0=0X9C;ET0=1; EA=1; TR0=1; /* 函数名 :UsartConfiguration()* 函数功能 :设置串口* 输入 : 无* 输出 : 无*/void UsartConfiguration()SCON=0X50;PCON=0X80;TH1=0xF3;TL1=TH1;ES=1;EA=1;TR1=1;/* 函数名 :void Usart() interrupt 4* 函数功能 : 串口中断函数* 输入 : 无* 输出 : 无*/void

20、Usart() interrupt 4 if(RI=1) receiveDatam+=SBUF; receiveDatam='0' RI=0;/* 函数名 void DigDisplay1()* 函数功能 : 在数码管上显示"6-319gdh"* 输入 : 无* 输出 : 无*/ void DigDisplay1()unsigned char i;unsigned int j;for(i=0;i<8;i+)switch(i) /位选,选择点亮的数码管,case(0):LSA=0;LSB=0;LSC=0; break;/显示第0位case(1):LSA=

21、1;LSB=0;LSC=0; break;/显示第1位case(2):LSA=0;LSB=1;LSC=0; break;/显示第2位case(3):LSA=1;LSB=1;LSC=0; break;/显示第3位case(4):LSA=0;LSB=0;LSC=1; break;/显示第4位case(5):LSA=1;LSB=0;LSC=1; break;/显示第5位case(6):LSA=0;LSB=1;LSC=1; break;/显示第6位case(7):LSA=1;LSB=1;LSC=1; break;/显示第7位DIG=dispi;j=10; while(j-);DIG=0x00;/消隐/

22、* 函 数 名 : Delay(unsigned int n)* 函数功能 : 延时* 输 入 : n* 输 出 : 无*/void Delay(unsigned int n) /延时50us误差 0us unsigned char a,b;for(;n>0;n-) for(b=1;b>0;b-) for(a=22;a>0;a-);/* 函 数 名 : void Turn()* 函数功能 : 向电脑回传数据* 输 入 : 无* 输 出 : 无*/void Turn()unsigned char i,j;ES=0;for(i=0;i<17;i+)SBUF=danpianj

23、ii; while(!TI); TI=0;for(j=0;j<10;j+)SBUF=Aj; /将接收到的数据放入到发送寄存器while(!TI); /等待发送数据完成TI=0; /* 函数名 : Delay1ms* 函数功能 : 延时函数* 输入 : 无* 输出 : 无*/void Delay1ms(unsigned int y)unsigned int x;for(y;y>0;y-)for(x=110;x>0;x-);#include"temp.h"/* 函数名 : Ds18b20Init* 函数功能 : 初始化* 输入 : 无* 输出 : 初始化成功返

24、回1,失败返回0*/unsigned char Ds18b20Init()unsigned int i; EA = 0;DSPORT=0; /将总线拉低480us960usi=70;while(i-);/延时642usDSPORT=1;/然后拉高总线,如果DS18B20做出反应会将在15us60us后总线拉低i=0; EA = 1;while(DSPORT)/等待DS18B20拉低总线i+;if(i>5000)/等待>5MSreturn 0;/初始化失败return 1;/初始化成功#include"lcd.h"/* 函 数 名 : Lcd1602_Delay1

25、ms* 函数功能 : 延时函数,延时1ms* 输 入 : c* 输 出 : 无* 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。*/void Lcd1602_Delay1ms(uint c) /误差 0us uchar a,b;for (; c>0; c-) for (b=199;b>0;b-) for(a=1;a>0;a-); /* 函 数 名 : LcdWriteCom* 函数功能 : 向LCD写入一个字节的命令* 输 入 : com* 输 出 : 无*/#ifndef LCD1602_4PINS /当没有定义这个LCD1602_4PINS时void Lc

26、dWriteCom(uchar com) /写入命令LCD1602_E = 0; /使能LCD1602_RS = 0; /选择发送命令LCD1602_RW = 0; /选择写入LCD1602_DATAPINS = com; /放入命令Lcd1602_Delay1ms(1);/等待数据稳定LCD1602_E = 1; /写入时序Lcd1602_Delay1ms(5); /保持时间LCD1602_E = 0;#else void LcdWriteCom(uchar com) /写入命令LCD1602_E = 0; /使能清零LCD1602_RS = 0; /选择写入命令LCD1602_RW = 0

27、; /选择写入LCD1602_DATAPINS = com;/由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1; /写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;/Lcd1602_Delay1ms(1);LCD1602_DATAPINS = com << 4; /发送低四位Lcd1602_Delay1ms(1);LCD1602_E = 1; /写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;#endif/* 函 数 名 : LcdWriteData*

28、函数功能 : 向LCD写入一个字节的数据* 输 入 : dat* 输 出 : 无*/ #ifndef LCD1602_4PINS void LcdWriteData(uchar dat)/写入数据LCD1602_E = 0;/使能清零LCD1602_RS = 1;/选择输入数据LCD1602_RW = 0;/选择写入LCD1602_DATAPINS = dat; /写入数据Lcd1602_Delay1ms(1);LCD1602_E = 1; /写入时序Lcd1602_Delay1ms(5); /保持时间LCD1602_E = 0;#elsevoid LcdWriteData(uchar dat

29、)/写入数据LCD1602_E = 0; /使能清零LCD1602_RS = 1; /选择写入数据LCD1602_RW = 0; /选择写入LCD1602_DATAPINS = dat;/由于4位的接线是接到P0口的高四位,所以传送高四位不用改Lcd1602_Delay1ms(1);LCD1602_E = 1; /写入时序Lcd1602_Delay1ms(5);LCD1602_E = 0;LCD1602_DATAPINS = dat << 4; /写入低四位Lcd1602_Delay1ms(1);LCD1602_E = 1; /写入时序Lcd1602_Delay1ms(5);LCD

30、1602_E = 0;#endif/* 函 数 名 : LcdInit()* 函数功能 : 初始化LCD屏* 输 入 : 无* 输 出 : 无*/ #ifndefLCD1602_4PINSvoid LcdInit() /LCD初始化子程序 LcdWriteCom(0x38); /开显示LcdWriteCom(0x0c); /开显示不显示光标LcdWriteCom(0x06); /写一个指针加1LcdWriteCom(0x01); /清屏LcdWriteCom(0x80); /设置数据指针起点#elsevoid LcdInit() /LCD初始化子程序LcdWriteCom(0x32); /将8

31、位总线转为4位总线LcdWriteCom(0x28); /在四位线下的初始化LcdWriteCom(0x0c); /开显示不显示光标LcdWriteCom(0x06); /写一个指针加1LcdWriteCom(0x01); /清屏LcdWriteCom(0x80); /设置数据指针起点#endif#include"temp.h"/* 函数名 : Ds18b20WriteByte* 函数功能 : 向18B20写入一个字节* 输入 : com* 输出 : 无*/void Ds18b20WriteByte(unsigned char dat)unsigned int i,j; EA = 0;for(j=0;j<8;j+)DSPORT=0;/每写入一位数据之前先把总线拉低1usi+;DSPORT=dat&0x01; /然后写

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论