单片机应用实习报告.docx
《单片机应用实习报告.docx》由会员分享,可在线阅读,更多相关《单片机应用实习报告.docx(44页珍藏版)》请在冰豆网上搜索。
单片机应用实习报告
摘要
此次的设计单片机硬件和实现外围电路的方案,因为已经有了电路板,重点介绍以单片机AT89C52为控制核心,实现键盘显示电路、多功能数字时钟、实时温度检测显示、频率测量的数字频率设计。
时钟计数是利用单片机的定时器完成的,利用6位8段数码管显示电路显示。
测温采用温度传感器芯片采集温度,经过各种转换和运算最后显示在数码管上。
测频的基本原理是采用在底频段直接测频法,通过单片机定时器定时1s计算中断的次数,然后将次数通过转换显示在数码管的各位,设计的频率计范围能够达到1HZ~50KHZ,满足所要求的频率范围,测量精度较高。
程序部分是通过看教材加以理解在和同学请教改编而成。
abstract
Thedesignofthesinglechipmicrocomputerhardwareandrealizethebuffercircuitscheme,fortherearealreadyacircuitboard,introducedAT89C52singlechipmicrocomputertoascontrolcore,realizethekeyboarddisplaycircuit,multi-functiondigitalclock,andthereal-timetemperaturetestshowedthat,thenumberoffrequencymeasurementfrequencydesign.Theclockcountingofthemicrocontrollertimeriscomplete,usingsix8periodofdigitaltubedisplaycircuitdisplay.Temperaturemeasuringthetemperaturesensorchipcollectiontemperature,throughavarietyoftransformationandoperationfinallydisplayedinthedigitaltubes.Thebasicprincipleofmeasuringfrequencyisadoptedinthedirectmethodofmeasuringfrequencyband,throughthemicrocontrollertimertiming1scalculationinterruptthenumberoftimesandthenwillbedisplayedindigitaltimesthroughtheconversiontubeofeveryone,thedesignofthefrequencymetercanreach1HZrange~50KHZ,meettherequiredfrequencyrange,hashighaccuracy.Partsoftheprogramisseethroughtheteachingmaterialsareunderstoodinadaptedandfellowstudents.
1数字时钟
1.1单片机的基本知识
1.1.1数码管动态显示原理
图1数码管显示原理图
如图1数码管显示原理图所示,使用LED显示器时,要注意是共阴还是共阳,要注意区分这两种不同的接法。
为了显示数字或字符,必须对数字或字符进行编码。
七段数码管加上一个小数点,共计8段。
因此为LED显示器提供的编码正好是一个字节。
我们用的是共阴LED显示器,根据电路连接图显示16进制数的编码已列在下表。
0x3f,0x06,0x5b,0x4f,0x66,0x6d,
012345
0x7d,0x07,0x7f,0x6f,0x77,0x7c,
6789AB
0x39,0x5e,0x79,0x71,0x00
CDEF无显示
动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效,由另一位控制显示码值。
选亮数码管采用动态扫描显示。
所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。
我们这里正是利用的数码管动态显示来完成显示功能。
1.1.2键盘扫描原理
图2中左边16个按键为4*4矩阵键盘,检测到低电平时认为被按下。
图2中,矩阵键盘全部连接单片机的I/O口,检测时由软件强制拉低。
将矩阵按键的最右边一列设置为独立按键,只需要在程序最开始处用软件将“RD”端置低,然后依次检测“P3.0,P3.1,CSDA和INT1”即可。
图2矩阵键盘图
1.2程序说明和流程图
1.2.1程序说明
此时钟的设计与实现,主要采用了6只LED数码管,加Atmel89c52单片机,包括显示模块,运算模块和校时模块三大功能模块。
显示模块:
用Atmel89c52控制,用数码管的显示功能来设计。
显示部分硬件用六只LED为显示管,这些LED发光二极管的阴极是互相连接在一起的,所以称为共阴极数码管。
通过在这8只发光二极管的阳极加+5V或0V的电压使不同的二极管发光,形成不同的数字。
该模块主要是将运算模块和校时模块运算出来的十进制表示的时位、分位和秒位数值,并通过6只数码管显示出来。
该模块实现的硬件是7seg-mpx6-cc单元,采用软件译码。
通过单片机P0口输出值和两个74HC573译码器控制段选和位选和显示。
运算模块:
该模块的主要功能是对时、分、秒的运算,并把运算出的最终结果存到事先已经开辟的内存单元里,以便显示模块即时地显示出来。
该模块可以细分为秒定时模块和运算模块。
延时程序实现延时功能,由于CPU运算模块中的指令消耗一定的时间,所消耗的时间可以用来延时。
当演示完成后才能让秒单元内的数值加1。
在主程序里,必须对秒、分和时的单元内的数值进行判断,当秒加到60时,分必须加1、秒清零;当分加到60时,时加1、分清零。
当时加到24时,直接清零。
然后转到调用处。
校时模块:
该模块主要功能是修改时、分、秒内存单元的数值。
每按一次键,对应的显示值便加1。
分、秒加到59后变为00;小时加到23后再按键即变为00.再调校时均不向上一单位进位(例如分加到59后变为00;但小时不发生改变)。
1.2.2流程图
1.主函数
初始化(定时器、显示区、输入输出、计数单元等)
开始
初始化时,分,秒并在秒上自加一位
秒计数到60
Y
N
分钟自加一位,秒钟归零
分钟到60
Y
N
时钟自加一位,分钟归零
键盘输入
Y
N
修改分钟,小时
调用显示子程序
图3主程序流程图
2.显示子程序
图4显示子程序流程图
1.3调试与仿真
我们跟据试验原理设计了仿真图,将程序在keil中运行后,将生成的HEX档加载、运行,来看是否能实现我们要求的功能,并看是否有错误。
如图3实验仿真图所示,这与我们想要的结果是一致的。
可见我们的程序是正确的,并且能够实现我们想要的功能。
图5数字钟仿真图
2数字温度计
2.1总体设计框图
温度计电路设计总体设计方框图如图4所示,控制器采用单片机AT89c52,温度传感器采用DS18B20,用6位LED数码管以串口传送数据实现温度显示
图6数字温度计总体框图
2.2温度采集部分的设计
2.2.1温度传感器DS18B20
TO-92封装的DS18B20的引脚排列见下图,其引脚功能描述见表1。
DS18B20
表1DS18B20详细引脚功能描述
序号
名称
引脚功能描述
1
GND
地信号
2
DQ
数据输入/输出引脚。
开漏单总线接口引脚。
当被用着在寄生电源下,也可以向器件提供电源。
3
VDD
可选择的VDD引脚。
当工作于寄生电源时,此引脚必须接地。
2.2.2DS18B20温度传感器与单片机的接口电路
DS18B20可以采用两种方式供电,一种是采用电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源。
另一种是寄生电源供电方式,如图4所示单片机端口接单线总线,为保证在有效的DS18B20时钟周期内提供足够的电流,可用一个MOSFET管来完成对总线的上拉。
当DS18B20处于写存储器操作和温度A/D转换操作时,总线上必须有强的上拉,上拉开启时间最大为10us。
采用寄生电源供电方式时VDD端接地。
由于单线制只有一根线,因此发送接口必须是三态的。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:
初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
DS18B20的复位时序
图7DS18B20的读时序
对于DS18B20的读时隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。
DS18B20在完成一个读时序过程,至少需要60us才能完成。
图8DS18B20的写时序
对于DS18B20写0时序和写1时序的要求不同,当要写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采样IO总线上的“0”电平,当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。
图9写0时序与写1时序
2.2.3设计流程图
图10主程序流程图图11读温度流程图
2.4读出温度子程序
读出温度子程序的功能是读出RAM中的9字节,其程序流程图如图9示
图12温度转换流程图
2.5温度转换命令子程序
温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。
温度转换命令子程序流程图如上图,图10所示。
2.6计算温度子程序
计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定,其程序流程图如图11所示。
图13计算温度流程图图14显示数据刷新流程图
2.7显示数据刷新子程序
显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高显示位为0时将符号显示位移入下一位。
程序流程图如图14。
2.8调试与仿真
根据电路图,各单元电路之间的连接关系,以及用哪些元器件进行仿真,由于是初学者经验不足,没有实际应用过,单凭看资料很难掌握它们内容。
设计时难免考虑不周、出现差错,单是纸上谈兵,想使自己设计的电路完美无误是不可能的,所以,必须进行仿真。
在仿真过程中会遇到问题要善于理论联系实际,深入思考,分析原因,找出解决问题的办法。
通过前面总的设计框图,我们初步搭建了数字频率计设计的框架结构。
下面仿真结果如图:
图15温度检测显示仿真图
3数字频率计
3.1数字频率计设计流程图
数字频率计主要由以下几部分组成:
(1)时基电路;
(2)逻辑控制电路;(3)可控制的显示电路。
因为单片机内部振荡频率很高,所以一个机器周期的量化误差相当小,可以提高低频信号的测量的准确性。
本设计主要是以单片机AT89C52为核心,通过计数电路,以及软件程序的编写,实现脉冲频率的显示。
整体设计思路可用图16表示。
框图中各部分的作用及所采用的器件说明如下:
图16数字频率计流程图
3.2软件控制部分
软件控制部分是整机电路设计成败的关键。
它逻辑性强,时序关系配合得当。
控制电路的作用是:
定时器1定时到1s时计算INT0引脚输入脉冲的个数,然后送给显示电路显示。
软件控制部分见附录程序。
3.3数据显示电路
数据显示电路由锁存器和8段数码管组成,采用器件LED显示器。
LED显示器的结构由发光二极管构成a、b、c、d、e、f、g和h8段,并由此得名。
本设计中采用了六个8段数码管进行数据显示,将六个数码管串接起来进行显示,显示数据即是对频率计的测量结果。
如图17所示:
图17数据显示电路
图18LED动态显示流程图
3.4软件设计流程图
本设计中软件流程如图19所示。
图19软件设计流程图
3.5数字频率计的仿真
根据电路图,各单元电路之间的连接关系,以及用哪些元器件进行仿真,由于是初学者经验不足,没有实际应用过,单凭看资料很难掌握它们内容。
设计时难免考虑不周、出现差错,单是纸上谈兵,想使自己设计的电路完美无误是不可能的,所以,必须进行仿真。
在仿真过程中会遇到问题要善于理论联系实际,深入思考,分析原因,找出解决问题的办法。
通过前面总的设计框图,我们初步搭建了数字频率计设计的框架结构。
在输入频率为5000Hz的条件下仿真结果如图20所以:
图20数字频率计仿真图
4串口通信
4.1单片机串行和并行通信
计算机与外界的信息交换称为通信,常用的通信方式有两种:
并行通信和串行通信。
51单片机用4个接口与外界进行数据输入与数据输出就是并行通信,并行通信的特点是传输信号的速度快,但所用的信号线较多,成本高,传输的距离较近。
串行通信的特点是只用两条信号线(一条信号线,再加一条地线作为信号回路)即可完成通信,成本低,传输的距离较远。
51单片机的串行接口是一个全双工的接口,它可以作为UART(通用异步接受和发送器)用,也可以作为同步移位寄存器用。
51单片机串行接口的结构如下:
(1)数据缓冲器(SBUF)
接受或发送的数据都要先送到SBUF缓存。
有两个,一个缓存,另一个接受,用同一直接地址99H,发送时用指令将数据送到SBUF即可启动发送;接收时用指令将SBUF中接收到的数据取出。
(2)串行控制寄存器(PCON)
SCON用于串行通信方式的选择,收发控制及状态指示,各位含义如下:
SM0
SM1
SM2
REN
TB8
RB8
TI
RI
SM0,SM1:
串行接口工作方式选择位,这两位组合成00,01,10,11对应于工作方式0、1、2、3。
串行接口工作方式特点见下表2:
SM0
SM1
工作方式
功能
波特率
0
0
0
8位同步移位寄存器(用于I/O扩展)
fORC/12
0
1
1
10位异步串行通信(UART)
可变(T1溢出率*2SMOD/32)
1
0
2
11位异步串行通信(UART)
fORC/64或fORC/32
1
1
3
11位异步串行通信(UART)
可变(T1溢出率*2SMOD/32)
SM2:
多机通信控制位。
REN:
接收允许控制位。
软件置1允许接收;软件置0禁止接收。
TB8:
方式2或3时,TB8为要发送的第9位数据,根据需要由软件置1或清0。
RB9:
在方式2或3时,RB8位接收到的第9位数据,实际为主机发送的第9位数据TB8,使从机根据这一位来判断主机发送的时呼叫地址还是要传送的数据。
TI:
发送中断标志。
发送完一帧数据后由硬件自动置位,并申请中断。
必须要软件清零后才能继续发送。
RI:
接收中断标志。
接收完一帧数据后由硬件自动置位,并申请中断。
必须要软件清零后才能继续接收。
(3)输入移位寄存器
接收的数据先串行进入输入移位寄存器,8位数据全移入后,再并行送入接收SBUF中。
(4)波特率发生器
波特率发生器用来控制串行通信的数据传输速率的,51系列单片机用定时器T1作为波特率发生器,T1设置在定时方式。
波特率时用来表示串行通信数据传输快慢程度的物理量,定义为每秒钟传送的数据位数。
(5)电源控制寄存器PCON
其最高位为SMOD。
(6)波特率计算
当定时器T1工作在定时方式的时候,定时器T1溢出率=(T1计数率)/(产生溢出所需机器周期)。
由于是定时方式,T1计数率=fORC/12。
产生溢出所需机器周期数=模M-计数初值X。
4.2串口通信设计框图
(1)发送端流程图:
图21发送流程图
(2)接收端流程图:
显示
图22接收流程图
4.3调试与仿真
仿真图如下所示:
图23串口通信仿真图
5心得与体会
这次的单片机实习我利用老师给的板子,按照要求设计电路。
硬件的设计跟焊接都要我们自己动手去焊,软件的编程也要我们不断的调试,最终一个能完成课程设计的劳动成果出来了,很高兴它能按着设计的思想与要求运动起来。
当然,这其中也有很多问题,第一、不够细心比如由于粗心大意焊错了线,由于对课本理论的不熟悉导致编程出现错误。
第二,是在学习态度上,这次课设是对我的学习态度的一次检验。
对于这次单片机综合课程实习,我的第一大心得体会就是作为一名工程技术人员,要求具备的首要素质绝对应该是严谨。
我们这次实习所遇到的多半问题多数都是由于我们不够严谨。
通过这次单片机实习,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。
创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。
在这次课程设计中,我们运用到了以前所学的专业课知识,如:
C语言、模拟和数字电路知识等。
虽然过去从未独立应用过它们,但在学习的过程中带着问题去学我发现效率很高,这是我做这次课程设计的又一收获。
最后,在实习之前,我们要对所用单片机的内部结构有一个系统的了解,知道该单片机内有哪些资源;要有一个清晰的思路和一个完整的的软件流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯,一个程序的完美与否不仅仅是实现功能,而应该让人一看就能明白你的思路,这样也为资料的保存和交流提供了方便;在实习过程中遇到问题是很正常的,但我们应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。
但是从中学到的知识会让我受益终身。
发现、提出、分析、解决问题和实践能力提高都会受益于我在以后的学习、工作和生活中。
6实物焊接图
实物图如下所示:
图24实物焊接图
附录A程序结合实现功能切换
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
sbits4=P3^0;
sbits12=P3^2;
sbits16=P3^3;
sbits17=P3^4;
sbits19=P3^6;
sbitrd=P3^7;
sbitds=P2^2;
sbitdula=P2^6;
sbitwela=P2^7;
ucharcount0=0,count2=0,num1=0,num2=0,num3=0,second=0,minute=0,hour=0;a,b,c,d,e,f;
ulongcount1=0,freq;
uinttemp;
floatf_temp;
ucharbuff[4];
ucharcodetable1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
ucharcodetable2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
voiddelay(uintx)
{
uinti,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
voidinit()
{
rd=0;
TMOD=0x01;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TR0=1;
ET0=1;
EA=1;
}
voiddsreset()
{
uinti;
ds=0;
i=103;
while(i>0)i--;
ds=1;
i=4;
while(i>0)i--;
}
bittempreadbit()
{
uinti;
bitdat;
ds=0;i++;
ds=1;i++;i++;
dat=ds;
i=8;while(i>0)i--;
returndat;
}
uchartempread()
{
uchari,j,dat=0;
for(i=0;i<8;i++)
{
j=tempreadbit();
dat=(j<<7)|(dat>>1);
}
returndat;
}
voidtempwritebyte(uchardat)
{
uinti;
ucharj;
bittestb;
for(j=0;j<8;j++)
{
testb=dat&0x01;
dat>>=1;
if(testb)
{
ds=0;
i++;i++;
ds=1;
i=8;while(i>0)i--;
}
else
{
ds=0;
i=8;while(i>0)i--;
ds=1;
i++;i++;
}
}
}
voidtempchange()
{
dsreset();
delay
(1);
tempwritebyte(0xcc);
tempwritebyte(0x44);
}
uintget_temp()
{
uchara,b;
dsreset();
delay
(1);
tempwritebyte(0xcc);
tempwritebyte(0xbe);
a=tempread();
b=tempread();
temp=b;
temp<<=8;
temp=temp|a;
f_temp=temp*0.0625;
temp=f_temp*10+0.5;
returntemp;
}
voiddis_time()
{
P0=0xff;
wela=1;
P0=0xfe;