下载

1下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 单片机串口通信

单片机串口通信.doc

单片机串口通信

呆子
2011-09-24 0人阅读 举报 0 0 暂无简介

简介:本文档为《单片机串口通信doc》,可适用于工程科技领域

ATC串口编程ATC串口编程前言本文档是为单片机初学者写的有关串口通讯编程的说明文档。使用的单片机硬件是最通用的ATC单片机编程语言为c语言。本文档不是系统的介绍单片机知识的教程而是为了使您尽快掌握串口编程方法的技术说明。本文档前几部分大量内容摘自平凡老师的单片机教程此教程是单片机入门的良好教材但由于那本教程是由汇编语言描述的对于时间不充足的同学来说学习汇编会浪费一些时间所以我还是整理了我们要了解的内容写到了本文档中。对于时间比较充分也有兴趣学习汇编语言的同学可以先阅读平凡老师的“单片机教程”然后从本文档第六部分看起。该教程网址:http:wwwicsearchcompmcudpjjxndpjjxhtm我也已经下载了此教程存在本实验室电脑中。单片机的基本认识一台能够工作的计算机要有这样几个部份构成:CPU(进行运算、控制)、RAM(数据存储)、ROM(程序存储)、输入输出设备(例如:串行口、并行输出口等)。在个人计算机上这些部份被分成若干块芯片安装一个称之为主板的印刷线路板上。而在单片机中这些部份全部被做到一块集成电路芯片中了所以就称为单片(单芯片)机而且有一些单片机中除了上述部份外还集成了其它部份如ADDA等。天!电脑中的CPU一块就要卖上千块钱这么多东西做在一起还不得买个天价!再说这块芯片也得非常大了。不价格并不高从几元人民币到几十元人民币体积也不大一般用脚封装当然功能多一些单片机也有引脚比较多的如引脚功能少的只有多个或多个引脚有的甚至只只引脚。为什么会这样呢?功能有强弱另外这种芯片的生产量很大技术也很成熟系列的单片机已经做了十几年所以价格就低了。既然如此单片机的功能肯定不强干吗要学它呢?话不能这样说实际工作中并不是任何需要计算机的场合都要求计算机有很高的性能一个控制电冰箱温度的计算机难道要用P?应用的关键是看是否够用是否有很好的性能价格比。实现一个发光二极管的闪烁体会对单片机的c语言编程买回来一块c单片机要想使用它首先要做必要的连线。我们实验室通常会给我们提供已经接好线的板子所以我们不必自己去连线这里需要说明的一点是一块单片机要工作起来首先需要复位所谓复位就是在单片机的RST引脚持续的加上两个机器周期的高电平使单片机回到工作的状态。(机器周期在串口波特率的计算中介绍)我做实验时使用的板子是一块较复杂的板子的一部分那块板子的复位方式是其他器件的程序给单片机复位可是我做实验时那个器件不需要工作所以单片机一直不能复位。如果你遇到这种情况请按任何一本书上介绍的加电复位选择合适的电容和电阻按书上的连线图焊接好如果你用的是我以前用过的板子这块板子已经接好了复位电路无须多考虑。请打开一本单片机的书找到单片机的引脚图。我们用的板子在p脚接有一个发光二极管当p为高电压时二极管点亮为低电压时二极管熄灭。我们现在想让小灯每隔s闪烁一次实际上就是要灯亮s再灭s也就是说要P不断地输出高和低电平。怎样实现这个要求呢?我们首先给出程序然后对照程序分析。实验程序开始#include<regh>//c单片机编程特有的头文件#defineuintunsignedint#defineucharunsignedcharsbitP=P^sbit是单片机c程序新的关键字用于定义位变量voidDelay(uinti)延时程序i是时间参数{uintjfor(i>i)for(j=j<j){}}voidmain(){for(){P=单片机内部给p脚加低电平关闭小灯Delay()延时sP=单片机内部给p脚加高电平点亮小灯Delay()延时S}}在以上程序中我们可以看出p=这条语句的含义就是p加高电压这个高电压不是v而是v。p=则是p加低电压。为什么是p=是给p加v电压而不是v我们不用管。现在从主函数看起主函数内部是个for循环此循环是让程序不停的在循环体内部转圈。循环体中首先让灯暗然后调用延时函数delay此函数的作用是延时s然后点亮小灯然后又是延时延时完了进入下一次的循环……这样程序就每隔s就给p加一次电压加的电压高低更替并且永远循环下去。其结果是让小灯不停的闪烁。Delay函数纯粹是用软件的运行来消耗时间以达到延时的目的至于为什么参数是时延时为s以后再谈。写好了程序下一步我们的任务是把程序烧写到单片机的存储器中去但是单片机是不认识c语言的所以需要我们预先编译成单片机认识的hex格式文件此步骤用keilc软件。然后将hex文件用编程器写到单片机里把单片机插回板子加上电就可以看到小灯在闪烁了。Keilc和编程器的用法语言描述不太直观如果您没有用过建议您现场请教实验室其他同学。三、几个基本概念、位的含义通过上面的实验我们已经知道:一盏灯亮或者说一根线的电平的高低可以代表两种状态:和。实际上这就是一个二进制位因此我们就把一根线称之为一“位”用BIT表示。上面程序中的语句sbitP=P^中sbit就是定义位变量的新的关键字。、字节的含义一根线可以表于和两根线可以表达四种状态也就是可以表于到而三根可以表达计算机中通常用根线放在一起同时计数就可以表过到一共种状态。这根线或者位就称之为一个字节(BYTE)。为什么一个字节是位数而不是其它数这只是人为地规定。、存储器简介存储器就是用来存放数据的地方。它是利用电平的高低来存放数据的也就是说它存放的实际上是电平的高、低而不是我们所习惯认为的这样的数字。存储器按功能可以分为只读和随机存取存储器两大类。所谓只读从字面上理解就是只可以从里面读不能写进去它类似于我们的书本发到我们手回之后我们只能读里面的内容不可以随意更改书本上的内容。只读存储器的英文缩写为ROM(READONLYMEMORY)我们只有用编程器对之进行编程。所谓随机存取存储器即随时可以改写也可以读出里面的数据它类似于我们的黑板我可以随时写东西上去也可以用黑板擦擦掉重写。随机存储器的英文缩写为RAM(READRANDOMMEMORY)这两种存储器的英文缩写一定要记牢。、寄存器的认识单片机中的寄存器多数是八位的也就是每个寄存器可以放个二进制数每个二进制数就是一位了。下面的文档中会直接用到几个单片机中的特殊寄存器这些寄存器都有自己的名字如TMODSCONIPPSWACC等他们都有自己特定的功能我想等到用到那一个在说哪一个如果你不习惯可以去查单片机的书。、晶振频率、机器周期指令周期单片机是时序电路必然会有产生时序脉冲的装置这个任务交给了晶振。本实验用的晶振是MH的也就是每秒钟产生M个脉冲。单片机的机器周期是晶振振动周期的十二倍也就是十二分频。一个机器周期也就是/us大概是us。指令周期是一条指令的执行时间单片机中的指令周期按指令不同有单周期双周期和四周期指令等这些一般不用记用到了查单片机公司给的手册就可以了。、​ 记数器与定时器介绍鉴于初进实验室的同学可能尚未接触数字电路中计数器的概念-条对记述和定时作详细介绍如已学习过数字电路可快速浏览以下-条。、计数概念的引入从选票的统计谈起:画“正”。这就是计数生活中计数的例子处处可见。例:录音机上的计数器、家里面用的电度表、汽车上的里程表等等再举一个工业生产中的例子线缆行业在电线生产出来之后要计米也就是测量长度怎么测法呢?用尺量?不现实太长不说要一边做一边量呢怎么办呢?行业中有很巧妙的方法用一个周长是米的轮子将电缆绕在上面一周由线带轮转这样轮转一周不就是线长米嘛所以只要记下轮转了多少圈就可以知道走过的线有多长了。、计数器的容量从一个生活中的例子看起:一个水盆在水龙头下水龙没关紧水一滴滴地滴入盆中。水滴不断落下盆的容量是有限的过一段时间之后水就会逐渐变满。录音机上的计数器最多只计到…那么单片机中的计数器有多大的容量呢?c单片机中有两个计数器分别称之为T和T这两个计数器分别是由两个位的RAM单元组成的即每个计数器都是位的计数器最大的计数量是。、定时c中的计数器除了可以作为计数之用外还可以用作时钟时钟的用途当然很大如打铃器电视机定时关机空调定时开关等等那么计数器是如何作为定时器来用的呢?一个闹钟我将它定时在个小时后闹响换言之也可以说是秒针走了()次所以时间就转化为秒针走的次数的也就是计数的次数了可见计数的次数和时间之间的确十分相关。那么它们的关系是什么呢?那就是秒针每一次走动的时间正好是秒。结论:只要计数脉冲的间隔相等则计数值就代表了时间的流逝。由此单片机中的定时器和计数器是一个东西只不过计数器是记录的外界发生的事情而定时器则是由单片机提供一个非常稳定的计数源。提供给定时器的计数源是由单片机的晶振经过分频后获得的一个脉冲源(分频是指晶振频率的分之一)。晶振的频率当然很准所以这个计数脉冲的时间间隔也很准。例如一个M的晶振它提供给计数器的脉冲时间间隔是M等于M也就是记数周期为个微秒。结论:计数脉冲的间隔与晶振有关M的晶振计数脉冲的间隔是微秒。、溢出让我们再来看水滴的例子当水不断落下盆中的水不断变满最终有一滴水使得盆中的水满了。这时如果再有一滴水落下就会发生什么现象?水会漫出来用个术语来讲就是“溢出”。水溢出是流到地上而计数器溢出后将使得TF变为“”。至于TF是什么我们稍后再谈。一旦TF由变成就是产生了变化产生了变化就会引发事件就象定时的时间一到闹钟就会响一样。至于会引发什么事件我们下次再介绍现在我们来研究另一个问题:要有多少个计数脉冲才会使TF由变为。、任意定时及计数的方法刚才已研究过计数器的容量是位也就是最大的计数值到因此计数计到就会产生溢出。这个没有问题问题是我们现实生活中经常会有少于个计数值的要求如包装线上一打为瓶一瓶药片为粒怎么样来满足这个要求呢?我们采用预置数的方法我要计那我就先放进再来个脉冲不就到了了吗。定时也是如此每个脉冲是微秒则计满个脉冲需时毫秒但现在我只要毫秒就可以了怎么办?个毫秒为个微秒所以只要在计数器里面放进就可以了。、计数/定时器的方式控制字我们上面说过c中有两个计数/定时器T和T每个计数器都有两个八位寄存器即是十六位的寄存器。TH、TL分别是计数器T的高八位和低八位存储区TH、TL分别是计数器的高八位和低八位存储区。在单片机中有两个特殊功能寄存器与定时计数有关这就是TMOD和TCON。TMOD和TCON是寄存器的名称我们在写程序时就可以直接用这个名称来指定它们。GATECTMMGATECTMM图寄存器TMOD示意图SMSMSMRENTBRBTIRI图串行口控制寄存器SCON:示意图从图中我们可以看出TMOD被分成两部份每部份位。分别用于控制TT(前四位控制T后四位控制T)至于这里面是什么意思我们下面介绍。可以看出TCON也被分成两部份高位用于定时计数器低位则用于中断(我们暂不管)。而TF()我们上节课已提到了当计数溢出后TF()就由变为。原来TF()在这儿!TR、TR分别是控制T和T工作状态的位。我们用图来讨论以下问题:、​ MM:定时计数器一共有四种工作方式就是用MM来控制的位正好是四种组合(方式方式方式方式)。、​ CT:前面我们说过定时计数器即可作定时用也可用计数用到底作什用由我们根据需要自行决定也说是决定权在我们编程者。如果CT为就是用作定时器如果CT为就是用作计数器。、​ GATE:门控信号GATE=时定时器计数器的启动受到双重控制即要求TRTR和INTINT同时为高电平时定时器计数器才可工作。GATE=时TC的启动仅受TR或TR控制。看到这里,我们先不管四种工作方式是什么意思,我们举例讨论两个计数定时器和工作方式的选择。例如如果我们要使T工作在方式那么只需要给MM赋值(见上面第一点)我们还想只用TR控制T那么给GATE赋即可(见以上第三点)如果我们把T用做一个定时器则给CT赋就可以了(见以上第二点条)。T部分我们先不使用全部赋值。给这么好几个东西赋值其实只需要一条c语言语句。对照着表一我们只需要把二进制数赋给寄存器TMOD即可实现以上全部的赋值。而二进制数就是十六进制数x(x为十六进制数的标志)。所用的赋值语句为:TMOD=x。简单吧?现在只需要一条语句TR=就可以启动定时器使其工作起来了。下面我们来介绍定时/计数器的四种工作方式。、​ 方式(MM=)定时器计数器的工作方式称之为位定时计数方式。它由TL()的低位和TH()的位构成位的计数器此时TL()的高位未用。、​ 方式(MM=)工作方式是位的定时计数方式将MM设为即可其它特性与工作方式相同。满计数值是的次方。、​ 工作方式(MM=)在介绍这种式方式之前先让我们思考一个问题:上一次课我们提到过任意计数及任意定时的问题比如我要计个数可是位的计数器要计到才满怎么办呢?我们讨论后得出的办法是用预置数先在计数器里放上再来个脉冲不就行了吗?是的但是计满了之后我们又该怎么办呢?要知道计数总是不断重复的流水线上计满后马上又要开始下一次计数下一次的计数还是吗?当计满并溢出后计数器里面的值变成了(为什么可以参考前面课程的说明)因此下一次将要计满后才会溢出这可不符合要求怎么办?当然办法很简单就是每次一溢出时执行一段程序可以在这段程序中做把预置数送入计数器中的事情。所以采用工作方式或都要在溢出后做一个重置预置数的工作做工作当然就得要时间软件也要费一些事情,为了省时省力,有了此种方式:自动再装入预置数的工作方式。既然要自动得新装入预置数那么预置数就得放在一个地方要不然装什么呢?那么预置数放在什么地方呢?它放在T()的高位这样高位不就不参与计数了。在工作方式中只有低位参与计数而高位不参与计数用作预置数的存放这样计数范围就小多了当然做任可事总有代价的关键是看值不值如果我根本不需要计那么多数那么就可以用这种方式。每当计数溢出高八位中的预置的数值自动进入低位。这是由硬件自动完成的不需要由人工干预。通常这种式作方式用于波特率发生器也是本文档程序中用的最多的一种方式。用于这种用途时定时器就是为了提供一个时间基准。计数溢出后不需要做事情要做的仅仅只有一件就是重新装入预置数再开始计数而且中间不要任何延迟可见这个任务用工作方式来完成是最妙不过了。定时器计数器的定时计数范围工作方式:位定时计数方式因此最多可以计到的次方也就是次。工作方式:位定时计数方式因此最多可以计到的次方也就是次。工作方式和工作方式都是位的定时计数方式因此最多可以计到的次方也说是次。预置值计算:用最大计数量减去需要的计数次数即可。例:流水线上一个包装是盒要求每到盒就产生一个动作用单片机的工作方式来控制应当预置多大的值呢?对了就是=。以上是计数明白了这个道理定时也是一样。这在前面的课程已提到我们不再重复请参考前面的例子。下面我们用定时器实现小灯的闪烁来放松一下。如果想要小灯每隔s闪烁一次如前面所述也就是让P每隔s改变一次电平的高低。前面的实验是纯粹用软件来消磨时间这次我们用定时器来预定时间控制P的电平。定时器的方式是自动装入预置数的八位定时器最大定时间隔是计满的次方也就是计满个数就要溢出并开始下一次定时。前面提到M的晶振提供的计数周期是us那么最大的定时间隔是*us=us显然如果这样短的时间小灯就闪烁一次的话那么人眼是分辨不出来的。怎样获得更大的时间间隔呢?可以采用软件计数的办法也就是说预先设置一个变量,每当一个定时周期到了不急于给p赋值而是先给变量加一,当这个变量达到某一个数值时,就给p电平取反比如在以下程序中我们准备让小灯每隔s闪烁一次则*=也就是说如果预先设置变量的值从零变到这时候就标志着s的时间间隔到了就可以给p赋值了。在执行中每次定时器定时时间到了总要执行几条语句执行这些语句也需要一定时间当然相对于个计数周期这些时间是不长的为了明确概念初学者可以先不仔细算。本程序中我们取软件计数到时电平变化以补偿代码执行的时间。说了这么多如果你已经不知道我再说什么了那请看完以下程序在看上面这段话。实验二#include<regh>//头文件#defineuintunsignedintsbitP=P^//定义P^为位变量Pvoidmain(void){uintk=//定义用于软件计数的变量k并赋初值TMOD=x//使用定时器的方式TR=//启动定时器P=//给P赋初值关闭小灯TH=XTL=X//装载计数初值while()//不停的循环{while(!TF)//检查是否定时器溢出如溢出则向下执行TF=//溢出标志位清while(k==)//当定时器溢出次时进入循环体{P=!P//使P电位反向控制小灯明暗k=//软件计数标志清零准备下一次计数}}}由以上的程序我们可以看出使用计数/定时器的一般步骤为:、​ 确定TC的工作方式――编程TMOD寄存器、​ 计算TC中的计数初值并装载到TH和TL、​ TC在中断方式工作时须开CPU中断源――编程IE寄存器(下节讲)、​ 启动定时/计数器――编程TCON中的TR和TR位。上面第三条中提到中断休息一会我们来看单片机中另一个重要的内部资源――中断。五、中断介绍、有关中断的概念什么是中断我们从一个生活中的例子引入。你正在家中看书突然电话铃响了你放下书本去接电话和来电话的人交谈然后放下电话回来继续看你的书。这就是生活中的“中断”的现象就是正常的工作过程被外部的事件打断了。仔细研究一下生活中的中断对于我们学习单片机的中断也很有好处。第一、什么可经引起中断生活中很多事件可以引起中断:有人按了门铃了电话铃响了你的闹钟闹响了你烧的水开了…等等诸如此类的事件我们把可以引起中断的称之为中断源单片机中也有一些可以引起中断的事件c中一共有个:两个外部中断两个计数定时器中断一个串行口中断。第二、中断的嵌套与优先级处理:设想一下我们正在看书电话铃响了同时又有人按了门铃你该先做那样呢?如果你正是在等一个很重要的电话你一般不会去理会门铃的而反之你正在等一个重要的客人则可能就不会去理会电话了。如果不是这两者(即不等电话也不是等人上门)你可能会按你通常的习惯去处理。总之这里存在一个优先级的问题单片机中也是如此也有优先级的问题。优先级的问题不仅仅发生在两个中断同时产生的情况也发生在一个中断已产生又有一个中断产生的情况比如你正接电话有人按门铃的情况或你正开门与人交谈又有电话响了情况。考虑一下我们会怎么办吧。第三、中断的响应过程:当有事件产生进入中断之前我们必须先记住现在看书的第几页了或拿一个书签放在当前页的位置然后去处理不同的事情(因为处理完了我们还要回来继续看书):电话铃响我们要到放电话的地方去门铃响我们要到门那边去也说是不同的中断我们要在不同的地点处理而这个地点通常还是固定的。计算机中也是采用的这种方法五个中断源每个中断产生后都到一个固定的地方去找处理这个中断的程序当然在去之前首先要保存下面将执行的指令的地址以便处理完中断后回到原来的地方继续往下执行程序。具体地说中断响应可以分为以下几个步骤:、保护断点即保存下一将要执行的指令的地址就是把这个地址送入堆栈。、寻找中断入口根据个不同的中断源所产生的中断查找个不同的入口地址。以上工作是由计算机自动完成的与编程者无关。在这个入口地址处存放有中断处理程序(这是程序编写时放在那儿的如果没把中断程序放在那儿就错了中断程序就不能被执行到)。、执行中断处理程序。、中断返回:执行完中断指令后就从中断处返回到主程序继续执行。MCS中断系统的结构:如图(抱歉本图请找本书看一下)所示由与中断有关的特殊功能寄存器、中断入口、顺序查询逻辑电路等组成包括个中断请求源个用于中断控制的寄存器IE、IP、ECON和SCON来控制中断。、中断请求源:()​ 外部中断请求源:即外中断和经由外部引脚引入的在单片机上有两个引脚名称为INT、INT也就是P、P这两个引脚。在内部的TCON中有四位是与外中断有关的。IT:INT触发方式控制位可由软件进和置位和复位IT=INT为低电平触发方式IT=INT为负跳变触发方式。这两种方式的差异可暂不考虑。IE:INT中断请求标志位。当有外部的中断请求时这位就会置(这由硬件来完成)在CPU响应中断后由硬件将IE清。IT、IE的用途和IT、IE相同。()​ 内部中断请求源TF:定时器T的溢出中断标记当T计数产生溢出时由硬件置位TF。当CPU响应中断后再由软件将TF清。TF:与TF类似。TI、RI:串行口发送、接收中断在串口中再仔细讲解。、中断允许寄存器IE在MCS-中断系统中中断的允许或禁止是由片内可进行位寻址的位中断允许寄存器IE来控制的。见下表EAESETEXETEX中断允许寄存器IE示意表其中EA是总开关如果它等于则所有中断都不允许。ES-串行口中断允许:ES=串口允许中断ES=串口不允许中断。ET-定时器中断允许(以下的含义和ES的解释相同)EX-外中断中断允许。ET-定时器中断允许EX-外中断中断允许。如果我们要设置允许外中断定时器中断允许其它不允许则IE可以是EAESETEXETEX用c语句IE=xc即可完成上述对IE的编程。当然也可以分别对每一位编程:EA=ET=EX=、五个中断源的自然优先级外中断>定时器>外中断>定时器>串口优先级:单片机采用了自然优先级和人工设置高、低优先级的策略即可以由程序员设定那些中断是高优先级、哪些中断是低优先级由于只有两级必有一些中断处于同一级别处于同一级别的就由自然优先级确定。开机时每个中断都处于低优先级我们可以用指令对优先级进行设置。看下表。PSPTPXPTPX中断优先级寄存器IP示意表中断优先级中由中断优先级寄存器IP来设置的IP中某位设为相应的中断就是高优先级否则就是低优先级。例:设有如下要求将T、外中断设为高优先级其它为低优先级求IP的值。IP的首位没用可任意取值设为后面根据要求写就可以了PSPTPXPTPX因此最终IP的值就是十六进制数x。本串口通讯实验中因为只用到了串口中断所以没必要设优先级寄存器IP本段内容可以只作一般了解。、MCS-的中断响应过程:、中断响应的条件:讲到这儿我们依然对于计算机响应中断感到神奇我们人可以响应外界的事件是因为我们有多种“传感器“――眼、耳可以接受不同的信息计算机是如何做到这点的呢?其实说穿了一点都不希奇MCS工作时在每个机器周期中都会去查询一下各个中断标记看他们是否是““如果是就说明有中断请求了所以所谓中断其实也是查询不过是每个周期都查一下而已。这要换成人来说就相当于你在看书的时候每一秒钟都会抬起头来看一看查问一下是不是有人按门铃是否有电话。。。。很蠢不是吗?可计算机本来就是这样它根本没人聪明。了解了上述中断的过程就不难解中断响应的条件了。在下列三种情况之一时CPU将封锁对中断的响应:A、CPU正在处理一个同级或更高级别的中断请求。B、现行的机器周期不是当前正执行指令的最后一个周期。我们知道单片机有单周期、双周期、三周期指令当前执行指令是单字节没有关系如果是双字节或四字节的就要等整条指令都执行完了才能响应中断(因为中断查询是在每个机器周期都可能查到的)。C、正在执行的指令是返回批令(RETI)或访问IP、IE寄存器的指令则CPU至少再执行一条指令才应中断。这些都是与中断有关的如果正访问IP、IE则可能会开、关中断或改变中断的优先级而中断返回指令则说明本次中断还没有处理完所以都要等本指令处理结束再执行一条指令才可以响应中断。后两条理解不太直观没关系最重要的是第一条。、中断响应过程用c语言编程时我们不用中断具体怎样响应,我们只要在程序中预先设置好了有关中断的寄存器,那么一但出现了中断请求,单片机硬件会自动跳出主函数去执行中断函数。中断函数的格式为:返回值函数名interruptnn对硬中断源的编号。比如我们要设置一个串口的中断程序:voidchuankou(void)interrupt{。。。。。。}注意当程序中有两个以上中断源时要涉及到寄存器组切换的问题此时中断函数要写成voidchuankou(void)interruptusing{。。。。。。}由于本串口通讯实验只用一个中断源所以用不到寄存器组的切换故不再讲述。你可以在做完实验以后查阅单片机c语言的书籍。同样讲述完了中断我们用中断来做个程序程序的功能仍然是使小灯每隔s闪烁一次只不过这次用中断来做。我们用定时器的中断来做由于前面提到的原因定时间隔太小小灯闪烁不明显要用到“软件计数器”本例中同样要遇到这种情况。请看程序:实验三#include<regh>头文件#defineuintunsignedintuinti=sbitP=P^定义P^为位变量Pvoidtimer(void)interrupt用定时器的中断,此中断的编号是{TF=清除定时器的中断标志While(i==)当中断(每隔s左右)次时进入循环体{P=!PP电平取反,控制小灯闪烁i=软件计数标志清零}}voidmain(void){TMOD=x设置定时器的工作方式TH=oxTL=x预置计数初值IE=x打开定时器的中断,开总中断TR=定时器开始工作While()无限循环,实际工作中此处可加其他功能的代码(注){}}这是用中断来实现的对小灯闪烁的控制没有中断发生时程序一直在主函数的空循环里空转圈当定时器溢出TF置一时(由硬件完成)硬件自动向cpu提出中断的请求cpu自动的跳出主函数去执行中断函数中的代码执行完中断以后又回到主函数。请注意此处的中断函数和一般的子函数不同一般的子函数须要主函数来调用而中断函数是一但有中断发生硬件自动执行中断中的代码这个过程是硬件自动实现的无须人工调用。以上这个程序和前面的程序所不同的是,程序不只是可以控制小灯,还可以在注出的while空循环处加入具有其他功能的代码。到现在串口通讯的前期准备工作基本完成你可以有很多地方不理解没关系只要你感觉对单片机的c编程有了一个基本的认识基本上掌握了大致的思路那么请接着看下一部分:串口通讯概念和基本实验。如果你感觉还是对单片机很模糊建议你直接去看平凡老师的教程和北航的“单片机的c语言程序设计”教程。(教研室有这本书)串口通讯概念和基本实验、串行接口的一般概念单片机与外界进行信息交换称之为通讯。c单片机的通讯方式有两种:A、并行通讯:数据的各位同时发送或接收。本文档不涉及并行通讯只将串行通讯。B、串行通讯:数据一位一位顺序发送或接收。串行通讯的方式:异步通讯:它用一个起始位表示字符的开始用停止位表示字符的结束。其每帧的格式如下:在一帧格式中先是一个起始位然后是个数据位规定低位在前高位在后接下来是奇偶校验位(可以省略)最后是停止位。用这种格式表示字符则字符可以一个接一个地传送。在异步通讯中CPU与外设之间必须有两项规定即字符格式和波特率。字符格式的规定是双方能够在对同一种和的串理解成同一种意义。原则上字符格式可以由通讯的双方自由制定但从通用、方便的角度出发一般还是使用一些标准为好如采用ASCII标准。波特率即数据传送的速率其定义是每秒钟传送的二进制数的位数。例如数据传送的速率是字符s而每个字符如上述规定包含数位则传送波特率为波特。同步通讯:在同步通讯中每个字符要用起始位和停止位作为字符开始和结束的标志占用了时间所以在数据块传递时为了提高速度常去掉这些标志采用同步传送。由于数据块传递开始要用同步字符来指示同时要求由时钟来实现发送端与接收端之间的同步故硬件较复杂。本文档不讨论同步通讯。.c单片机的串行接口结构c单片机通过引脚RXD(P串行数据接收端)和引脚TXD(P串行数据发送端)与外界通讯。SBUF是串行口缓冲寄存器包括发送寄存器和接收寄存器。它们有相同名字和地址空间但不会出现冲突因为它们两个一个只能被CPU读出数据一个只能被CPU写入数据。所以语句SBUF=SBUF是有意义的。它并不是将本身的值赋给了本身而是将一个寄存器的值赋给了另一个寄存器并且单片机不会搞错哪个是发送的哪个是接受的。、串行口的控制与状态寄存器​ 串行口控制寄存器SCON它用于定义串行口的工作方式及实施接收和发送控制。其各位定义如下表:SMSMSMRENTBRBTIRI串口控制寄存器SCON示意表各位的说明如下SMSM:工作方式控制位(其中fosc为晶振频率)SMSM工作方式说明波特率同步移位寄存器Fosc位异歩收发由定时器控制位异步收发Fosc或Fosc位异步收发由定时器控制注意由于实验条件本文档只有方式和方式的例程。SM:多机通讯控制位。本文档不使用编程时置即可。REN:接收允许控制位。由软件置位以允许接收又由软件清来禁止接收。TB:是要发送数据的第位。在方式或方式中要发送的第位数据根据需要由软件置或清。例如可约定作为奇偶校验位或在多机通讯中作为区别地址帧或数据帧的标志位。RB:接收到的数据的第位。在方式中不使用RB。在方式中若(SM)=RB为接收到的停止位。在方式或方式中RB为接收到的第位数据。TI:发送中断标志。在方式中第位发送结束时由硬件置位。在其它方式的发送停止位前由硬件置位。TI置位既表示一帧信息发送结束同时也是申请中断可根据需要用软件查询的方法获得数据已发送完毕的信息或用中断的方式来发送下一个数据。TI必须用软件清。RI:接收中断标志位。在方式当接收完第位数据后由硬件置位。在其它方式中在接收到停止位的中间时刻由硬件置位(例外情况见于SM的说明)。RI置位表示一帧数据接收完毕可用查询的方法获知或者用中断的方法获知。RI也必须用软件清。​ 电源控制寄存器PCON:SMOD此寄存器只有第一位SMOD和本文档有关。SMOD:串行口波特率加倍位――方式波特率=定时器溢出率方式波特率为Fosc。――方式波特率=定时器溢出率方式波特率为Fosc单片机的全双工串行口可编程为种工作方式现分述如下:方式为移位寄存器输入输出方式。本文档不用故不叙述有兴趣的话可以看教程。方式为波特率可变的位异步通讯接口方式。发送或接收一帧信息包括个起始位个数据位和个停止位。输出:当CPU执行一条指令将数据写入发送缓冲SBUF时就启动发送。串行数据从TXD引脚输出发送完一帧数据后就由硬件置位TI。输入:在(REN)=时串行口采样RXD引脚当采样到至的跳变时确认是开始位就开始接收一帧数据。只有当(RI)=且停止位为或者(SM)=时停止位才进入RB位数据才能进入接收寄存器并由硬件置位中断标志RI否则信息丢失。所以在方式接收时应先用软件清零RI和SM标志。方式方式为固定波特率的位异步通讯接口方式。它比方式增加了一位可程控为或的第位数据。输出:发送的串行数据由TXD端输出一帧信息为位附加的第位来自SCON寄存器的TB位用软件置位或复位。它可作为多机通讯中地址数据信息的标志位也可以作为数据的奇偶校验位。当CPU执行一条数据写入SUBF的指令时就启动发送器发送。发送一帧信息后置位中断标志TI。输入:在(REN)=时串行口采样RXD引脚当采样到至的跳变时确认是开始位就开始接收一帧数据。在接收到附加的第位数据后当(RI)=或者(SM)=时第位数据才进入RB位数据才能进入接收寄存器并由硬件置位中断标志RI否则信息丢失。且不置位RI。再过一位时间后不管上述条件时否满足接收电路即行复位并重新检测RXD上从到的跳变。工作方式方式为波特率可变的位异步通讯接口方式。除波特率外其余与方式相同。、波特率的选择如前所述在串行通讯中收发双方的数据传送率(波特率)要有一定的约定。在C串行口的四种工作方式中方式和的波特率是固定的而方式和的波特率是可变的由定时器T的溢出率控制。以下讨论中FOSC是晶振的频率。A、方式方式的波特率固定为晶振频率的。B、方式方式的波特率由PCON中的选择位SMOD来决定可由下式表示:波特率=的SMOD次方除以再乘一个fosc也就是当SMOD=时波特率为fosc当SMOD=时波特率为foscC、方式和方式定时器T作为波特率发生器其公式如下:波特率=定时器T溢出率乘的SMOD次方除以波特率=(^SMOD)*(定时器的溢出率)T溢出率=T计数率产生溢出所需的周期数式中T计数率的含义是:一秒钟计数的次数。它取决于它工作在定时器状态还是计数器状态。当工作于定时器状态时T计数率为fosc(即一个机器周期)当工作于计数器状态时T计数率为外部输入频率此频率应小于fosc。产生溢出所需周期与定时器T的工作方式、T的预置值有关。定时器T工作于方式:溢出所需周期数=x(X为预置数)定时器T工作于方式:溢出所需周期数=x定时器T工作于方式:溢出所需周期数=x因为方式为自动重装入初值的位定时器计数器模式所以用它来做波特率发生器最恰当。当时钟频率选用MHZ时容易获得标准的波特率所以很多单片机系统选用这个频率的晶振。好了先面我们给出串口初始化的过程前面讲的几个寄存器会在下面用到。串口初始化的歩骤:a)确定定时器的工作方式――编程TMOD寄存器b)计算定时器的初值――装载TH,TLc)启动定时器――编程TCON中的TR位d)确定串行口的工作方式――编程SCONe)​ 串行口在中断方式工作时须开CPU和源中断――编程IE寄存器。为了说明以上的基本过程,请看串口通讯的第一个实验。本实验的目的很简单就是从pc机向单片机发送数据然后单片机紧接着把pc发送的数据送回pc在显示器上显示出来。我们目前所要做的工作只是给单片机编程让单片机能够接收到pc发送的数据并且接收到pc发送的数据以后在送给pc至于pc怎样发送接受由串口调试助手来完成。串口调试助手要陪伴我们整个实验过程,让我们先认识一下吧从上图我们可以看见,左上角第一个设置是串口的选择,计算机上有两个串口,我也分不清那个是COM那个是COM,你可以试一下。波特率的设置必须和你已经写到单片机里的程序设置的波特率一致!校验位也要和单片机程序一至数据位是八位停止位是一位。一切设置好后在助手的下面的文本区填入要发送的数据点击发送后如果上面的大文本框内能够正确的显示出来的话实验就成功了。以后我们描述调试助手的设置用下面的格式:(波特率校验位数据位停止位)比如上图的设置描述为(n)其中n为无校验。下面请看程序:实验四#include<regh>头文件voidmain(void)主程序(判断单片机串口是否正常工作){unsignedcharaTMOD=x采用定时器的工作方式TL=xfd计算定时器的初值装载TL,THTH=Xfd波特率()=(^SMOD)*(定时器的溢出率)溢出速率=(计数速率)(TH)计数速率与TMOD寄存器中CT(TMOD)的状态有关。当CT=时计数速率为Fosc当CT=时计数速率取决与外部输入时钟频率但此频率不能超过Fosc。SCON=X允许串口接受数据工作方式为无奇偶校验位。PCON=x串口波特率不加倍。TR=启动定时器计数TR是TCONwhile(){while(RI==)判断串口缓冲区是否接受完数据(RI==表示接受完){}接受完了跳出循环,没接收完等待接受RI=硬件置位软件清零a=SBUF接受串口缓冲区数据。SBUF=a通过串口缓冲区向外发送数据。while(TI==)判断串口缓冲区是否发送完数据(TI=时表示发送完){发送完跳出循环,没发送完等待发送}TI=硬件置位软件清零。}}调试助手设置:(n,)把这个程序编译,烧进单片机,就可以通过调试助手向单片机发送数据了。上面的助手有一个自动发送的选项用这个选项可以方便调试过程。如果没有回显或显是不正确请检查:、​ 单片机是否插上了板子,并且给板子加上了电。、​ 串口调试助手的设置是否正确(波特率停止位校验位以及串口是否打开)、​ 程序是否烧写正确。上面的程序使用查询方式做得所谓查询就是单片机不停的查询RI是否为TI是否为。。。。。。这样单片机出了处理串口的数据别的什么都干不了了所以我们下面有了另一中方式――――中断方式。此种方式一旦串口请求中断就处理串口。其他时间单片机可以干别的事情。请看程序:实验五#pragmasmall//存储模式定义(一般不必深究)#include<regh>//头文件unsignedcharavoidinitmpu(void)//串口、中断、初始化设置子函数//MH晶振下波特率无奇偶校验{TMOD=x//定时器的工作方式TL=xfd//装载计数初值TH=xfdSCON=x//采用串口工作方式无奇偶校验PCON=x//串口波特率不加倍IE=x//开总中断开串口中断TR=//启动定时器}voidgetch(void)interrupt中断源编号为即串口中断{RI=清除中断标志硬件置位软件清零a=SBUF接受串口缓冲区数据。SBUF=a通过串口缓冲区向外发送数据。while(TI==)//判断是否发送结束:TI==为结束。{//等待发送结束}TI=//发送结束标志清零}voidmain(void)//主函数中断方式串口通讯{initmpu()//调用初始化串口子函数while()//无限空循环此处可以加其它功能{}}调试助手设置:(n,)上面这个程序就是用的中断方式我们说过中断方式可以同时做其它事情现在把上面的程序稍加改写请看边让小灯闪烁边进行串口通讯的程序。实验六#pragmasmall存储模式定义#include<regh>头文件unsignedcharasbitP=P^定义Pvoidinitmpu(void)串口、中断、初始化设置子函数MH晶振下波特率无奇偶校验{TMOD=x定时器的工作方式TL=xfd装载计数初值TH=xfdSCON=x采用串口工作方式无奇偶校验PCON=x串口波特率不加倍IE=x开总中断开串口中断TR=启动定时器}voidgetch(void)interrupt中断源编号为即串口中断{RI=清除中断标志硬件置位软件清零a=SBUF接受串口缓冲区数据。SBUF=a通过串口缓冲区向外发送数据。while(TI==)判断是否发送结束:TI==为结束。{等待发送结束}TI=发送结束标志清零}voidmain(void)主函数中断方式串口通讯{unsignedcharj,kP=initmpu()调用初始化串口子函数while()无限空循环此处可以加其它功能{for(j=j<j)for(k=k<k){}软件延时P=!P控制小灯}}调试助手设置:(n,)好了如果以上几个实验你都实验成功并且掌握了串口通讯的流程基本任务完成了下面一部分是我在做串口通讯实验时遇到的几个问题有的解决了有的还没有解决我都记录了下来请您参考。相信您如果认真的做了如下几个实验你将会对串口通讯有更深入一些的理解。有关串口通讯试验的几个问题的思考前一章中用的是串口的方式即无奇偶校验位如果想要加进奇偶校验就要采用方式或方式三。本实验采用方式三。前一章的实验全是用的是的波特率这是为了入门的方便。在实际的工作中对波特率是有更高要求的。单片机串口通讯的波特率高低对整个系统性能有着重要影响。所以能获得多高的稳定波特率、怎样获得较高的稳定的波特率是接下来要讨论的。​ 用查询方式实现的波特率(加奇偶校验)奇偶校验是为了发送接收数据的过程中不出错的一种设置。其基本思想是:计算出发送的每一帧数据“”的个数如果为奇数个则校验位置如果为偶数个则校验位置这样每帧数据加上自己的校验位的个数都是偶数个。此种方式叫偶校验。反之是奇校验。在单片机中硬件自己可以进行奇偶校验。单片机的PSW寄存器的P位就是用来做奇偶校验的。当累加寄存器ACC(是八位寄存器)中的个数是奇数时P的值是当ACC中的个数是偶数时P的值是。这样其实硬件自己完成了偶校验。累加器ACC示意表当ACC中的值按如上设置时PSW中的P位应是。我们前面提到过串口控制寄存器SCON中的TB位用于发送校验位只要把硬件统计出来的校验值赋给TB就可以了。C语句实现如下:ACC=SBUFTB=P奇偶校验中每一帧数据格式如下:起始数据。。。。。。。。。。。。。。。。。。数据校验停止其中的校验位就是TB的数据。奇偶校验的实现过程是这样的(以偶校验为例):串口调试助手每发送一个字节(位)数据就统计这八位中的个数并且自己记录下。单片机收到这个字节的位数据后把它放进ACC然后把P的值给发送的第九位TB串口调试助手接收到单片机送回的一帧数据后检测TB看是否和自己刚才计算的校验值相等如相等则此帧数据发送回显正确如不等则回显是错误的。好了有了这些请看以下程序:实验七#include<regh>voidmain(void)波特率加偶校验采用查询方式{TMOD=x定时器方式TL=xff置数,波特率TH=xffSCON=xd串口工作方式有奇偶校验PCON=x波特率加倍TR=启动定时器while()无限循环{while(RI==)等待接收完毕{}RI=清除接收标志ACC=SBUF将接收到的数据送给累加器ACCTB=P将校验位赋给要发送的第九位SBUF=ACC向pc发送刚接收到的数据while(TI==)等待发送结束{}TI=清零结束标志}}调试助手设置:(e,)经调试查询方式可以达到的波特率并且可以加奇偶校验这就是说比以前的的

VIP免券下载文档

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/26

单片机串口通信

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利