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

10 篇文章 3 订阅

转载自简书--点击打开链接

文章框架

文章框架



前言

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

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

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


知识点

电平

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

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

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

 

 

MAX232

 

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

T#INT#OUTR#INR#OUTVSC
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溢出产生。

方式波特率
0f / 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

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

帧格式

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

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

相关寄存器

PCON

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

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

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

SCON

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

76543210
符号SM0SM1SM2RENTB8RB8TIRI
说明工作方式选择位工作方式选择位多机通信控制位允许串行接收位方式2、3时,发送数据的第9位方式2、3时,接收数据的第9位发送中断标志接收中断标志
看下表看下表与本例无关懒得说1:允许串口接收数据|第八位发送结束时,硬件置1第八位接收结束时,硬件置1
SM0SM1方式说明
000同步移位寄存器方式
01110位异步收发(8数据位),波特率可变
10211位异步收发(9数据位),波特率固定
11311位异步收发(9数据位),波特率可变

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


实例

需求说明

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

程序清单

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

程序说明下载
VSPDVisual 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后,亮灯。

 


作者:兔子泽
链接:https://www.jianshu.com/p/ce7b8f409585
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值