K60-串口通信

本文主要介绍了K60单片机的串口通信(UART)原理和实现,包括异步串行通信的数据格式、TTL电平、开始位/停止位/校验位、波特率等,并详细阐述了串口初始化、字节的发送与接收。通过理解这些基础知识,可以实现K60单片机的串口通信功能。
摘要由CSDN通过智能技术生成


0x00 前言

本文试图从易于理解的角度讲解k60单片机的串口通信(UART),从相关寄存器的简单配置到完成一个字节的收发,再到多个字节的应用。由于使用的单片机是K60,所以是"基于K60",但是串口通信的原理和基本概念都是的通用的

因为是简单讲解,所以阉割了一些内容,不会特别全面与深入。

参考资料

K60-UART串口通信讲解
STM32的串口通信


0x01 串行通信原理

1.1 简单介绍

串口是串行通信接口的简称,是一种外设接口。串行通信可以分为异步通信与同步通信,此处只涉及到异步通信原理。实现异步串行通信功能的模块在一部分 MCU 中被称为通用异步收发器(Universal Asynchronous Receiver/Transmitters,UART)。

实现串行通信的数据传输只需要两条线,发送线(TX)、接收线(RX)。

1.2 原理部分

串行通信的特点是:数据以字节为单位,按位的顺序(例如从最低位开始)从一条传输线上发送出去。

即通过一个移位寄存器,在发送时,将并行的字节数据(8位二进制)移位成串行的线性数据发送出去。接受时同理,将串行数据移位成并行数据再存储到数据寄存器中。

以一个字节为例

在这里插入图片描述


1.2.1异步串行通信的数据格式

在这里插入图片描述

从开始位到停止位结束的时间间隔称为一帧(frame)。所以,也称这种格式为帧格式。

一帧数据里面包含起始位、数据位、校验位和停止位(可以没有校验位),所以一帧数据至少10位二进制

每发送一个字节,都要发送“开始位”与“停止位”,这是影响异步串行通信传送速度的因素之一。同时因为每发送一个字节,必须首先发送“开始位”,所以称之为“异步”(Asynchronous)通信。

1.2.2 如何发送 (0/1) ? —— TTL电平

MCU 引脚输入/输出一般使用 TTL(Transistor Transistor Logic)电平,即晶体管-晶体管逻辑电平

逻辑“0” 逻辑“1”
TTL电平 小于0.4V 大于2.4V

可以发现 : 0.4V~2.4V处于一种中间态,既不是1也不是0,此状态可以认为用于间隔相邻发送位。

以一个字节且无校验位为例

在这里插入图片描述

可以观察发现:逻辑“0”和逻辑“1”中间的电平部分就是这样一种中间态,每发送完一个位数据都要回到这样一种中间态,这是很有必要的,否则就无法判断停止位。

TTL电平传输数据的距离有限,为了延长传输距离,可以将TTL转RS-232C,这里不予拓展


1.2.3 开始位/停止位/校验位

开始位: 作用是告诉接收方接下来要传输数据了,开始位的标志是保持空闲状态时(逻辑“1”),下拉电平到逻辑“0”并且保持发送一个位的时间(这个时间是由波特率决定的,后续会说明),如果该低电平没有保持一定的时间,则认为是偶然因素造成而忽略掉。

停止位: 发送器发送 1 到 2位的停止位(逻辑"1"),表示一个字节传送结束。若继续发送下一字节,则重新发送开始位,开始一个新的字节传送。若不发送新的字节,则维持“1”的状态,使发送数据线处于空闲。

校验位:

在异步串行通信中,如何知道传输是正确的?最常见的方法是增加一个位(奇偶校验位),供错误检测使用。字符奇偶校验检查(Character Parity Checking)称为垂直冗余检查(VerticalRedundancy Checking,VRC),它是为每个字符增加一个额外位使字符中“1”的个数为奇数或偶数。奇数或偶数依据使用的是“奇校验检查”还是“偶校验检查”而定。

  • 当使用“奇校验检查”时,如果字符数据位中“1”的数目是偶数,校验位应为“1”,如果“1”的数目是奇数,校验位应为“0”。
  • 当使用“偶校验检查”时,如果字符数据位中“1”的数目是偶数,则校验位应为“0”,如果是奇数则为“1”。

这里列举奇偶校验检查的一个实例,看看 ASCII 字符“R”,其位构成是1010010。由于字符“R”中有 3 个位为“1”,若使用奇校验检查,则校验位为 0;如果使用偶校验检查,则校验位为 1。在传输过程中,若有 1 位(或奇数个数据位)发生错误,使用奇偶校验检查,可以知道发生传输错误。若有 2 位(或偶数个数据位)发生错误,使用奇偶校验检查,就不能知道已经发生了传输错误。但是奇偶校验检查方法简单,使用方便,发生 1 位错误的概率远大于 2位的概率,所以“奇偶校验”这种方法还是最为常用的校验方法。几乎所有 MCU 的串行异步通信接口,都提供这种功能。

1.2.4 波特率


单位是:位/秒,记为bps

波特率可以认为是传输数据的速率,所以发送一位二进制的时间就是波特率的倒数。通常使用的波特率有 600、900、1200、1800、2400、4800、9600、19200、38400、57600、115200 等。

UART0 和 UART1 时钟源为内核时钟,UART2~UART5 的时钟源为外设时钟(总线时钟)。波特率由一个 13 位的模数计数器(SBR)和一个 5 位的分数微调计数器(BRFD)共同决定。13 位SBR[SBR]范围 1~8191,它决定了模块的时钟分频。微调计数器给波特率时钟增加一个细微的延时,以便匹配系统波特率。波特率时钟与模块时钟同步并驱动接收器。计算公式如下:

  • 波特率 = UART 模块时钟/(16*(SBR[SBR]+BRFD))

SBR由波特率寄存器配置,BRFD由控制寄存器4配置

波特率一致是发送方与接收方实现通信的必要条件


0x02 代码部分

2.1 整体框架

在这里插入图片描述

2.2 串口初始化

uart_init(UART3,115200); 以串口模块3为例,波特率=115200

2.2.1 引脚初始化

补充说明:代码中有 MASK 关键字的部分代表"掩码",作用于寄存器,与寄存器做位运算,表示寄存器对应位的有效性。以下不再不再重复说明
 case UART3:
        SIM_SCGC4 |= SIM_SCGC4_UART3_MASK;      //使能UART3时钟

        if(UART3_RX == PTE5)
        {
   
            port_init( PTE5, ALT3);              //在PTE5上使能UART3_RXD
        }
        else if(UART3_RX == [...]){
   ...}
        ...
        else ASSERT(0);  //上诉条件都不满足,直接断言失败了,设置管脚有误?
       
        if(UART3_TX == PTE4)
        {
   
            port_init( PTE4, ALT3);             //在PTE4上使能UART3_TXD
        }
        if(UART3_TX == [...]){
   ...}
        ...
        else ASSERT(0);  //上诉条件都不满足,直接断言失败了,设置管脚有误?
        
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值