zoukankan      html  css  js  c++  java
  • 单片机基础(八):单片机串行口结构与工作方式及应用

    单片机串行口结构

    在这里插入图片描述
      串行口结构如上图
      发送时,SBUF中写入数据后,串行口通过发送控制器,将SBUF中的数据逐个逐位地通过串行输出口TXD引脚逐个发出,当一个字节发送结束后,触发TI中断位,通知单片机发送结束
      接收时,先向REN引脚写1,外部引脚RXD会实时检测电平变化,当满足串行接收数据的条件时,会逐位接收数据并保存到SBUF,当一个字节接收结束后,触发RI中断位,通知单片机接收结束


    串行口控制寄存器SCON

    SCON D7 D6 D5 D4 D3 D2 D1 D0
    98H SM0 SM1 SM2 REN TB8 RB8 TI RI

    SM0、SM1用于设定串行口工作方式   fosc :晶振频率

    SM0 SM1 方式 功能 波特率
    0 0 方式0 移位寄存器方式 fosc/12
    0 1 方式1 8位异步通信方式 可变
    1 0 方式2 9位异步通信方式 fosc/32或fosc/64
    1 1 方式3 9位异步通信方式 可变

    SM2:多机通信控制位
    REN:允许接收控制位
    TB8/RB:发送/接收的第9位数据
    TI:发送中断标志位
    RI:接收中断标志位


    电源控制寄存器

    PCON D7 D6 D5 D4 D3 D2 D1 D0
    87H SMOD

    当SMOD位为1时,串行口方式1、方式2、方式3的波特率加倍


    这里只介绍方式0与方式1的应用

    方式0
      方式0通常用来外接移位寄存器,用作扩展I/O口,方式0工作时波特率固定为 fsoc/12,工作时,串行数据通过RXD输入、输出,同步时钟通过TXD输出
      发送:TI = 0 时,SBUF写入数据后,发送过程启动,发送结束后,TI被置为1,并向CPU申请中断
      接收:在 RI = 0 时,将REN置"1"就启动一次接收过程,RXD上的串行数据一次移入移位寄存器,当一个字节发送完成之后,接收中断标志RI被置为"1",同时向CPU申请中断
      方式0波特率固定,也无需编程设定定时器

    方式0应用实例:扩展并行I/O口
      当外接串入并出的移位寄存器时,即是扩展并行输出口,当外接并入串出的移位寄存器时,相当于扩展并行输入口

    原理图如下
    在这里插入图片描述
    4094模块使用方式:
    在这里插入图片描述
    D接RXD,CLK接TXD,STB接P1.0,OE接EA

    扩展并行输出口控制流水灯程序如下:

    #include<reg52.h>
    sbit P1_0 = P1^0;
    void main(){
    	unsigned char i;
    	unsigned int j;
    	SCON = 0x00;//设置串行口工作方式
    	i = 0x01;//00000001b   发送的用于控制LED灯的变量
    	for(;;){
    		P1_0 = 0;//将4094接入串口
    		SBUF = i;//
    		while(TI==0);
    		P1_0 = 1;//将STB置1,准备4094发送
    		TI = 0;//TI归位
    		for(j = 0;j<0xffff;j++);//适当延时
    		i = i*2;
    		if(i==0){
    			i = 0x01;//循环
    		}
    	}
    }
    

    方式1
      方式1位8位异步通信方式,在方式1下,一帧信息为10位,1位起始位(0),8位数据位(低位在前)和1位停止位(1)
      发送:在 TI = 0 时,向SBUF写入数据,启动发送过程,数据有TXD引脚送出,当一帧数据发送完毕后,TI 被置为"1"
      接收:当 REN = 1 时,接收控制器开始接收数据,数据依次被移入移位寄存器,当8位数据及停止位全部移入后,进行响应操作
      方式1下,TXD数据发送端,RXD为数据接收端,波特率可变,由定时/计数器T1的溢出率和电源控制寄存器PCON中的SMOD位决定,故可编程设定定时器以设定波特率,其中溢出率 = 计数器一秒钟内溢出的次数
     波特率 = 2SMOD × (T1的溢出率) / 32
     T1溢出率 = fsoc / ( 12 × 计数值 )
    所以
     T1的初值 = MAX值 - fsoc × 2SMOD / (12 × 波特率 × 32)

    在这里插入图片描述
    分析如下:
    在这里插入图片描述
    甲机发送程序:

    #include<reg52.h>
    void main(){
    	unsigned char i;
    	SCON = 0x40;
    	TMOD = 0x20;
    	TL1 = 0xE6;
    	TH1 = 0xE6;
    	TR1 = 1;//设定完毕
    	P1 = 0xff;//为读取准备
    	while(1){
    		i = P1;
    		SBUF = i;
    		while(TI==0);//等待发送完成
    		TI = 0;
    	}
    }
    

    乙机接收程序:

    #include<reg52.h>
    void main(){
    	SCON = 0x50;
    	TMOD = 0x20;
    	TL1 = 0xE6;
    	TH1 = 0xE6;
    	TR1 = 1;
    	EA = 1;
    	ES = 1;
    	while(1);
    }
    
    void setLED() intrrupt 4{
    	if(RI){
    		RI = 0;
    		P2 = SBUF;
    	}
    }
    

    2019/3/5

  • 相关阅读:
    [转]Entity Framework 和NHibernate的区别
    NHibernate One Session Per Request简单实现
    memcache和memcached之间的区别
    Memcached 内存分配机制介绍
    linux,apache,php,mysql常用的查看版本信息的方法
    Linux查看文件夹大小
    Linux查看系统配置常用命令
    php 文件缓存(转)
    memcache在xampp下的安装
    通过改进代码将for循环遍历数组提高效率
  • 原文地址:https://www.cnblogs.com/kafm/p/12721821.html
Copyright © 2011-2022 走看看