51单片机实战:与计算机异步串行通信

文章框架

文章框架


前言

猴!今儿扯串口,相对于并行——一口气全把数据扔过去,串行显得更加稳重——一位一位来。
串行就是这样,只需要一条数据线(全双工和同步串行时两条),一位一位的传过去。为了让大家在直到你是在给我传数据而不是外面的噪音或者是胡说八道,所以串行数据的各位要组装帧(看正文中的帧格式)。乍一看,这种方式跟并行比肯定慢的一腿。但实际上,多亏了它的稳定性,可以在波特率极高的情况下依然保持稳定,这是并行所办不到的(传的快了或距离远了就张牙舞爪了),所以发展到现在,串口已经把并口甩走几条街啦。

并口传输的例子:《51单片机实战:液晶显示器のLCD1602》

除此之外,串行传输分同步和异步。同步除了传输数据外,还要传输时钟信号,以保持双方同步。另一种,异步,就没这么麻烦了,也是本例中要讲到的,各自走各自的时钟就好,只要帧格式和波特率都商量好是一样的就好。


知识点

电平

电平 高电平 低电平 说明
TTL +5V 0V Transistor–Transistor Logic。常用于设备内部的数据传输,10英尺内。
RS-232C -12V +12V RS(recommended standard)代表推荐标准,232是标识号,C代表RS232的最新一次修改(1969),用于计算机串口

电平之前在文章《51单片机实战:液晶显示器のLCD1602》中介绍过,那里只说了TTL,本例中由于要和计算机打交道,所以多了一种电平:RS-232C

在单片机中是TTL,电脑那边传出和接收都是RS232,所以两种电平需要作转换。


MAX232

当当当!它就是干这活的。

T#IN T#OUT R#IN R#OUT VS C
TTL输入 TTL输出 RS232输入 RS232输出 电源 接电容

举个栗子,比如单片机从T1IN输入TTL电平,转换好的RS232电平就从R1OUT输出。其他的照猫画虎,这里不详细说这个东西,因为咱们在Proteus里干活,用不着转换(Proteus光环)。

波特率(Baud Rate)

在此描述串行传输数据速率。
正儿八经的说,波特率乃码元的传输速率,即每秒传输的码元个数(码元可以是任意进制的),并不是什么每秒传输的比特数,大家注意。
波特来源于一个人的名字:Jean-Maurice-Émile Baudot,因此简写为Baud,单位符号:Bd。波特率可简写成Bd/s。

在串口通信中,其码元就是二进制信号,所以波特率的数值等于比特率数值,但你不能说波特率就是比特率啊!

单片机的串口通信有四种方式(各方式具体是干什么的,别着急,在后面),其中方式0和方式2的波特率是固定的。方式1和方式3的波特率是可变的,其脉冲周期由定时器1溢出产生。

方式 波特率
0 f / 12
1 ((2^SMOD) / 32) × (T1溢出率)
2 ((2^SMOD) / 64) × f
3 ((2^SMOD) / 32) × (T1溢出率)

其中f是系统晶振频率,T1是计时器1,SMOD是PCON中的最高位(PCON见相关寄存器的第一个)。

可以从上述公式看出,波特率不可变是因为直接与系统晶振频率相关(晶振频率不可变,除非换晶振),而可变是因为直接与T1的溢出率相关(溢出率可以改变)。

溢出率
在之前定时器应用的例子(《51单片机实战:定时器与数码管的应用》)中,我们计算的是溢出周期,也就是多长时间会溢出一次。这次我们用到的溢出率其实是同一个东西,取倒数就可以了。

详见:《51单片机实战:定时器与数码管的应用》 - 知识点 - 定时器/计数器 - 初值

  • 使用定时器1的方式2

    定时器的方式2是一个自动重装初值的8位定时器。低8位(TLX)用于自加计时,高8位(THX)保存每次自动重装的初值。

    所以,用于产生脉冲周期的定时器的
    溢出周期 = [(2^8) - i] × 12 / f
    其中, i为定时器初值,f还是晶振频率。

    溢出率 = 1 / 溢出周期

11.0592MHz
为什么要用这么蹩脚的数字作晶振频率哈,就是跟这里有关。如果你已经用上述公式计算过串口方式1下的12MHz和11.0592MHz在9600波特率下的定时器初值,你就会发现,前者得出一个小数,而后者是个整数。
我们可没办法用小数赋初值,所以你若用近似的整数作初值,就意味着会产生误差。

  • 常用:11.0592MHz & 9600BdTHX = TLX = 0xfd

若用其他的晶振和波特率的话,请自行按前面的公式计算。

帧格式

串行传输按比特来,一个个比特组成一个帧,帧需要一定的格式才能被双方识别这是一个帧信息。

S D P E
起始位 数据位 奇偶校验位 终止位
标明帧头 数据信息 用于检验此帧是否出错 标明帧尾
1位,低电平 可以是5、6、7、8位 可加可不加,可奇校验也可偶校验 可以是1、1/2、2位,高电平

相关寄存器

PCON

电源管理寄存器,用于管理单片机的电源部分。
字节地址:87H,不能位寻址,reg52.h中已定义,单片机复位时全部清零。

7 6 5 4 3 2 1 0
符号 SMOD (SMOD0) (LVDF) (P0F) GF1 GF0 PD IDL
说明 串口方式为1、2、3时,设置串口波特率的速率 STC单片机特有功能 STC单片机特有功能 STC单片机特有功能 通用工作标志位 通用工作标志位 掉电模式 空闲模式
0:正常;1:加倍 ||||1:进入掉电模式 1:进入空闲模式

上表中出现的“串口方式”见下表的SM0和SM1。

SCON

串口控制寄存器,用于设定串口工作方式。
字节地址:98H,可位寻址,reg52.h中已定义,单片机复位时全部清零。

7 6 5 4 3 2 1 0
符号 SM0 SM1 SM2 REN TB8 RB8 TI RI
说明 工作方式选择位 工作方式选择位 多机通信控制位 允许串行接收位 方式2、3时,发送数据的第9位 方式2、3时,接收数据的第9位 发送中断标志 接收中断标志
看下表 看下表 与本例无关懒得说 1:允许串口接收数据 |第八位发送结束时,硬件置1 第八位接收结束时,硬件置1
SM0 SM1 方式 说明
0 0 0 同步移位寄存器方式
0 1 1 10位异步收发(8数据位),波特率可变
1 0 2 11位异步收发(9数据位),波特率固定
1 1 3 11位异步收发(9数据位),波特率可变

上表中波特率可变的方式,都由定时器1的溢出率控制。


实例

需求说明

当单片机接收到字符a时,点亮一个LED灯。传送方式:9600波特率,8数据位,无校验位,1停止位。

程序清单

本例中我就不写电脑端程序了,直接用现成的。

程序 说明 下载
VSPD Visual Serial Port Driver,用于建立虚拟串口连接,因为我们还是用Proteus模拟接口,所以需要VSPD模拟串口之间连接起来 度娘网盘
UartAssist 串口调试助手,用来给单片机发送消息 度娘网盘

电路

电路

注意,这里面我没有放转换电平转换芯片(MAX232),只有在Proteus里可以这么干,现实中焊板子还是要做电平转换的,这里这个软件给简化了。

COMPIM

COMPIM

乃虚拟9Pin串口,模拟前记得要设置参数。
参数设置

注意,波特率要设置虚拟波特率那个,物理波特率在本例中没用。

虚拟终端
右下角那个东西是虚拟终端(Virtual Terminal),他可以直接截获串口传来的消息然后显示出来。很方便做这方面调试时使用。

Virtual Terminal

路径:边栏instrumentsvirtual terminal

如果在调试的时候不小心把它的终端窗口关了,再次打开路径:菜单debug - virtual terminal,注意是在启动调试的情况下。

代码

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

char a;  //用于从缓冲区中接收数据,虽然在此例中显得有点多此一举,但最好还是把东西放到自家变量中放心。

//初始化函数
void init(){
    a = 0;

    //定时器初始化
    TMOD = 0x20;  //定时器1的方式2
    TH1 = 0xfd;
    TL1 = 0xfd;
    TR1 = 1;
    
    //串口初始化,方式1
    SM0 = 0;
    SM1 = 1;
    REN = 1;  //允许接收
    
    EA = 1;  //中断总闸·开!
    ES = 1;  //串口中断·开!
}

void main() {
    init();
    while(1);
}

void com() interrupt 4{
    a = SBUF; //SBUF为串口接收缓冲区
    while(!RI);  //判断接收是否完毕
    if(a == 0x61)  //如果是'a',亮灯
        P0 = 0;
    RI = 0;  //准备下一次接收
}

效果

  • 发送c

    调试助手发送数据

    注意这里串口调试助手中的通讯设置那一块,要和Proteus中COMPIM元件保持一致。
    Proteus

    可以看出发送c后,端口正确收到了c,但并没有亮灯。

  • 发送a

    Proteus

    收到a后,亮灯。


结语

大年初二,拜访完姥姥家就该看看单片机怎么玩,你说是吧!这两天快马加鞭了,下一站:一周目大BOSS。各位加油。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容