《单片机技术》课件项目六 单片机温度采集系统_第1页
《单片机技术》课件项目六 单片机温度采集系统_第2页
《单片机技术》课件项目六 单片机温度采集系统_第3页
《单片机技术》课件项目六 单片机温度采集系统_第4页
《单片机技术》课件项目六 单片机温度采集系统_第5页
已阅读5页,还剩132页未读 继续免费阅读

下载本文档

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

文档简介

一、学习目标1.了解单片机的串口的概念。2.掌握单片机串口硬件结构。3.掌握单片机串口通信工作方式。4.掌握单总线(一线总线)工作原理。5.掌握单片机驱动DS18B20驱动方法。二、学习任务任务一用串口扩展IO口;任务二单片机双机通信;任务三PC与单片机串口通信;任务四DS18B20温度采集系统。三、任务分解任务一用串口扩展I0口【任务描述】大街上有很多点阵广告屏,有的是插U盘更新内容,有的则是使用PC机通过单片机串口动态更新内容,串口动态更新内容的实质就是单片机与外界通信。单片机之间可实现双机通信、多机通信并可与PC机通信;利用PC机与单片机可组成上位机、下位机通信网络。本任务用单片机的串口扩展出8个IO口,实现流水灯效果。【任务描述】大街上有很多点阵广告屏,有的是插U盘更新内容,有的则是使用PC机通过单片机串口动态更新内容,串口动态更新内容的实质就是单片机与外界通信。单片机之间可实现双机通信、多机通信并可与PC机通信;利用PC机与单片机可组成上位机、下位机通信网络。本任务用单片机的串口扩展出8个IO口,实现流水灯效果。【任务分析】熟悉掌握单片机串口的硬件结构,熟悉单片机串口通信工作方式0的应用。【相关知识】一、串行通信概述

计算机与外界的信息交换称为通信。通信的基本方式可分为并行通信和串行通信两种。所谓并行通信是指数据的各位同时在多根数据线上发送或接收。串行通信是数据的各位在同一根数据线上依次逐位发送或接收。1串行通信基础知识

目前串行通信在单片机双机、多机以及单片机与PC机之间的通信等方面得到了广泛应用。

并行通信示意图P0.7P0.6P0.5P0.4P0.3P0.2P0.1P0.0P2.7RDWRRDWRCSD7D6D5D4D3D2D1D0825589C51

串行通信示意图89C51外设TXDTXDRXDRXD发送接收1.1异步通信和同步通信

串行通信按同步方式可分为异步通信和同步通信两种基本通信方式。1)

同步通信(SynchronousCommunication)

同步通信是一种连续传送数据的通信方式,一次通信传送多个字符数据,称为一帧信息。数据传输速率较高,通常可达56000bps或更高。其缺点是要求发送时钟和接收时钟保持严格同步。同步字符数据字符1数据字符2…数据字符n-1数据字符n校验字符(校验字符)同步通信数据传送格式2)异步通信(AsynchronousCommunication)

在异步通信中,数据通常是以字符或字节为单位组成数据帧进行传送的。收、发端各有一套彼此独立,互不同步的通信机构,由于收发数据的帧格式相同,因此可以相互识别接收到的数据信息。同步通信的数据帧格式如图所示。D0D1D2D3D4

D5

D6

D7

0/11111D70/1100D0D1第n字符帧空闲位停止位奇偶校验停止位8位数据8位数据起始位起始位奇偶校验第n-1字符帧第n+1字符帧异步通信帧格式8位数据

异步通信信息帧格式如图所示。(1)起始位:在没有数据传送时,通信线上处于逻辑“1”状态。当发送端要发送1个字符数据时,首先发送1个逻辑“0”信号,这个低电平便是帧格式的起始位。其作用是向接收端表示发送端开始发送一帧数据。接收端检测到这个低电平后,就准备接收数据信号。(2)数据位:在起始位之后,发送端发出(或接收端接收)的是数据位,数据的位数没有严格的限制,5~8位均可。由低位到高位逐位传送。(3)奇偶校验位:数据位发送完(接收完)之后,可发送一位用来检验数据在传送过程中是否出错的奇偶校验位。奇偶校验是收发双方预先约定好的有限差错检验方式之一。有时也可不用奇偶校验。(4)停止位:字符帧格式的最后部分是停止位,逻辑“1”电平有效,它可占1/2位、1位或2位。停止位表示传送一帧信息的结束,也为发送下一帧信息作好准备。1.2串行通信的波特率

波特率(BaudRate)是串行通信中一个重要概念,它是指传输数据的速率,亦称比特率。波特率的定义是每秒传输二进制数码的位数。如:波特率为1200bps是指每秒钟能传输1200位二进制数码。

波特率的倒数即为每位数据传输时间。例如:波特率为1200bps,每位的传输时间为:1)(833.01200msdT==

波特率和字符的传输速率不同,若采用图9.4的数据帧格式,并且数据帧连续传送(无空闲位),则实际的字符传输速率为1200/11=109.09帧/秒。

波特率也不同于发送时钟和接收时钟频率。同步通信的波特率和时钟频率相等,而异步通信的波特率通常是可变的。1.3串行通信的制式1)单工制式(Simplex)

单工制式是指甲乙双方通信只能单向传送数据。单工制式如图9.5所示。

在串行通信中,数据是在两个站之间传送的。按照数据传送方向,串行通信可分为三种制式。发送器A接收器B图6.5单工制式2)半双工制式(Halfduplex)

半双工制式是指通信双方都具有发送器和接收器,双方既可发送也可接收,但接收和发送不能同时进行,即发送时就不能接收,接收时就不能发送。半双工制式如图6.6所示。发送接收发送接收A端B端图6.6半双工制式3)全双工制式(Fullduplex)

全双工制式是指通信双方均设有发送器和接收器,并且将信道划分为发送信道和接收信道,两端数据允许同时收发,因此通信效率比前两种高。全双工制式如图6.7所示。发送接收接收发送A端B端图6.7全双工制式1.4串行通信的校验

串行通信的目的不只是传送数据信息,更重要的是应确保准确无误地传送。因此必须考虑在通信过程中对数据差错进行校验,因为差错校验是保证准确无误地通信的关键。常用差错校验方法有奇偶校验、累加和校验以及循环冗余码校验等。1)奇偶校验

奇偶校验的特点是按字符校验,即在发送每个字符数据之后都附加一位奇偶校验位(1或0),当设置为奇校验时,数据中1的个数与校验位1的个数之和应为奇数;反之则为偶校验。收、发双方应具有一致的差错检验设置,当接收1帧字符时,对1的个数进行检验,若奇偶性(收、发双方)一致则说明传输正确。奇偶校验只能检测到那种影响奇偶位数的错误,比较低级且速度慢,一般只用在异步通信中。2)累加和校验

累加和校验是指发送方将所发送的数据块求和,并将“校验和”附加到数据块末尾。接收方接收数据时也是先对数据块求和,将所得结果与发送方的“校验和”进行比较,若两者相同,表示传送正确,若不同则表示传送出了差错。“校验和”的加法运算可用逻辑加,也可用算术加。累加和校验的缺点是无法检验出字节或位序的错误。3)循环冗余码校验(CRC)

循环冗余码校验的基本原理是将一个数据块看成一个位数很长的二进制数,然后用一个特定的数去除它,将余数作校验码附在数据块之后一起发送。接收端收到该数据块和校验码后,进行同样的运算来校验传送是否出错。目前CRC已广泛用于数据存储和数据通信中,并在国际上形成规范,市面上已有不少现成的CRC软件算法。2AT89C51的串行接口AT89C51内部有一个可编程全双工串行通信接口。该部件不仅能同时进行数据的发送和接收,也可作为一个同步移位寄存器使用。下面将对其内部结构、工作方式以及波特率进行介绍。2.1串行接口的结构及功能AT89C51串行口结构框图发送SBUF(99H)接收SBUF(99H)同步时钟门电路发送控制器接收控制器输入移位寄存器串行口控制寄存器(98H)内部总线≥1串行口中断TIRITXD(P3.1)RXD(P3.0)

发送数据过程:CPU通过内部总线将并行数据写入发送SBUF,在发送控制电路的控制下,按设定好的波特率,每来一次移位脉冲,通过引脚TXD向外输出一位。一帧数据发送结束后,向CPU发出中断申请,TI位置1。CPU响应中断后,开始准备发送下一帧数据。发送SBUF(99H)接收SBUF(99H)同步时钟门电路发送控制器接收控制器输入移位寄存器串行口控制寄存器(98H)内部总线≥1串行口中断TIRITXD(P3.1)RXD(P3.0)接收数据过程:CPU不停地检测引脚RXD上的信号,当信号中出现低电平时,在接收控制电路的控制下,按设定好的波特率,每来一次移位脉冲,读取外部设备发送的一位数据到移位寄存器。一帧数据结束后,数据被存入接收SBUF,同时向CPU发出中断申请,RI位置1。CPU响应中断后,开始接收下一帧数据。1)串行数据缓冲器SBUFSBUF是串行口缓冲寄存器,包括发送寄存器和接收寄存器,以便能以全双工方式进行通信。此外,在接收寄存器之前还有移位寄存器,从而构成了串行接收的双缓冲结构,这样可以避免在数据接收过程中出现帧重叠错误。发送数据时,由于CPU是主动的,不会发生帧重叠错误,因此发送电路不需要双重缓冲结构。

在逻辑上,SBUF只有一个,它既表示发送寄存器,又表示接收寄存器,具有同一个单元地址99H。但在物理结构上,则有两个完全独立的SBUF,一个是发送缓冲寄存器SBUF,另一个是接收缓冲寄存器SBUF。如果CPU写SBUF,数据就会被送入发送寄存器准备发送;如果CPU读SBUF,则读入的数据一定来自接收缓冲器。即CPU对SBUF的读写,实际上是分别访问上述两个不同的寄存器。2)串行控制寄存器SCON

串行控制寄存器SCON用于设置串行口的工作方式、监视串行口的工作状态、控制发送与接收的状态等。它是一个既可以字节寻址又可以位寻址的8位特殊功能寄存器。其格式如图6-1所示。见表6-1串行口控制寄存器SCONRITIRB8TB8RENSM2SM1SM0SCON98H99H9AH9BH9CH9DH9EH9FH位地址0:双机1:多机多机通信0:禁止1:允许接收控制发送数据第9位接收数据第9位发送中断标志接收中断标志(1)SM0SM1:串行口工作方式选择位。其状态组合所对应的工作方式如表所示。SM0SM1工作方式功能说明000同步移位寄存器输入/输出,波特率固定为fosc/1201110位异步收发,波特率可变(T1溢出率/n,n=32或16)10211位异步收发,波特率固定为fOsc/n,n=64或32)11311位异步收发,波特率可变(T1溢出率/n,n=32或16)6-1串行口工作方式(2)SM2:多机通信控制器位。在方式0中,SM2必须设成0。在方式1中,当处于接收状态时,若SM2=1,则只有接收到有效的停止位“1”时,RI才能被激活成“1”(产生中断请求)。在方式2和方式3中,若SM2=0,串行口以单机发送或接收方式工作,TI和RI以正常方式被激活并产生中断请求;若SM2=1,RB8=1时,RI被激活并产生中断请求。(4)TB8:方式2和方式3中要发送的第9位数据。该位由软件置位或复位。在方式2和方式3时,TB8是发送的第9位数据。在多机通信中,以TB8位的状态表示主机发送的是地址还是数据:TB8=1表示地址,TB8=0表示数据。TB8还可用作奇偶校验位。(3)REN:串行接受允许控制位。该位由软件置位或复位。当REN=1,允许接收;当REN=0,禁止接收。(6)TI:发送中断标志位。TI=1,表示已结束一帧数据发送,可由软件查询TI位标志,也可以向CPU申请中断。注意:TI在任何工作方式下都必须由软件清0。(5)RB8:接收数据第9位。在方式2和方式3时,RB8存放接收到的第9位数据。RB8也可用作奇偶校验位。在方式1中,若SM2=0,则RB8是接收到的停止位。在方式0中,该位未用。(7)RI:接收中断标志位。RI=1,表示一帧数据接收结束。可由软件查询RI位标志,也可以向CPU申请中断。

注意:RI在任何工作方式下也都必须由软件清0。在AT89C51中,串行发送中断TI和接收中断RI的中断入口地址是同是0023H,因此在中断程序中必须由软件查询TI和RI的状态才能确定究竟是接收还是发送中断,进而作出相应的处理。单片机复位时,SCON所有位均清0。PCOND7D6D5D4D3D2D1D0位名称SMOD---GF1GF0PDIDL

SMOD:串行口波特率倍增位。在工作方式1~工作方式3时,若SMOD=1,则串行口波特率增加一倍。若SMOD=0,波特率不加倍。系统复位时,SMOD=0。2.电源控制寄存器PCON2.2串行口工作方式AT89C51串行通信共有4种工作方式,它们分别是方式0、方式1、方式2和方式3,由串行控制寄存器SCON中的SM0SM1决定,如表9-1所示。1.工作方式0

在方式0下,串行口作为同步移位寄存器使用。此时SM2、RB8、TB8均应设置为0。

(1)发送:TI=0时,执行“SBUF=0xxx”启动发送,8位数据由低位到高位从RXD引脚送出,TXD发送同步脉冲。发送完后,由硬件置位TI。

(2)接收:RI=0,REN=1时启动接收,数据从RXD输入,TXD输出同步脉冲。8位数据接收完,由硬件置位RI。可通过“x=SBUF”读取数据。

方式0的波特率为fosc/12,即一个机器周期发送或接收一位数据。

应当指出:方式0并非是同步通信方式。它的主要用途是外接同步移位寄存器,以扩展并行I/O口。2.工作方式1

方式1是一帧10位的异步串行通信方式,包括1个起始位(0),8个数据位和一个停止位(1),其帧格式如下:

起始位0D0D1D2D3D4D5D6D7

停止位1(1)数据发送

当TI=0时,执行“SBUF=0xxx”指令后开始发送,由硬件自动加入起始位和停止位,构成一帧数据,然后由TXD端串行输出。发送完后,TXD输出线维持在“1”状态下,并将SCON中的TI置1,表示一帧数据发送完毕。(2)数据接收

RI=0,REN=1时,接收电路以波特率的16倍速度采样RXD引脚,如出现由“1”变“0”跳变,认为有数据正在发送。

在接收到第9位数据(即停止位)时,必须同时满足以下两个条件:RI=0和SM2=0或接收到的停止位为“1”,才把接收到的数据存入SBUF中,停止位送RB8,同时置位RI。若上述条件不满足,接收到的数据不装入SBUF被舍弃。在方式1下,SM2应设定为0。(3)波特率波特率=2SMOD×(T1溢出率)/32T1溢出率=1/T1定时时间=(M-T初)·T机1波特率=32·12·(M-T初)2SMOD·fosc3.工作方式2和方式3

工作方式2和方式3都是11位异步收发串行通信方式,两者的差异仅在波特率上有所不同。方式2:波特率=2SMOD·fosc/64(SMOD=0或1)方式3:(与方式1相同)波特率=32·12·(M-T初)2SMOD·fosc(1)数据发送

TI=0,发送数据前,先由软件设置TB8,可使用如下指令完成:TB8=1

;将TB8位置1TB8=0

;将TB8位置0

然后再向SBUF写入8位数据,并以此来启动串行发送。一帧数据发送完毕后,CPU自动将TI置1,其过程与方式1相同。(2)数据接收

REN=1,RI=0时,启动接收

①若SM2=0,接收到的8位数据送SBUF,第9位数据送RB8。②若SM2=1,接收到的第9位数据为0,数据不送SBUF;接收到的第9位数据为1,数据送SBUF,第9位送RB8。

对波特率需要说明的是,当串行口工作在方式1或方式3,且要求波特率按规范取1200、2400、4800、9600…时,若采用晶振12MHz和6MHz,按上述公式算出的T1定时初值将不是一个整数,因此会产生波特率误差而影响串行通信的同步性能。解决的方法只有调整单片机的晶振频率fosc,为此有一种频率为11.0592MHz的晶振,这样可使计算出的T1初值为整数。下表列出了串行方式1或方式3在不同晶振时的常用波特率和误差。常用波特率和误差

晶振频率(MHZ)波特率

(HZ)SMODT1方式2定时初值实际波特率误差(%)12.0096001F9H8923712.0048000F9H4460712.0024000F3H24040.1612.0012000E6H12020.1611.0592192001FDH19200011.059296000FDH9600011.059248000EAH4800011.059224000F4H2400011.059212000E8H12000【任务实施】利用8位并行输出串口移位寄存器74LS164扩展16位输出口的电路。串行口的数据通过RXD(P3.0)引脚加到74LS164的输入端。串行口输出移位时钟通过TXD(P3.1)引脚加到74LS164时钟端,作为同步移位脉冲,其波特率固定为fOSC/12。串行通信方式0应用电路对应的程序如下:

#include<reg51.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedint//延时voidDelayMS(uintms){uchari;while(ms--)for(i=0;i<120;i++);}//主程序voidmain(){ucharc=0x80;SCON=0x00;//串口模式0,即移位寄存器输入/输出方式

while(1){c=_crol_(c,1);SBUF=c;//TI=0,没有发送完

while(TI==0);//等待发送结束

TI=0;//TI软件置位

DelayMS(400);}}【进阶提高】通过指拨开关动作产生高低电平,作为74LS165的输入,74LS165将接收到的数据发往串口,串口负责接收,串口将接收到的数据送P1口显示。扩展串口串口接收电路对应的程序如下:#include<reg51.h>#include<intrins.h>#include<stdio.h>#defineucharunsignedchar#defineuintunsignedintsbitSPL=P2^5;//shift/load//延时voidDelayMS(uintms){uchari;while(ms--)for(i=0;i<120;i++);}//主程序

voidmain(){SCON=0x10;while(1){SPL=0;SPL=1;while(RI==0);RI=0;P0=SBUF;DelayMS(20);}}任务二单片机双机通信在银行业务系统中,为了提高柜员的登录安全和授权操作中的安全性,应用动态口令系统。通过单片机的双机通信可模拟动态密码的获取。这里就用到了单片机双机通信。假设单片机甲机中存放的动态口令是010086,甲机发送动态口令给单片机乙机,乙机接收到数据以后在6个数码管上显示接收数据。将两个独立的单片机系统用连接线进行连接,使用串行通信进行数据传送。那么单片机如何利用串口实现双机通信的?【分析任务】本任务要实现双机通信,需要掌握双机通信编程要领。通信协议一般如下:

主机发送数据,从机接收数据,双方发送和接收数据采用查询方式;

双机开始通信,主机发送握手信号,等待从机应答;

从机接收到握手信号后,应答OK或BUSY;

当从机应答OK后,主机开始向从机发送缓冲区里的数据;从机接收完数据后,返回接收成功或失败,若失败,主机将重新发送,从机将重新接收。主机发送的数据格式:字节数n,数据1,数据2......数据n,字节校验;其中字节校验是将字节数和所有数据进行相异或。【相关知识】一、串行口双机或多机通信工作方式单片机串口的初始化要使用单片机的串口,需要对其进行初始化工作。单片机串口初始化需完成单片机串口工作方式选择、波特率设置、波特率发生器设置等基本的设置。如设置单片机晶振频率为11.0592MHz,串口波特率为9600b/s,串口选择工作方式1,定时器配置为工作方式2。初始化程序如下:voidUartInit(void){TMOD=(TMOD&0x0f)|0x20;//设置定时器T1为定时方式2TH1=110592001/12/32/9600;//求波特率为9600时定时器初值TL1=TH1;TR1=1;//启动T1计数器SCON=0x70;//设置串行工作方式1,允许接收PCON=0x80;}【任务实施】#include<reg51.h>#defineucharunsignedchar#defineuintunsignedint#definekey_portP1#definedis_portP2voidmain(void){ ucharkey_in=0xff; SCON=0x50;//MODER1,REN=1; TMOD=0x20;//TIMER1MODER2; TH1=0xf3;//bode=2400 TL1=0xf3; ET1=1; TR1=1; EA=1; ES=1; while(1){ if(key_in!=key_port) { key_in=key_port; SBUF=key_in; } }}voidget_disp(void)interrupt4using0{ if(RI) //如果是串口输入引起中断

{dis_port=SBUF; RI=0; } elseTI=0; //否则就是串口输出引起的中断}【进阶提高】在KeilC51中录入下面程序,并调试程序:#include<reg51.h>#defineucharunsignedchar#defineuintunsignedintucharxx=0; //设计数标志sbitkey=P1^7; //设键盘ucharbuffer=0;voiddelay(intk) //延时函数{inti;for(i=0;i<k;i++);}//显示子程序voiddisplay(ucharm){switch(m) { case0:P2=0x3F;break; case1:P2=0x06;break; case2:P2=0x5B;break; case3:P2=0x4F;break; case4:P2=0x66;break; case5:P2=0x6D;break; case6:P2=0x7D;break; case7:P2=0x07;break; case8:P2=0x7F;break; case9:P2=0x6F;break;

case10:P2=0x77;break; case11:P2=0x7C;break; case12:P2=0x39;break; case13:P2=0x5E;break; case14:P2=0x79;break; default:P2=0x71;break; }}voidint_s()interrupt4//串口中断服务程序{ES=0; //关串口中断

if(RI==1){buffer=SBUF; RI=0;//清标志位

display(buffer);}if(TI==1){TI=0; } ES=1;//开串口中断

return;}voidmain(){display(buffer);//初始化

EA=1; ES=1;SCON=0X50; //工作方式1 TMOD=0X20;//定时器1工作方式2 TH1=0XE6;//1200bps,12Mhz TR1=1; //启动定时器

while(1){while(key==1) //查询键盘是否松开

{;}if(key==0) //查询键盘是否按下

delay(10); if(key==0) { xx=xx+1; //计数标志加1 if(xx==16) { xx=0; } SBUF=xx;//发送数据

} while(key==0) //键盘是否松开

{;} }}任务三PC与单片机通信【任务描述】比较而言,个人电脑(PC机)具有更强的信息处理能力,经常需要将单片机采集到的现场数据传送给PC机集中处理,或者由PC机发出命令,各终端(单片机)执行。本任务要求由PC机发出不同的数据,单片机接收后回传给PC机,从而验证接收数据是否正确。【任务分析】任务要求通过串口工具向单片机发信息,单片机通过收到信息后将信息回传给PC机,需要有单片机发送信息和接收信息两个方面的编程知识。【相关知识】单片机可以利用“串口”实现和PC机的通信,这需要了解PC机的一些特性。“RS-232C标准”是美国EIA(电子工业联合会)与BELL等公司一起开发并于1969年公布的通信协议。目前该通信协议在微机通信接口中广泛使用,IBMPC机上的COM1、COM2接口就是选用了RS-232接口。RS-232标准包括了按位串行传输的电气和机械方面的规定,使用数据终端设备和数据通信设备之间的接口。1.机械特性。2.功能特性。RS-232c接口的主要引脚功能定义。插针序号

符号

功能

方向2(3)TXD

发送数据

输出3(2)RXD

接收数据

输入4(7)RTS

请求发送

输出5(8)CTS

清除发送

输入6(6)DSR数据通信设备准备好

输入7(5)GND

信号地—8(1)DCD数据载体检测

输入20(4)DTR

数据终端准备好输出22(9)RI

振铃指示

输入3.电气特性。RS-232C采用“负逻辑”,规定逻辑0:+3~+15V;逻辑1:—15~-3V。RS-232C标准的信号传输的最大电缆长度为几十米,传输速率小于20KB/s。4.电平转换。鉴于AT89C51单片机的输入、输出电平均为TTL/CMOS电平,而计算机配置的是RS-232C标准串行接口,使用的是RS-232C标准电平,二者的电气规范不一致,因此要完成PC机与单片机的数据通信,必须进行电平转换。【任务实施】单片机与PC通信任务对应的程序代码如下:#include<reg52.h>#defineucharunsignedchar#defineuintunsignedint#defineN26ucharx;//uchardatatable[N];//暂存数组,可以将10改为你需要的数值chartable1[N];uintcnt=0;ucharsendFlag=0;//未发送数据时ucharreceFlag=0;//未接受到数据时uinti=0,j;voidserial_init(void){TMOD=0x20;//计时器1作为比特率发生器,方式2TH1=0xfd;TL1=0xfd;//装入初值TR1=1;//计时中断允许SM0=0;SM1=1;//串行口工作于方式2ES=1;//串行口中断允许PS=1;REN=1;//接收允许EA=1;//总中断允许}voidmain(){serial_init();//初始化

while(1){P2=table1[0];//显示数组的第一个元素

if(receFlag==1){

fasong();

receFlag=0;//发完了清标志

}}}voidserial()interrupt4{

ES=0;//关串口中断

if(RI){

table1[cnt]=SBUF;cnt++;

while(!RI);//等待接收完毕

if(cnt==N){cnt=0;receFlag=1;}

RI=0;//软件清除接收中断

}if(TI){TI=0;//发送完一个数据

sendFlag=0;//清标志位

}ES=1;//开串口中断

}【进阶提高】把任务3中接收到的从PC机发过来的数据,用数码管显示其ASCII码,比如发过来一个‘1’,显示的是31,发过来一个字符‘2’,显示的是32。录入下面程序,并调试运行。单片机与PC通信用数码管显示对应的程序代码如下:#include<reg52.h>#defineucharunsignedchar#defineuintunsignedint#defineN1ucharx;chartable1[N];//暂存数组uintcnt=0;ucharsendFlag=0;//未发送数据时ucharreceFlag=0;//未接受到数据时uinti=0,j;//共阳数码管段码ucharcodedis[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};voiddelayms(ucharms)//延时ms{uchari;while(ms--){for(i=0;i<120;i++);}}voidserial_init(void){TMOD=0x20;//计时器1作为比特率发生器,方式2TH1=0xfd;TL1=0xfd;//装入初值TR1=1;//计时中断允许SM0=0;SM1=1;//串行口工作于方式2ES=1;//串行口中断允许PS=1;REN=1;//接收允许EA=1;//总中断允许}voidsend_char(unsignedchartxd)//传送一个字符{ ES=0;SBUF=txd;while(!TI);//等特数据传送

sendFlag=1; ES=1;//清除数据传送标志}voidfasong(){//发送数组receive[];uchari;for(i=0;i<N;i++){send_char(table1[i]);}

}voiddisplay(){P1=0x01;P2=dis[table1[0]&0x0f];delayms(10);//个位显示P1=0x02;P2=dis[table1[0]/16];delayms(10);//十位显示}voidmain(){serial_init();//初始化

while(1){display();if(receFlag==1){fasong();receFlag=0;//发完了清标志

}}}voidserial()interrupt4{

ES=0;//关串口中断

if(RI){

table1[cnt]=SBUF;cnt++;while(!RI);//等待接收完毕

if(cnt==N){cnt=0;receFlag=1;}RI=0;//软件清除接收中断

}if(TI){TI=0;//发送完一个数据

sendFlag=0;//清标志位

}ES=1;//开串口中断

}任务四DS18B20温度采集系统【任务描述】

使用数字温度传感器DS18B20,将采集到的温度信息送单片机,单片机处理该实时温度信息后,通过串口送PC串口显示。【任务分析】1-wire单总线是Maxim全资子公司Dallas的一项专有技术。与目前多数标准串行数据通信方式,如SPI/I2C/MICROWIRE不同,它采用单根信号线,既传输时钟,又传输数据,而且数据传输是双向的。它具有节省I/O口线资源、结构简单、成本低廉、便于总线扩展和维护等诸多优点。【相关知识】一、温度传感器DS18B20DS18B20对应的程序代码如下:#include<reg52.h>#include<intrins.h>#define uchar unsignedchar#define uint unsignedint#define u8 unsignedchar#define u16 unsignedint#define u32 unsignedlongint#define uchar32unsignedlongcharunsignedintsdata;//测量到的温度的整数部分unsignedcharxiaoshu1;//小数第一位unsignedcharxiaoshu2;//小数第二位unsignedcharxiaoshu;//两位小数bitfg=1;//温度正负标志sbitP10=P1^0;sbitP11=P1^1;sbitP12=P1^2;//通信端口使用#define TX_0 P10=0#define TX_1 P10=1//uchar32*p=sort_temp;//=======================================//精确延时函数//=======================================//延时1us==用于在切换引脚电平时,等待引脚电平稳定voiddelay1us(void)//12MHz,12分频单片机{}//延时7us==读间隙产生后延时7us,然后单片机读取引脚电平voiddelay7us(void)//12MHz,12分频单片机{//调用占2个周期

_nop_();_nop_(); _nop_();_nop_();_nop_();}//延时15us==拉低500us复位后,18B20在15us后会发出存在脉冲voiddelay15us(void)//12MHz,12分频单片机{ //调用占2个周期

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();}//延时60us==产生写时序后,延时60us,等待18B20成功读取引脚电平voiddelay60us(void)//12MHz,12分频单片机{unsignedchara,b;for(b=11;b>0;b--)for(a=1;a>0;a--);}//延时500us==复位时用到voiddelay500us(void)//12MHz,12分频单片机{unsignedchara,b;for(b=99;b>0;b--)for(a=1;a>0;a--);}//========================//粗略可调延时函数//========================voiddelayms(u16ms){ while(ms--) {unsignedchara,b,c;for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--); }}voiddelay(void)//417us对应2400波特率{unsignedchara;for(a=206;a>0;a--);}//===========================//DS18B20读一个字节//===========================u8DS18B20_Read_Byte(void){ u8i; u8byte=0; for(i=0;i<8;i++) { byte>>=1; P11=0; delay1us(); P11=1; //上升沿产生读时间间隙

delay7us(); //至少7us以后,读取DS18B20数据,但也不能过大,例如延时15us就不正常了

if(P11) { byte|=0x80; } delay60us(); P11=1; //释放总线

} returnbyte;}//===========================//向DS18B20写一个字节//===========================voidDS18B20_Write_Byte(u8byte){ u8i=0; for(i=0;i<8;i++) { P11=0; //下降沿产生写时间间隙

delay1us(); if(byte&0x01) //把数据对应位的电平送到DQ引脚

{ P11=1;} else { P11=0;} delay60us(); //延时60us,等待DS18b20读取引脚电平

byte>>=1; P11=1; //释放总线

}}//===========================//复位DS18B20//===========================voidDS18B20_RST(void){ P11=1; delay1us(); P11=0;delay500us(); //拉低500us,复位信号

P11=1; //DQ=1 delay15us(); //15us}//=============================//DS18B20存在检测返回0表示器件存在,1不存在//=============================u8DS18B20_Check(void){ u8revalue=0; u8times=0; while(times<240&&(P11!=0)) //检测到低电平跳出或者循环240次跳出

{ times++; delay1us(); } if(times>=240) revalue=1; elsetimes=0; while(times<240&&(P11==0)) //检测到高电平跳出

{ times++; delay1us(); } if(times<240) revalue=0; else revalue=1;

returnrevalue;}//===========================//读取DS18B20温度值//===========================floatDS18B20_Read_Temp(void){ intTEMP_INT; floatTEMP; u8H8,L8; DS18B20_RST(); //复位

DS18B20_Check(); DS18B20_Write_Byte(0xcc); //跳过ROM命令单个传感器所以不必读取ROM里的序列号

DS18B20_Write_Byte(0x44); //开始转换

DS18B20_RST(); //复位

DS18B20_Check(); DS18B20_Write_Byte(0xcc); //跳过ROM命令单个传感器所以不必读取ROM里的序列号DS18B20_Write_Byte(0xbe); //读寄存器,共九字节,前两字节为转换值

L8=DS18B20_Read_Byte(); //低8位

H8=DS18B20_Read_Byte(); //高8位

if(H8>0x7f)//最高位为1时温度是负

{L8=~L8;H8=~H8+1;//补码转换,取反加一

fg=1;//读取温度为负时fg=1} xiaoshu1=(L8&0x0f)*10/16;//小数第一位

xiaoshu2=(L8&0x0f)*100/16%10;//小数第二位

xiaoshu=xiaoshu1*10+xiaoshu2;//小数两位TEMP_INT=(H8<<8)|L8; //将高8位左移8位后与低8位相加【此处按位或相当于相加】 TEMP=TEMP_INT*0.0625; //默认为12位ADC对应的转换精度为0.0625 returnTEMP;}//===========================//DS18B20初始化配置引脚//===========================u8DS18B20_Init(void){ u8revalue='?'; DS18B20_RST(); revalue=DS18B20_Check(); if(revalue==0) { DS18B20_Read_Temp(); } returnrevalue;}voidSendByte(unsignedcharnum){ unsignedchari; TX_0; delay(); //起始位

for(i=0;i<8;i++) { if(num&0x01) //先发低位

TX_1; else TX_0; num>>=1; delay(); } TX_1; delay(); //停止}voidmain(){floattemp=0; // u8zhengs=0; u8xiaos=0; DS18B20_Init(); delayms(900); while(1) { temp=DS18B20_Read_Temp(); zhengs=temp; delayms(100); SendByte('T'); SendByte(':'); SendByte(zhengs/10%10+'0');

SendByte(zhengs%10+'0'); SendByte('.'); SendByte(xiaoshu1+'0'); SendByte(xiaoshu2+'0'); SendByte(10); //换行

SendByte(13); //回车

}}【进阶提高】将DS18B20采集到的信息上传给PC,先来实现串口助手发来的信息发送给单片机,然后保存于一数组里,然后将数组里面的东西发送给PC端,一发一收来检查数据的正确性.sbitrw=P0^6;//1602的读写控制线sbiten=P0^7;//1602的使能控制线sbitP11=P1^1;sbitP12=P1^2;//通信端口使用//uchar32*p=sort_temp;//=======================================//精确延时函数//=======================================//延时1us==用于在切换引脚电平时,等待引脚电平稳定voiddelay1us(void)//12MHz,12分频单片机{}//延时7us==读间隙产生后延时7us,然后单片机读取引脚电平voiddelay7us(void)//12MHz,12分频单片机{

//调用占2个周期

_nop_();_nop_(); _nop_();_nop_();_nop_();}//延时15us==拉低500us复位后,18B20在15us后会发出存在脉冲voiddelay15us(void)//12MHz,12分频单片机{ //调用占2个周期

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();}//延时60us==产生写时序后,延时60us,等待18B20成功读取引脚电平voiddelay60us(void)//12MHz,12分频单片机{unsignedchara,b;for(b=11;b>0;b--)for(a=1;a>0;a--);}//延时500us==复位时用到voiddelay500us(void)//12MHz,12分频单片机{unsignedchara,b;for(b=99;b>0;b--)for(a=1;a>0;a--);}//========================//粗略可调延时函数//========================voiddelayms(u16ms){ while(ms--) {unsignedchara,b,c;for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--); }}voiddelay(uintn)//延时函数{uintx,y;for(x=n;x>0;x--)for(y=110;y>0;y--);}//===========================//DS18B20读一个字节//===========================u8DS18B20_Read_Byte(void){ u8i; u8byte=0; for(i=0;i<8;i++) { byte>>=1; P11=0; delay1us(); P11=1; //上升沿产生读时间间隙

delay7us(); //至少7us以后,读取DS18B20数据,但也不能过大,例如延时15us就不正常了

if(P11) { byte|=0x80; } delay60us(); P11=1; //释放总线

} returnbyte;}//===========================//向DS18B20写一个字节//===========================voidDS18B20_Write_Byte(u8byte){ u8i=0; for(i=0;i<8;i++) { P11=0; //下降沿产生写时间间隙

delay1us(); if(byte&0x01) //把数据对应位的电平送到DQ引脚

{ P11=1;} else { P11=0;} delay60us(); //延时60us,等待DS18b20读取引脚电平

byte>>=1; P11=1; //释放总线

}}//=============================//DS18B20存在检测返回0表示器件存在,1不存在//=============================u8DS18B20_Check(void){ u8revalue=0; u8times=0; while(times<240&&(P11!=0)) //检测到低电平跳出或者循环240次跳出

{ times++; delay1us(); }

if(times>=240) revalue=1; else times=0; while(times<240&&(P11==0)) //检测到高电平跳出

{ times++; delay1us(); }if(times<240) revalue=0; else revalue=1;

returnrevalue;}//===========================//读取DS18B20温度值//===========================floatDS18B20_Read_Temp(void){ intTEMP_INT; floatTEMP; u8H8,L8; DS18B20_RST(); //复位

DS18B20_Check();

DS18B20_Write_Byte(0xcc); //跳过ROM命令单个传感器所以不必读取ROM里的序列号

DS18B20_Write_Byte(0x44); //开始转换

DS18B20_RST(); //复位

DS18B20_Check(); DS18B20_Write_Byte(0xcc); //跳过ROM命令单个传感器所以不必读取ROM里的序列号DS18B20_Write_Byte(0xbe); //读寄存器,共九字节,前两字节为转换值

L8=DS18B20_Read_Byte(); //低8位

H8=DS18B20_Read_Byte(); //高8位

TEMP_INT=(H8<<8)|L8; //将高8位左移8位后与低8位相加【此处按位或相当于相加】 TEMP=TEMP_INT*0.0625; //默认为12位ADC对应的转换精度为0.0625 returnTEMP;}//液晶开始/*********************************************************************************/ voidlcd_wcom(ucharcom)//1602写命令函数(单片机给1602写命令){//1602接收到命令后,不用存储,直接由HD44780执行并产生相应动作

rs=0;//选择指令寄存器

rw=0;//选择写

P2=com;//把命令字送入P2delay(5);//延时一小会儿,让1602准备接收数据

en=1;//使能线电平变化,命令送入1602的8位数据口

en=0;}voidlcd_wdat(uchardat)//1602写数据函数{rs=1;//选择数据寄存器

rw=0;//选择写

P2=dat;//把要显示的数据送入P2delay(5);//延时一小会儿,让1602准备接收数据

en=1;//使能线电平变化,数据送入1602的8位数据口

en=0;}voidlcd_init()

温馨提示

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

评论

0/150

提交评论