zoukankan      html  css  js  c++  java
  • 有关51串口通信

    (1)SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制以及设置状态标志:
     
    SCON        位      7        6         5         4         3         2           1            0
    位于98h           SM0     SM1    SM2    REN     TB8     RB8       TI           RI
     
    1.SM0与SM1是工作方式控制位
    2.SM2与方式有关,一般只用方式1所以,SM2一般用不到, 
    3.REN,允许串行接收位。由软件置REN=1,则启动串行口接收数据;若软件置REN=0,则禁止接收。
    4.TB8,在方式2或方式3中,是发送数据的第九,可以用软件规定其作用。可以用作数据的奇偶校验位,或在多机通信中,作为地址帧/数据帧的标志位。
        在方式0和方式1中,该位未用。
    5.RB8,在方式2或方式3中,是接收到数据的第九位,作为奇偶校验位或地址帧/数据帧的标志位。在方1时,若SM2=0,则RB8是接收到的停止位。
    6.TI,发送中断标志位。在方式0时,当串行发送第8位数据结束时,或在其它方式,串行发送停止位的开始时,由内部硬件使TI1,向CPU发中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。
    7.RI,接收中断标志位。在方式0时,当串行接收第8位数据结束时,或在其它方式,串行接收停止位的中间时,由内部硬件使RI1,向CPU发中断申请。也必须在中断服务程序中,用软件将其清0,取消此中断申请。
     #### 如果使用方式一的话,只要设置SM0=0,SM1=1选择方式一;REN=1启动串行口接收数据;TI跟RI,在中断服务程序中,必须用软件将其清0,取消此中断申请。
     
    (2) PCON中只有一位SMOD与串行口工作有关
      SMODPCON.7  波特率倍增位。在串行口方式1、方式2、方式3时,波特率与SMOD有关,当SMOD=1时,波特率提高一倍。复位时,SMOD=0
     
    SBUF可读可写
     
     
    串行口工作之前,应对其进行初始化,主要是设置产生波特率的定时器1、串行口控制和中断控制。具体步骤如下:
    §确定T1的工作方式(编程TMOD寄存器);/*TMOD寄存器 有8位,低4位是控制定时器0的,高四位是控制定时器1的,分别为GATE(初始化时候是0,不用管它)、C/t(定时计数选择位,0位定时器)、M1、M0(工作方式选择位)*/
    §计算T1的初值,装载TH1TL1; /* T1 溢出率 = fosc /{12×[256 -(TH1]} 其中fosc为单片机的主频*/
    §启动T1(编程TCON中的TR1位);
    §确定串行口控制(编程SCON寄存器);
    串行口在中断方式工作时,要进行中断设置(编IEIP寄存器)。
     
     
     
    方式0的波特率 =  fosc/12
    方式2的波特率 =2SMOD/64· fosc
    方式1的波特率 =2SMOD/32·T1溢出率)
    方式3的波特率 =2SMOD/32·T1溢出率)
     
    IE寄存器:
    EA:全局中断允许位,要想打开任何中断,EA都必须为1.然后再允许某个特定的中断。
    ES:串行口中断允许。ES=1时,串口接收或者发送完成数据以后会引起中断(TI=1,或者RI=1)
    ET1:定时计数器1中断允许。ET1=1时,当定时计数器1计数满,溢出后引起中断,可在中断函数中处理定时器。
    EX1:外部中断1允许位。EX=1时,外部条边沿(或者电平)中断信号来后,会引起外部中断,可在外部中断函数中处理事件。
    ET0/EX0功能跟上面一样,只是换了个定时器或者外部中断。
     
    中断优先级寄存器IP
     
     
    #include<reg52.h>
    unsigned char flag,a;
    void main()
    {

    TMOD=0x20;//设置定时器1为工作方式2
    TH1=0xfd;
    TL1=0xfd;
    TR1=1;
    REN=1;
    SM0=0;
    SM1=1;
    EA=1;
    ES=1;
    while(1)
    {
    /* if(RI==1)
    {
    RI=0;
    P1=SBUF;
    }
    */
    if(flag==1)
    {
    ES=0;
    flag=0;
    SBUF='1';//28;
    while(!TI);
    TI=0;
    SBUF='2';//28;
    while(!TI);
    TI=0;
    SBUF='3';//28;
    while(!TI);
    TI=0;
    ES=1;
    }
    }
    }

    void ser() interrupt 4
    {
    RI=0;
    // P1=SBUF;
    a=SBUF;
    flag=1;
    }
     
     
     
    /*
    2012年3月21日21:23:36:
    此程序为由串口调试工具向单片机发送数据,单片机通过led灯显示发送的数据
    如发送ff,则灯全灭
    发送fe,点亮第一个灯
    */
    #include <reg52.h>
    void init();

    void main()
    {
    init();
    while(1)
    {
    if(RI==1) //串行接收完毕时,由内部硬件使RI置1。检测是否接受完毕
    {
    P2=SBUF; //接收完毕后将接收到的SBUF赋给P2口
    }
    }


    }

    void init() //定时器及串口初始化
    {
    TMOD=0x20; //设置定时器1为工作方式2
    TH1=0xfd; //定时器装初值
    TL1=0xfd;
    TR1=1; //开定时器
    REN=1; //(SCON寄存器中)允许串行接收
    SM0=0; //设置工作方式控制位,选择为工作方式1
    SM1=1;
    EA=1; //开总中断
    ES=1; //开串口中断
    }

    void ser() interrupt 4 //中断关服务函数
    {
    RI=0; /*串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请,
    须在中断服务程序中,用软件将其清0,取消此中断申请。
    */
    P2=SBUF; //将接收数据缓冲器SBUF中接受的数据传给P2口

    }
     
     
    /*
    2012年3月21日21:23:36:
    此程序为由串口调试工具向单片机发送数据,单片机通过led灯显示发送的数据
    如发送ff,则灯全灭
    发送fe,点亮第一个灯
    并且单片机接受发来的数据以后,在发回给上位机显示!
    */
    #include <reg52.h>
    #define uchar unsigned char
    #define uint unsigned int
    void init();
    uchar a,flag;
    void main()
    {
    init();
    while(1)
    {
    if(flag==1)
    {
    ES=0; //关串行口中断 要使其发送数据时候关中断
    flag=0;
    SBUF=a;
    while(!TI); //检测是否发完
    TI=0; //发完莫忘TI清零!!!
    ES=1; //开串口中断
    }
    }


    }

    void init() //定时器及串口初始化
    {
    TMOD=0x20; //设置定时器1为工作方式2
    TH1=0xfd; //定时器装初值
    TL1=0xfd;
    TR1=1; //开定时器
    REN=1; //(SCON寄存器中)允许串行接收
    SM0=0; //设置工作方式控制位,选择为工作方式1
    SM1=1;
    EA=1; //开总中断
    ES=1; //开串口中断
    }

    void ser() interrupt 4 //中断关服务函数
    {
    RI=0; /*串行接收停止位的中间时,由内部硬件使RI置1,向CPU发中断申请,
    须在中断服务程序中,用软件将其清0,取消此中断申请。
    */
    P2=SBUF; //将接收数据缓冲器SBUF中接受的数据传给P2口
    a=SBUF;
    flag=1;
    }


     
     
  • 相关阅读:
    多线程中lock用法
    跨域使用Proxy page或Cross Frame
    new 操作符所做的事情
    跨域使用js文件
    跨域使用window.name
    TFS 映射错误( is already mapped in workspace)解决办法
    跨域使用JSONP
    jquery加载页面中的部分内容
    CQRS架构案例Tiny Library CQRS详解:AOP拦截与异常处理
    面向领域驱动架构的查询实现方式
  • 原文地址:https://www.cnblogs.com/steararre/p/2410445.html
Copyright © 2011-2022 走看看