发新话题
打印

[分享] 【高手坐堂】之万人学习51单片机!

本主题由 soso 于 2008-11-27 15:10 解除置顶

【高手坐堂】之万人学习51单片机!


请点击图片放大,查看详情

获奖网友名单公布:(学习光盘近期赠送,请您注意查收。谢谢大家的参与!让我们共同进步,谢谢!)


在此劳烦大家将各位的具体通讯地址:如电话,邮编,姓名,地址(因为是快递所以请不要写邮箱)发到wangtingting@eeworld.com.cn中,谢谢大家!


springvirus  在这里感谢 springvirus 长期,持之以恒的关注,而且给了我们许多非常好的建议,值得我们借鉴与思考,springvirus总说自己是
菜鸟,但我想也是eeworld的super 菜鸟~ 希望,通过大家在一起一系列的学习,由菜鸟变成大虾哦~

xhrabbit  姗姗,年纪虽小,可是学识渊博,有自己的思想,在技术方面也有自己的认识与见解,小朋友非常刻苦也非常可爱,大家看看姗姗的帖子,会立刻喜欢上这个小姑娘的!姗姗,Fighting~~

wang7588038 我们已经推出了关于AVR方面的系列讲座,链接如下,知道你非常希望得到这方面的知识,我们论坛就马上动手准备啦,
【高手坐堂】之让我们学学AVR! (m16;led流水灯;外部中断;定时器;串口中断)http://bbs.eeworld.com.cn/thread-66668-1-1.html   多多关注啊!

pflysky pflysky小朋友期待关于ARM的课程,我们也是在筹划之中了,计日可待。

njxiii 什么问题继续问,我会随时回答你的问题的,打破砂锅问到底的精神值得肯定!

sungodmg
ARM讲座马上展开,看来大家都等不及了,希望我们越办越好吧!





老练讲座的PDF文档:




老练讲座继续更新:

9.22  “单片机复位电路分析专题”
http://bbs.eeworld.com.cn/thread-66492-1-1.html

9.23  51上面也能跑操作系统了啊
http://bbs.eeworld.com.cn/viewthread.php?tid=66531

热心朋友ZQK推荐的单片机教程伟纳 平凡老师的教程)



成都理工大单片机课件
http://bbs.eeworld.com.cn/viewthread.php?tid=66883&pid=117889&page=1&extra=#pid117889






【高手坐堂】之万人学习51单片机! 老练全部教程整理:




第一部分 IO知识培训(09.12)

  单片机的IO口控制单片机初学者最为关心的问题,如何快速学会使用IO是初学者最为困难的地方。

  众多的教科书上面介绍了很多IO的原理,这些长篇大论让很多初学者看起来难以理解,同时也会止步于单片机门外。我们现在所要学习的使用IO就是很简单的使用就可以了,IO无非就是4种状态,输出为高、输出为低、输入为高、输入为低。

  我们只要把握这四个方面就可以了,先看看我们的单片机接口,单片机共有32个io。分别为P0、P1、P2、P3口,P0口如果当作IO来使用时,必须要使用上拉电阻,因为51单片机内部没有上拉这一功能。


  在这个学习板上面,大家可以看到40个io对应的位置,并且在数码管下面就增加了上拉电阻,使得io可以实现。
现在我们以P1口接的led指示灯来说明输出高低电平的功能,当我们使用汇编程序:

ORG 0000H
LJMP MAIN
ORG 0100H
MAIN:  MOV P1,#00H
        JMP  MAIN
        END

  这样,P1口的led就会变亮,因为P1口赋值#00h以后,就是将led的所有io都设置为低电平了。

  如果将MOV P1,#00H改成MOV P1,#0FFH,那么io就设置成了高电平,led就会被熄灭。当然C51中也比较简单。

#include <reg51.h>
Main()
{
P1=#00H;
While(1)
{;}
}

  这个同样的道理,如果P1=#0FFH,就是熄灭led。

  当我们对键盘的程序如下图解释:



  这个就是我们板子上面的键盘的接线图,当我们单独使用键盘的时候,我们要将P3.4置低电平,此时,我们也是根据前面led设置io的方式进行设置。

  如下程序:

    ORG  0000H
  JMP   MAIN
ORG  0100H
MAIN: CLR   P3.4
        MOV  P1,#0FFH
JNB   P2.7, MAIN
  MOV P1,#00H
        JMP    MAIN
        END
C51中:
       #include <reg51.h>
       Main()
       {
        P3^4=0;
While(1)
        {
          P1=0x0FF;
while(P2^7==0)
          {
P1=0x00;
}
}
}

  从这2个程序都可以看出io为低电平和高电平的效果。
附件: 您所在的用户组无法下载或查看附件
第二讲
单片机外部中断使用 (09.16)


  很多人都知道51单片机中中断的重要性,但是书中的长篇累牍让我们一下子理解有点很不适应。所以我们尽可能简化51单片机的中断,目前我们是要学会单片机中断的使用就可以了,而不是从原理基本说起。

  在51单片机中有2个外部中断,这两个外部中断口处于低电平的时候开始触发中断信号,使得程序可以进入中断处理中断部分的程序。

  我们还是老规矩,先看看硬件电路:

 



  在图上的单片机原理图中,S0,S1分别接的是单片机的外部中断1和外部中断2,我们特意将两个发光二极管放在上面进行指示,以便我们可以看到中断运行的情况,此时我们可以设置中断程序的要求:

1、 指示灯平时没有中断按下的时候不进行工作,保持原有状态;

2、 当外部中断0响应的时候,我们就点亮D0,让外部中断0响应的条件就是按下S0按键。

  下面就是汇编程序:

      ORG    0000H
      LJMP   MAIN        ;主程序
      ORG    0003H
      LJMP    W_INT0      ;进入中断子程序
  ORG    0100H
MAIN:MOV SP, #50H         ;设置堆栈指针
     SETB    EA          ;CPU所有中断开(IE最高位MSB)
     SETB    EX0         ;INT0中断开
     CLR     IT0          ;INT0低电平触发(为1则为下降沿触发)
      MOV    P1,     #0FFH
      JMP     $
W_INT0:CLR   P1.0
        RETI
      END

如下是c51的程序:
//---------------------------------------------------
#include <reg51.h>
//---------------------------------------------------
//重定义I/0引脚名称
sbit led1=P1^0;
//---------------------------------------------------
//固定函数声明
void int_0();       //外部中断0
//---------------------------------------------------
void main(){
      P1=0X0FF;
      EA=1;               // CPU所有中断开(IE最高位MSB)
      EX0=1;              // INT0中断开
      IT0=0;              // INT0低电平触发(为1则为下降沿触发)
      while(1){
     {
     ;
     }
}
//-------------------------------------------------------------------
//INT0中断  由P3.2引脚产生
void int_0() interrupt 0 using 0
{
   led0=0;
}

      在上面的程序中,我们可以看出外部中断使用的方法,现在我们学会了使用中断0,那么我们现在开始学使用外部中断1吧。

  首先我们来设置程序的要求:

1、 外部中断0点亮D0,关闭D1

2、 外部中断1点亮D1,关闭D0

      我们先看看汇编语言的程序:
;---------------------------------------------------------------------
        LED0      EQU   P1.0
        LED1      EQU   P1.1
        ORG   0000H
        LJMP   main
        ORG   0003H
        LJMP   W_INT0      
        ORG   00013H
        LJMP    W_INT1
        ORG        0100H
main:
        SETB    EA          ;CPU所有中断开(IE最高位MSB)
        SETB    EX0         ;INT0中断开
        CLR     IT0         ;INT0低电平触发(为1则为下降沿触发)
        SETB    EX1         ;INT1中断开
        CLR     IT1         ;INT1低电平触发(为1则为下降沿触发)
        MOV    P1,  #0FFH
       JMP     $
W_INT0:
        SETB    LED1            ;关闭LED1
        CLR     LED0     ;点亮LED0
        RETI
W_INT0:
        CLR     LED1            ;点亮LED1
        SETB    LED0     ;关闭LED0
        RETI
END

    这是c51的程序:

//---------------------------------------------------
#include <reg51.h>
//---------------------------------------------------
//重定义I/0引脚名称
sbit LED0=P1^0;
sbit LED1=P1^1;
//---------------------------------------------------
//固定函数声明
void int_0();       //外部中断0
void int_1();       //外部中断1
//---------------------------------------------------
void main(){
     EA=1;               // CPU所有中断开(IE最高位MSB)
     EX0=1;              // INT0中断开
     IT0=0;              // INT0低电平触发(为1则为下降沿触发)
     EX1=1;              // INT1中断开
     IT1=0;              // INT1低电平触发(为1则为下降沿触发)
    while(1){
      {
        ;
}
}
//-------------------------------------------------------------------
void initial(){
     EA=1;               // CPU所有中断开(IE最高位MSB)
     EX0=1;              // INT0中断开
     IT0=0;              // INT0低电平触发(为1则为下降沿触发)
     EX1=1;              // INT1中断开
     IT1=0;              // INT1低电平触发(为1则为下降沿触发)
     return;
}
//-------------------------------------------------------------------
//INT0中断  由P3.2引脚产生
void int_0() interrupt 0 using 0
{
    Led1=1;             //关闭D1
    LED0=0;            //点亮D0
}
//-------------------------------------------------------------------
//INT1中断  由P3.3引脚产生
void int_1() interrupt 2 using 1
{
    LED0=1;          //关闭D0
    LED1=0;          //点亮D1
}

  这样,通过程序和实践,我们就可以很轻易学会了外部中断的使用方法。

有什么问题,欢迎大家随时提问啊!
附件: 您所在的用户组无法下载或查看附件
第三部分 定时器中断培训(09.17)

  关于定时器中断,我们简单介绍一下原理就可以了,因为具体介绍已经有很多资料都已经提供了。


  80C
51单片机内部设有两个16位的可编程定时器/计数器。可编程的意思是指其功能(如工作方式、定时时间、量程、启动方式等)均可由指令来确定和改变。在定时器/计数器中除了有两个16位的计数器之外,还有两个特殊功能寄存器(控制寄存器和方式寄存器)。我们可以看出,16位的定时/计数器分别由两个8位专用寄存器组成,即:T0由TH0和TL0构成;T1由TH1和TL1 构成。其访问地址依次为8AH-8DH。每个寄存器均可单独访问。这些寄存器是用于存放定时或计数初值的。此外,其内部还有一个8位的定时器方式寄存器 TMOD和一个8位的定时控制寄存器TCON。这些寄存器之间是通过内部总线和控制逻辑电路连接起来的。TMOD主要是用于选定定时器的工作方式; TCON主要是用于控制定时器的启动停止,此外TCON还可以保存T0、T1的溢出和中断标志。当定时器工作在计数方式时,外部事件通过引脚T0 (P3.4)和T1(P3.5)输入。定时计数器的原理:


当定时器/计数器为定时工作方式时,计数器的加1信号由振荡器的12分频信号产生,即每过一个机器周期,计数器加1,直至计满溢出为止。显然,定时器的定时时间与系统的振荡频率有关。因一个机器周期等于12个振荡周期,所以计数频率fcount=1/12osc。如果晶振为12MHz,则计数周期为:

T=1/(12×106)Hz×1/12=1μs


  这是最短的定时周期。若要延长定时时间,则需要改变定时器的初值,并要适当选择定时器的长度(如8位、13位、16位等)。
 


当定时器/计数器为计数工作方式时,通过引脚T0和T1对外部信号计数,外部脉冲的下降沿将触发计数。计数器在每个机器周期的S5P2期间采样引脚输入电 平。若一个机器周期采样值为1,下一个机器周期采样值为0,则计数器加1。此后的机器周期S3P1期间,新的计数值装入计数器。所以检测一个由1至0的跳 变需要两个机器周期,故外部事年的最高计数频率为振荡频率的1/24。例如,如果选用12MHz晶振,则最高计数频率为0.5MHz。虽然对外部输入信号 的占空比无特殊要求,但为了确保某给定电平在变化前至少被采样一次,外部计数脉冲的高电平与低电平保持时间均需在一个机器周期以上。


当CPU用软件给定时器设置了某种工作方式之后,定时器就会按设定的工作方式独立运行,不再占用CPU的操作时间,除非定时器计满溢出,才可能中断CPU 当前操作。CPU也可以重新设置定时器工作方式,以改变定时器的操作。由此可见,定时器是单片机中效率高而且工作灵活的部件。

  综上所述,我们已知定时器/计数器是一种可编程部件,所以在定时器/计数器开始工作之前,CPU必须将一些命令(称为控制字)写入定时/计数器。将控制字写入定时/计数器的过程叫定时器/计数器初始化。在初始化过程中,要将工作方式控制字写入方式寄存器,工作状态字(或相关位)写入控制寄存器,赋定时/计 数初值。下面我们就提出的控制字的格式及各位的主要功能与大家详细的讲解。


控制寄存器 定时器/计数器T0和T1有2个控制寄存器-TMOD和TCON,它们分别用来设置各个定时器/计数器的工作方式,选择定时或计数功能,控制启动运行,以及作为运行状态的标志等。其中,TCON寄存器中另有4位用于中断系统。


  TMOD定时器/计数器方式寄存器

  定时器方式控制寄存器TMOD在特殊功能寄存器中,字节地址为89H,无位地址。TMOD的格式如下图所示。





由图可见,TMOD的高4位用于T1,低4使用于T0,4种符号的含义如下:


GATE:门控制位。GATE和软件控制位TR、外部引脚信号INT的状态,共同控制定时器/计数器的打开或关闭。


C/T:定时器/计数器选择位。C/T=1,为计数器方式;C/T=0,为定时器方式。


M1M0:工作方式选择位,定时器/计数器的4种工作方式由M1M0设定。


M1M0


工作方式


功能描述


00


工作方式0


13位计数器


01


工作方式1


16位计数器


10


工作方式2


自动再装入8位计数器


11


工作方式3


定时器0:分成两个8位计数器;
定时器1:停止计数




  定时器/计数器方式控制寄存器TMOD不能进行位寻址,只能用字节传送指令设置定时器工作方式,低半字节定义为定时器0,高半字节定义为定时器1。复位时,TMOD所有位均为0。


  例:设定定时器1为定时工作方式,要求软件启动定时器1按方式2工作。定时器0为计数方式,要求由软件启动定时器0,按方式1工作。

  我们怎么来实现这个要求呢?
  


大家先看上面TMOD寄存器各位的分布图
 


第一个问题:控制定时器1工作在定时方式或计数方式是哪个位?通过前面的学习,我们已知道,C/T位(D6)是定时或计数功能选择位,当C/T=0时定时/计数器就为定时工作方式。所以要使定时/计数器1工作在定时器方式就必需使D6为0。


第二个问题:设定定时器1按方式2工作。上表中可以看出,要使定时/计数器1工作在方式2,M0(D4) M1(D5)的值必须是1 0。


第三个问题:设定定时器0为计数方式。与第一个问题一样,定时/计数器0的工作方式选择位也是C/T(D2),当C/T=1时,就工作在计数器方式。


第四个问题:由软件启动定时器0,前面已讲过,当门控位GATE=0时,定时/计数器的启停就由软件控制


第五个问题:设定定时/计数器工作在方式1,使定时/计数器0工作在方式1,M0(D0) M1(D1)的值必须是0 1。


从上面的分析我们可以知道,只要将TMOD的各位,按规定的要求设置好后,定时器/计灵敏器就会按我们预定的要求工作。我们分析的这个例子最后各位的情况如下:


    D7 D6 D5 D4 D3 D2 D1 D0

    0  0  1   0 0  1  0  1



二进制数00100101=十六进制数25H。所以执行MOV TMOD,#25H这条指令就可以实现上述要求。


  TCON定时器/计数器控制寄存器

  TCON在特殊功能寄存器中,字节地址为88H,位地址(由低位到高位)为88H一8FH,由于有位地址,十分便于进行位操作。


TCON的作用是控制定时器的启、停,标志定时器溢出和中断情况。


TCON的格式如下图所示。其中,TFl,TRl,TF0和TR0位用于定时器/计数器;IEl,ITl,IE0和IT0位用于中断系统。





各位定义如下:


TF1:定时器1溢出标志位。当字时器1计满溢出时,由硬件使TF1置“1”,并且申请中断。进入中断服务程序后,由硬件自动清“0”,在查询方式下用软件清“0”。


TR1:定时器1运行控制位。由软件清“0”关闭定时器1。当GATE=1,且INT1为高电平时,TR1置“1”启动定时器1;当GATE=0,TR1置“1”启动定时器1。


TF0:定时器0溢出标志。其功能及操作情况同TF1。


TR0:定时器0运行控制位。其功能及操作情况同TR1。


IE1:外部中断1请求标志。


IT1:外部中断1触发方式选择位。


IE0:外部中断0请求标志。


IT0:外部中断0触发方式选择位。


TCON中低4位与中断有关,我们将在下节课讲中断时再给予讲解。由于TCON是可以位寻址的,因而如果只清溢出或启动定时器工作,可以用位操作命令。例如:执行“CLR TF0”后则清定时器0的溢出;执行“SETB TR1”后可启动定时器1开始工作(当然前面还要设置方式定)。


  定时器/计数器的初始化


由于定时器/计数器的功能是由软件编程确定的,所以一般在使用定时/计数器前都要对其进行初始化,使其按设定的功能工作。初始货的步骤一般如下:


1、确定工作方式(即对TMOD赋值);


2、预置定时或计数的初值(可直接将初值写入TH0、TL0或TH1、TL1);


3、根据需要开放定时器/计数器的中断(直接对IE位赋值);


4、启动定时器/计数器(若已规定用软件启动,则可把TR0或TR1置“1”;若已规定由外中断引脚电平启动,则需给外引脚步加启动电平。当实现了启动要求后,定时器即按规定的工作方式和初值开始计数或定时)。


下面介绍一下确定时时/计数器初值的具体方法。

  因为在不同工作方式下计数器位数不同,因而最大计数值也不同。


现假设最大计数值为M,那么各方式下的


最大值M值如下:


方式0:M=213=8 192


方式1:M=216=65 536


方式2:M=28=256


方式3:定时器0分成两个8位计数器,所以两个M均为256。


因为定时器/计数器是作“加1”计数,并在计数满溢出时产生中断,因此初值X可以这样计算:


X=M-计数值


下面举例说明初值的确定方法。


例1、选择T1方式0用于定时,在P1.1输出周期为1ms方波,晶振fosc=6MHz。


解:根据题意,只要使P1.1每隔500us取反一次即可得到1ms的方波,因而T1的定时时间为500us,因定时时间不长,取方式0即可。则M1 M0=0;因是定时器方式,所以C/T=0;在此用软件启动T1,所以GATE=0。T0不用,方式字可任意设置,只要不使其进入方式3即可,一般取0, 故TMOD=00H。系统复位后TMOD为0,可不对TMOD重新清0。


下面计算500us定时T1初始值:


机器周期T=12/fosc=12/(6×106)Hz=2μs


设初值为X,则:


(1013-X)×2×10-6s=500×10-6s


X=7942D=1111100000110B=1F06H


因为在作13位计数器用时,TL1的高3位未用,应填写0,TH1占用高8位,所以X的实际填写应为:


X=111100000000110B=F806H


结果:TH1=F8H,TL1=06H


源程序如下:


ORG 2000H


MOV TL1,#06H ;给TL1置初值


MOV TH1,#0F8H ;给TH1置初值


SETB TR1 ;启动T1


LP1:JBC TF1,LP2 ;查询计数溢出否?


AJMP LP1


LP2:MOV TL1,#06H ;重新设置计数初值


MOV TH1,#0F8H


CPL P1.1 ;输出取反


AJMP LP1 ;重复循环


  看了上面的介绍,我们现在应该会计算定时器的初值和设置相关的参数了,下面我们先看看硬件如何设计,在protel99se中,我们可以设计成如下led电路图:




  我们在这里还是要设计自己的要求:


  使用定时器
0,定时1s,工作在方式1,使用16位计数方式,让D01s后取反闪烁。

  现在我们计算一下:在定时器中最大的延时只能做到
65ms,无法做到1s,那么我们只能通过寄存器进行计算,定时器为50ms,累加到1s,然后对D0进行取反操作。

  看如下汇编程序:


LED0   BIT    P1.0  ;灯的输出信号
LED1   BIT    P1.1
MSS    EQU   30H   ;20=1s
MS1    EQU   31H
;**************************************************
;主程序
;**************************************************

     ORG    0000H
     NOP
     NOP
     LJMP   MAIN
     ORG    00BH   ;计数器
     NOP
     NOP
     LJMP   SCAN   \
     ORG    01BH   ;计数器
     NOP
     NOP
     LJMP   SCAN1
     ORG    0100H


MAIN:   LCALL    DEL_1S
             MOV      P1,          #0FFH
             MOV      P3,          #0FFH
             MOV      SP,          #60H             ;设置堆栈
             MOV      MSS,       #00H
             MOV      TH0,        #3CH            ;50ms
             MOV      TL0,        #0B0H
             MOV      TH1,        #3CH            ;50ms
             MOV      TL1,        #0B0H
             MOV      TMOD,    #11H
             SETB      EA                              ;打开定时中断
             SETB      TR0
             SETB      ET0
             SETB      TR1
             SETB      ET1
             MOV      P1,       #0FFH
             AJMP     $
             NOP


;***********************************************
;定时子程序
;***********************************************

SCAN:     MOV       TH0,     #3CH
               MOV       TL0,     #0B0H
               PUSH      ACC
               INC         MSS
               MOV       A,          MSS
               CJNE       A,         #20,          SCA_E
               MOV       MSS,     #00
               CPL         LED0                            ;1S到了对LED0取反
               AJMP       SCA_E
SCA_E:    POP         ACC
               RETI
SCAN1:    MOV        TH1,      #3CH
                MOV        TL1,     #0B0H
                PUSH       ACC
                INC          MS1
                MOV        A,        MS1
                CJNE        A,       #20,         SCA_E1
                MOV         MS1,  #00
               CPL           LED1                               ;1S到了对LED0取反
               AJMP        SCA_E
SCA_E1:   POP          ACC
                RETI

                END


如下为c51的程序:
//---------------------------------------------------
#include <reg52.h>
//---------------------------------------------------
//重定义I/0引脚名称
sbit LED0=P1^0;
sbit LED1=P1^1;
//---------------------------------------------------
//全局变量及位标志定义
unsigned char MSS;
unsigned char MS1;
//---------------------------------------------------
//固定函数声明
void timer_0();
//
定时器中断0
void timer_1();
//
定时器中断1
//---------------------------------------------------
void main(){

                  TH0= 0x3C      ;50ms

                  TL0=0x0B0;
                  TH1= 0x3C      ;50ms
                  TL1=0x0B0;
                  EA=1;                            ;打开定时中断
                  TR0=1;
                  ET0=1;
                  TR1=1;
                  ET1=1;
                 TMOD=0X11;
      while(1){
     {
      ;
      }
}

//-------------------------------------------------------------------
//定时器0中断
void timer_0() interrupt 1 using 2
{

       TH0= 0x3C     ;50ms

       TL0=0x0B0;
       MSS=MSS+1;
       If(MSS>=20)
      {
       LED0=!LED0;
       }
       }
//-------------------------------------------------------------------
//定时器1中断
void timer_1() interrupt 3 using 3
{
     TH1= 0x3C        ;50ms
     TL1=0x0B0;
     MS1=MS1+1;
     If(MS1>=20)
    {
     LED1=!LED1;
     }

}

  以上就是定时器的用法,有问题欢迎交流
附件: 您所在的用户组无法下载或查看附件
第四部分 串口中断培训(09.18)

MCS-51单片机的串行口具有两条独立的数据线——发送端TXD和接收端RXD,它允许数据同时往两个相反的方向传输。一般通信时发送数据由TXD端输出,接收数据由RXD端输入。MCS-51单片机的串行口既可以用于网络通信,亦可实现串行异步通信,还可以用作同步移位寄存器。如果在串行口的输入输出引脚上加上电平转换器,就可方便地构成标准的RS-232接口。MCS-51单片机的串行接口是一个全双工通信接口,它有两个物理上独立的接收、发送缓冲器SBUF,可以同时发送和接收数据。但是发送缓冲器只能写入,不能读出;接收缓冲器只能读出,不能写入。两个缓冲器共用一个地址(99H)。



数据通信的基本概念



常用于数据通信的传输方式有单工、半双工、全双工和多工方式。



  •   单工方式:数据仅按一个固定方向传送。因而这种传输方式的用途有限,常用于串行口的打印数据传输与简单系统间的数据采集。
  •   半双工方式:数据可实现双向传送,但不能同时进行,实际的应用采用某种协议实现收/发开关转换。
  •   全双工方式:允许双方同时进行数据双向传送,但一般全双工传输方式的线路和设备较复杂。
  •   多工方式:以上三种传输方式都是用同一线路传输一种频率信号,为了充分地利用线路资源,可通过使用多路复用器或多路集线器,采用频分、时分或码分复用技术,即可实现在同一线路上资源共享功能。


根据同步方式,串行数据通信有两种形式,如图5-5所示。



  •   异步通信。在这种通信方式中,接收器和发送器有各自的时钟,它们的工作是非同步的。异步通信用一帧来表示一个字符,其内容是一个起始位,紧接着是若干个数据位。
  •   同步通信。同步通信格式中,发送器和接收器由同一个时钟源控制,在异步通信中,每传输一帧字符都必须加上起始位和停止位,占用了传输时间,若要求传送数据 量较大,速度就会慢得多。同步传输方式去掉了这些起始位和停止位,只在传输数据块时先送出一个同步头(字符)标志即可。
  •   同步传输方式比异步传输方式速度快,这是它的优势。但同步传输方式也有其缺点,即它必须要用一个时钟来协调收发器的工作,所以它的设备也较复杂。


MCS-51的串行口控制寄存器



在完成串行口初始化后,发送数据时,采用MOV SBUF,A指令,将要发送的数据写入SBUF,则CPU自动启动和完成串行数据的输出;接收数据时,采用MOV A,SBUF指令,CPU就自动将接收到的数据从SBUF中读出。



控制MCS-51单片机串行接口的控制寄存器有两个——特殊功能寄存器SCON和PCON,用以设置串行端口的工作方式、接收/发送的运行状态、接收/发送数据的特征、数据传输率的大小,以及作为运行的中断标志等,其格式如下:



① 串行口控制寄存器SCON。SCON的字节地址是98H,位地址(由低位到高位)分别是98H一9FH。SCON的格式如下:








SM0、SMl:串行口工作方式控制位。


00——方式0;01——方式1;


10——方式2;11——方式3。


SM2:仅用于方式2和方式3的多机通信控制位。


发送机SM2=1(要求程控设置)。




当为方式2或方式3时:




接收机 SM2=1时,若RB8=1,可引起串行接收中断;若RB8=0,不引起串行接收中断。SM2=0时,若RB8=1,可引起串行接收中断;若RB8=0,亦可引起串行接收中断。



  • REN串行接收允许位:0——禁止接收;1——允许接收
  • TB8:在方式2、3中,TB8是发送机要发送的第9位数据。
  • RB8:在方式2、3中,RB8是接收接收到的第9位数据,该数据正好来自发送机的TB8。
  • TI:发送中断标志位。发送前必须用软件清零,发送过程中TI保持零电平,发送完一帧数据后,由硬件自动置1。如要再发送,必须用软件再清零。
  • RI:接收中断标志位。接收前,必须用软件清零,接收过程中RI保持零电平,接收完一帧数据后,由片内硬件自动置1。如要再接收,必须用软件再清零。

电源控制寄存器PCON。PCON的字节地址为87H,无位地址,其格式如下:






PCON是为在CMOS结构的MCS-51单片机上实现电源控制而附加的,对于HMOS结构的MCS-51系列单片机,除了第7位外,其余都是虚设的。与串行通信有关的也就是第7位,称作SMOD,它的用处是使数据传输率加倍。



SMOD:数据传输率加倍位。在计算串行方式1,2,3的数据传输率时;0表示不加倍;1表示加倍。



其余有效位说明如下。



GF1、GF2:通用标志位。


PD:掉电控制位,0表示正常方式,1表示掉电方式。


IDL:空闲控制位,0表示正常方式,1表示空闲方式。



除了以上两个控制寄存器外,中断允许寄存器IE中的ES位也用来作为串行I/O中断允许位。当ES=1,允许串行I/O中断;当ES=0,禁止串行I/O中断。中断优先级寄存器IP的PS位则用作串行I/O中断优先级控制位。当PS=1,设定为高优先级;当PS =0,设定为低优先级。




工作方式



MCS-51 单片机可以通过软件设置串行口控制寄存器SCON中SM0(SCON.7)和SMl(SCON.6)来指定串行口的4种工作方式。串行口操作模式选择如表5-2所示。



表5-2 串行口操作模式选择表



SM0 SM1


模 式


功 能


波 特 率


0 0


0


同步移位寄存器


fOSC/12


0 1


1


8位UART


可变(T1溢出率)


1 0


0


9位UART


fOSC/64或fOSC/32


1 1


1


9位UART


可变(T1溢出率)




其中,fosc是振荡器的频率,UART为通用异步接收和发送器的英文缩写。下面对这4种工作模式作进一步介绍。



1.方式0



当设定SM1、SM0为00时,串行口工作于方式0,它又叫同步移位寄存器输出方式。在方式0下,数据从 RXD(P3.0)端串行输出或输入,同步信号从TXD(P3.1)端输出,发送或接收的数据为8位,低位在前,高位在后,没有起始位和停止位。数据传输 率固定为振荡器的频率1/12,也就是每一机器周期传送一位数据。方式0可以外接移位寄存器,将串行口扩展为并行口,也可以外接同步输入/输出设备。



执行任何一条以SBUF为目的的寄存器指令,就开始发送。



2.方式1



当设定SM1、SM0为01时,串行口工作于方式1。方式1为数据传输率可变的8位异步通信方式,由TXD发送,RXD接收,一帧数据为10位,1位起始位(低电平),8位数据位(低位在前)和1位停止位(高电平)。数据传输率取决于定时器1或2的溢出速率 (1/溢出周期)和数据传输率是否加倍的选择位SMOD。




对于有定时器/计数器2的单片机,当T2CON寄存器中RCLK和TCLK置位时,用定时器2作为接收和发送的数据传输率发生器,而RCLK=TCLK=0时,用定时器1作为接收和发送的数据传输率发生器。两者还可以交叉使用,即发送和接收采用不同的数据传输率。



类似于模式0,发送过程是由执行任何一条以SBUF为目的的寄存器指令引起的。



3.方式2



当设定SM0、SM1二位为10时,串行口工作于方式2,此时串行口被定义为9位异步通信接口。采用这种方式可接收或发送 11 位数据,以 11 位为一帧,比方式 1 增加了一个数据位,其余相同。第 9 个数据即 D8 位用作奇偶校验或地址/数据选择,可以通过软件控制它,再加特殊功能寄存器 SCON 中的 SM2 位的配合,可使 MCS-51 单片机串行口适用于多机通信。发送时,第9位数据为TB8,接收时,第9位数据送入RB8。方式 2 的数据传输率固定,只有两种选择,为振荡率的 1/64 或 1/32 ,可由 PCON 的最高位选择。



4.方式3



当设定SM0、SM1二位为11时,串行口工作于方式3。方式3与方式2类似,唯一的区别是方式3的数据传输率是可变的。而帧格式与方式2一样为11位一帧。所以方式3也适合于多机通信。



数据传输率的确定



串行口每秒钟发送(或接收)的位数就是数据传输率。



对方式0来说,数据传输率已固定成fosc/12,随着外部晶振的频率不同,数据传输率亦不相同。常用的fosc有12MHz和6MHz,所以数据传输率相应为1000×103和500×103bit/s。在此方式下,数据将自动地按固定的数据传输率发送/接收,完全不用设置。



对方式2而言,数据传输率的计算式为2SMOD·fosc/64。当SMOD=0时,数据传输率为fm/64;当SMOD=1时,数据传输率为fosc/32。在此方式下,程控设置SMOD位的状态后,数据传输率就确定了,不需要再作其他设置。



对方式1和方式3来说,数据传输率和定时器1的溢出率有关,定时器1的溢出率为:



定时器1的溢出率=定时器1的溢出次数/秒


方式1和方式3的数据传输率计算式为:


2SMOD/32×T1溢出率




根据SMOD状态位的不同,数据传输率有Tl/32溢出率和T1/16溢出率两种。由于T1溢出率的设置是方便的,因而数据传输率的选择将十分灵活。




前已叙及,定时器Tl有4种工作方式,为了得到其溢出率,而又不必进入中断服务程序,往往使T1设置在工作方式2的运行状态,也就是8位自动加入时间常数的方式。



表5-3所示常用数据传输率的设置方法。



表5-3 常用数据传输率设置方法



数据传输率/Hz


fOSC/MHz


SMOD


定时器1


C/T


方 式


重新装入值


方式0最大:1M


方式2最大:375k


方式1、3:62.5k


19.2k


9.6k


4.8k


2.4k


1.2k


110


12


12


12


11.0592


11.0592


11.0592


11.0592


11.0592


12


X


1


1


1


0


0


0


0


0


X


X


0


0


0


0


0


0


0


X


X


2


2


2


2


2


2


1


X


X


FFH


FDH


FDH


FAH


F4H


E8H


0FEEH





串行通信实例



我们先看看实例图形,我们先设计一个串口通讯的电路,一端和单片机连接,另一端和电脑连接。如下的protel所示:






此图中,使用的晶振是11.0592mhz的晶振,和电脑进行通讯,电脑上面



下面是汇编程序





      LED BIT  P1.0


      ORG   0000H


      LJMP  MAIN


      ORG   0023H


      LJMP  TRX


      ORG   0100H


MAIN: MOV   SP,    $50H


      MOV   TMOD,  #21H


      MOV   SCON,  #80H


      MOV   TH1,   #0fdh  ;9600bit


      MOV   TL1,   #0fdh


      SETB  ES


      SETB  REN


      SETB  EA


      MOV   SBUF,  #30H    ;发送数据第一位
      JNB   TI,    $


      CLR   TI


      MOV   SBUF,  #31H    ;发送数据第一位
      JNB   TI,    $


      CLR   TI


      MOV   SBUF,   #32H   ;发送数据第一位
      JNB   TI,     $


      CLR   TI


      JMP   $


TRX:   PUSH  PSW            ;串行中断


      PUSH  ACC


      PUSH  DPL


      PUSH  DPH


      JNB   RI,ENDRX


      clr   tb8


      CLR   RI


      MOV   A,SBUF


      CJNE A,#30H,ENDRX


      SETB LED0


ENDRX: POP  DPH


       POP  DPL


       POP  ACC


       POP  PSW


       RETI


END




这是一个