登录  | 立即注册

游客您好!登录后享受更多精彩

扫一扫,访问微社区

QQ登录

只需一步,快速开始

开启左侧

[寒假笔记] 单片机串口通讯的概念及其应用

[复制链接]
发表于 2018-2-7 17:59:54 | 显示全部楼层 |阅读模式
学习笔记
学习科目: 单片机串口通讯的概念及其应用
学习安排: 单片机串口通讯的概念及其应用
开始时间: 2018-02-07
结束时间:
串行通信是指使用一条数据线,将数据一位一位地依次传输,每一位数据占据一个固定的时间长度。
其只需要少数几条线就可以在系统间交换信息
该通讯分为异步通信和同步通信
单片机串行通讯我采用异步通信
在逻辑上,SBUF只有一个,它既表示发送寄存器,又表示接收寄存器
他们具有同一个单元地址99H。
在物理结构上,则有两个完全独立的SBUF,一个是发送缓冲寄存器SBUF,另一个是接收缓冲寄存器SBUF。
如果写SBUF,数据就是准备发送;如果读SBUF,则读入的数据来自接收的。
CPU对SBUF的读写,实际上是分别访问上述两个不同的寄存器。
例如 a = SBUF; 为写
SBUF = a;为读

对于时钟和中断有TCON控制寄存器
而对于中断也有串行控制寄存器SCON,一样它是可寻址的

SM0和SM1是用来设置工作模式的
方式0多用于拓展IO口,这里用不到
我用的工作方式是1 即 SM0=1  SM1=1 为10位异步收发器传送8位数据
REN为串行接收允许控制位。该位由软件置位或复位。当REN=1,允许接收,当REN=0,禁止接收。

那么我们如何知道数据发送完呢?
有2种方式,
1.查询发送中断标志位TI 当 TI=1表示发送了一帧数据
2.串口中断
但是TI在任何工作方式下必须由软件进行清0才可执行下一次发送数据

同理,接受数据完成后也有一样的方法
1.查询发接收中断标志位RI 当 RI=1表示接收了一帧数据
2.串口中断
RI也必须进行清0

对于中断而言无论是发送还是接收都会引起相同的中断
因此在中断程序中需要查询TIRI的状态才能判断是接收还是发送产生的中断

还有一个控制寄存器为PCON中的SMOD
为波特率加倍位 (产生高波特率时启用平时不用,比如用11.0592晶振产生57600波特率时就要设置成SMOD=1)
SMOD=1时,波特率加倍       PCON=0x80;
SMOD=0 时,波特率不加倍。PCON=0x00;

在PCON中只有这一个位与串口有关

对于串口通讯需要设置波特率
波特率=(2^SMOD*fosc)/32*12*(256-T初值)

当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1=1,以启动定时器)。这时溢出率取决于TH1中的计数值。
串行口工作之前需对相关寄存器进行配置,设定其工作模式。
1.设置T1的工作方式2(编程TMOD寄存器);
2.计算T1的初值,装载TH1、TL1;
3.启动T1(编程TCON中的TR1位);
4.确定串行口控制(编程SCON寄存器);

如需串行口在中断方式工作时,要进行中断设置编程IE寄存器。

那么我打算写一个通用串口用电脑控制单片机的流水灯
[mw_shl_code=c,true]#include <reg52.h>
#define uchar unsigned char
uchar num;
void UART_init()
{
        TMOD = 0x20;          //T1工作模式2  8位自动重装
        TH1 = 0xfd;
        TL1 = 0xfd;         //比特率9600
        TR1 = 1;                //启动T1定时器
        SM0 = 0;
        SM1 = 1;                 //串口工作方式1 10位异步
        REN = 1;                //串口允许接收
        EA  = 1;                //总中断开启
        ES  = 1;                //串口中断开启
}
void main()
{
        UART_init(); //初始化设置
        while(1);       
}

void UART() interrupt 4
{
        if(RI)        //是否接收完成
        {
                num = SBUF;          //num 取出
                P1 = SBUF;
                num++;
                RI = 0;
                SBUF = num;       
                while(!TI);
                TI = 0;
        }
}[/mw_shl_code]

使用烧录软件中的串口助手测试
应用成功,下一帖我将把数码管的数字显示写成一个函数打包方便使用,我会把代码进行共享
以上所有内容仅为个人学习及总结,如有错误之处请指点出来谢谢

串口通讯控制流水灯-STC-ISP.png
SM0和1工作方式.png
串口通讯SCON.png
串行接口结构.png
好懒~~不想说~~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表