数字通信基本知识
组成
串行通信和并行通信
- 串行通信:将数据一位一位地由端口送出或接收进来
- 并行通信:数据的各个数据位(一般为8位及其整数倍)在多条数据线上同时被传输
- 并行通信的传输速度快、效率高,但抗干扰能力差,且需要的资源多,一般用于短距离、高带宽的大数据量传输
- 串行通信节省传输线,但数据传送效率没有并行通信高
同步通信和异步通信
- 异步通信:处理器之间不使用公共的参考时钟,通信双方分别有自己的时钟源,但必须使用相同的波特率。例如UART就是属于串行异步通信。
- 同步通信:由主机提供时钟与数据,从机使用该时钟接收数据或发送数据,即通信双方公用时钟源。例如:SPI和I2C就属于串行同步通信。
异步串行通信的通用基础知识
定义
串行通信接口,即异步串行通信,简称UART,也就是我们常说的“串口”或SCI,在USB未普及之前,就是PC机必备的通信接口之一
特殊地位
串行通信具有特殊重要地位的原因
- 原因一:在通信方式上,属于单字节通信,是嵌入式开发中重要的调试手段之一
- 原因二:它是最简单的串行通信方式,硬件上所说的232、485通信均是指这个串口通信
- 原因三:硬件接线简单,与MCU引脚直接相连的一般只需要发送线、接收线和地线
异步串行通信的格式
串行通信数据以字节为单位,按位的顺序从发送线送出。从MCU引脚来看,高电平就是逻辑“1”,低电平就是逻辑“0”
串行通信格式
- 串行通信的发送线,平时处于逻辑“1”状态
- 开始发送一个字节前,先发送一位逻辑“0”,即起始位,表示发送一个字节的开始
- 随后发送一个字节,然后回到平时状态的逻辑“1”
- 每发送一个字节前,均要先发送一个逻辑”0“,这个起始位这就是”异步“之含义,所以称为异步通信
- LSB模式 最低有效位模式
- MSB模式 最高有效位模式
- UART默认LSB模式
串行通信的波特率
波特率定义
人们把每秒内传送的位数叫做波特率
单位是:位/秒,记为bps
常用的波特率有9600、19200等
波特率基本概念
在包含开始位与停止位的情况下,发送一个字节需要10位,很容易计算出,在特定波特率下,发送1K字节所需要的时间。波特率越高,位长越小,易受电磁干扰,所以串行通信速度不能很高。距离短时可以适当提高波特率,但提高幅度有限
奇偶校验
目的
在异步串行通信中,如何知道一个字节的传输是否正确?最常见的方法是增加一个位(奇偶校验位),供错误检测使用
定义
? 字符奇偶校验检测(Character Parity Checking,CPC)称为垂直冗余检测(Vertical Redundancy,VRC),它是为每个字符增加一个额外位使字符中“1”的个数为奇数或偶数
? 奇数或偶数依据使用的是“奇校验检查”还是“偶校验检查”而定。当使用”奇校验检查“时,如果字符数据位中“1”的数目是偶数,校验位应为“1”,如果“1”的数目是奇数,校验位应为“0”。当使用”偶校验检查“时,如果字符数据位中“1”的数目是偶数,校验位应为“0”,如果是奇数则为“1”
实例
ASCII字符”R“,其位构成是1010010
由于字符“R”中有3个位为“1”,若使用奇校验检查,则校验位为0;如果使用偶校验检查,则校验位为1
注:几乎所有的MCU的串行异步通信接口,都提供这种功能。但实际编程使用较少,原因是单字节校验意义不大
串行通信传输方式术语
1.全双工(Full-duplex)
? 数据传送是双向的,且可以同时接收与发送数据。这种传输方式中,除了地线之外,需要两根数据线,站在任何一端的角度看,一根为发送线,另一根为接收线。一般情况下,MCU的异步串行通信接口均是全双工的。
2.半双工(Half-duplex)
? 数据传送也是双向的,但是在这种传输方式中,除地线之外,一般只有一根数据线。任何时刻,只能由一方发送数据,另一方接收数据,不能同时收发。
3.单工(Simplex)
? 数据传送是单向的,一端为发送端,另一端为接收端。这种传输方式中,除了地线之外,只要一根数据线就可以了。有线广播就是单工的。
为使数据传输得更远,美国电子工业协会制定了串行物理接口标准RS232
异步创新通信格式:实际的异步串行通信采用的是NRZ数据格式,即“标准不归零传号/空号数据格式”。“不归零”是:用负电平表示一种二进制值,正电平表示另一种二进制值,不使用零电平。“传号/空号”分别是表示两种状态的物理名称,逻辑名称记为“1/0”。
RS232总线标准
- RS232采用负逻辑
- -15V ~ -3V为逻辑 “ 1 ”
- +3V ~ +15V为逻辑 “ 0 ”
- 最大的传输距离是30m
- 通信速率一般低于20Kbps
9芯串行接口排列
注:RS232一般使用9芯串行接口
引脚号 | 功能 | 引脚号 | 功能 |
---|
1 | 接收线信号检测 | 6 | 数据通信设备准备就绪(DSR) | 2 | 接收数据线(RXD) | 7 | 请求发送(RTS) | 3 | 发送数据线(TXD) | 8 | 允许发送(CTS) | 4 | 数据终端准备就绪(DTR) | 9 | 振铃指示 | 5 | 信号地(SG) | | |
注:在RS232通信中,常常只用三根线:接收线、发送线和地线
? 随着USB接口的普及,9芯接口正在逐渐从PC机,特别是从便携式电脑上消失。于是出现232-USB转换线、TTL-USB转换线,在PC机上安装相应的驱动软件,就可在PC机上使用一般的串行通信编程方式,通过USB接口实现与MCU的串行通信。
编程时,程序员并不直接与“发送移位寄存器”和“接收移位寄存器”打交道,只与数据寄存器打交道。
若可以发送,则将待发送的数据放入“数据寄存器”中就可以了,剩下的工作由MCU自动完成。
MCU会将数据从“数据寄存器”送到“发送移位寄存器”,硬件将“发送移位寄存器”的数据一位一位地按照规定的波特率移到发送引脚,供对方接收。
接受时,数据一位一位地从接收引脚进入“接收移位寄存器”,当收到一个完整字节时,MCU会自动将数据送入“数据寄存器”,并将状态寄存器的相应位改变,供程序员判定并取出数据。
UART编程相关
eUSCI模式下的UART
Enhanced Universal Serial Communication Interface
增强的通用串行通信接口(eUSCI)模块支持多种串行通信模式。不同的eUSCI模块支持不同的模式。每一个不同的eUSCI模块以不同的字母命名,例如:eUSCI_A、eUSCI_B等。MSP432单片机实现了不止一个相同的eUSCI模块,这些模块将以递增的数字命名,例如,MSP432单片机支持四个eUSCI_A模块时,这四个模块应该被命名为eUSCI_A0、eUSCI_A1、eUSCI_A2、eUSCI_A3。
eUSCI_A模块支持以下通信模式:
- UART通信模式;
- 具有脉冲整型的IrDA通信模式;
- 具有自动波特率检测的LIN通信模式;
- SPI通信模式。
USCI_B模块支持以下通信模式:
- IIC通信模式;
- SPI通信模式。
下面首先介绍eUSCI的异步模式——URAT。
UART
Universal Asynchronous Receiver and Transmitter
异步通信收发器
UART的特点及结构
UART即异步串行通信,可设置成全双工异步通讯方式,与PC(个人计算机)等通讯;或设置成半双工同步模式与其他外设通信,如ADC或DAC。
MSP432单片机内置了UART功能,它的作用是将外部设备串行数据转换为并行数据接收;讲内部并行数据转换为串行数据发送。在通用异步收发模式下eUSCI_Ax模块通过两个外部收发引脚UCAxRXD和UCAxTXD把MSP432单片机与外界连接起来。当寄存器UCAxCLT0的UCSYNC控制位被清零,UCMODEx控制位被配置为00时,eUSCI_A模块被配置为UART异步通信模式。
UART的特点如下:
- 传输7位或8位数据,可采用奇校验、偶校验或者无校验;
- 具有独立的发送和接收移位寄存器;
- 具有独立的发送和接收缓存寄存器;
- 支持最低位优先或最高位优先的数据发送和接收方式;
- 内置多处理器系统,包括线路空闲和地址位通信协议;
- 通过有效的起始位检测,将MSP432单片机从低功耗模式下唤醒;
- 可编程实现分频因子为整数或小数;
- 具有用于检测错误或排除错误的状态标志位;
UART运行机理
在UART模式下,其结构如图。由图可知,在UART模式下,eUSCI_A模块由串行数据接收逻辑(图①)、波特率发生器(图②)和串行数据发送逻辑(图③)三个部分组成。串行数据接收逻辑用于接收串行数据,包括接收移位寄存器、接收缓存寄存器和接收状态寄存器以及接收标志位设置逻辑。波特率发生器用于产生接收和发送的时钟信号,其参考时钟可以来源于ACLK或SMCLK,也可以来自于外部时钟输入UCLK,通过整数或小数分频得到特定的数据传输波特率。传输数据发送逻辑用于发送串行数据,包括发送移位寄存器、发送缓存寄存器和发送状态寄存器以及发送标志位设置逻辑。在UART模式下,eUSCI_A异步的以一定速率向另一个设备发送和接收字符,每个字符的传输时钟是基于软件对波特率的设定,发送和接收要使用相同的波特率。
应用
串口是嵌入式系统与外界联系的重要手段,主要用于以下两个方面:
- UART直接和其他的控制器进行数据交换
- UART和PC机通信:由于PC机串口是RS232电平,所以连接时需要使用RS232转换器
使用UART通信
使用UART通信需要两个引脚(将在下面的示例中用到),如下表:
引脚名称 | 类型 | 描述 |
---|
RXD | 输入 | 串行输入,接收数据 | TXD | 输出 | 串行输出,发送数据 |
串行发送机TxMachine
TxMachine支持下面的工作特性:
- 奇偶校验位的生成
- 清除发送
- 中断字符发送
- 双缓存区操作
串行接收机RxMachine
RxMachine把接收到的串行数据送到接收移位寄存器,接收完成后,数据送到串行接收缓存寄存器(SxRBUF),用户从SxRBUF中读取接收到的数据。
串行接收机在接收过程中能够检测出以下三种错误条件:
- 奇偶校验错:检测到奇偶校验错时,奇偶错标志位被置位。
- 帧错误:未收到停止位时,帧错误标志位被置位。
- 超越错误:当接收到一个新的字符前,以前收到的字符没有被CPU读走,旧的数据被覆盖,那么超越错误标志位被置位。
波特率的计算
一般填入波特率寄存器中的值都是通过如下的公式求出来:
UART_BR = MCLK / (BaudRate * N)
注意:N为波特率因子,大多数芯片取N = 16
有些波特率计算精度较高,它们有两个波特率寄存器UART_BR1和UART_BR2,其中UART_BR1则用来存放上式计算出来的整数部分,而UART_BR2则用来存放上式计算出来的小数部分,这样计算出来的波特率就更精确,误差更小。
如果假设时钟源选择12MHz,如果要取UART2的9600波特率,那么如何计算
- N = 12000000/9600 = 1250
- 1 -> OS16 UCBR2 = INT(1250/16) = 78
- UCBRF2 = INT(N/ 6 - INT(N/16)) * 16 = INT(0.125 * 16) = 2
- N = N - INT(N)
其中根据第一步,N=1250,INT(N)=0,因此N-INT(N)=0,查表TABLE24-4,可以得到UCBRSx的值应该为0.
注意,如果N-INT(N)不等于0,那么按照官方文档要求,在TABLE24-4中按照往前靠的原则进行查表,例如小数部分为0.125,那么查表对应数据为0.100对应的数值。
UART相关寄存器
1寄存器地址分析
- MSP432芯片有四个UART模块。每个模块有其对应的寄存器。以下地址分析均为16进制,为书写简化起见,在不至于引起歧义的情况下,略去十六进制后缀“0x”不写。
- UART模块x的寄存器地址=4000_1000+x * 400+n * 2(x = 0~3;n = 0~15(除2、10、11、12), n代表寄存器号)。
2控制寄存器
- eUSCI_Ax控制字寄存器0(UCAxCTLW0)
- eUSCI_Ax控制字寄存器1(UCAxCTLW1)
- eUSCI_Ax中断使能寄存器(UCAxIE)
- eUSCI_Ax调制控制字寄存器(UCAxMCTLW)
3状态寄存器
- eUSCI_Ax状态寄存器(UCAxSTATW)
- eUSCI_Ax中断标志寄存器(UCAxIFG)
- eUSCI_Ax中断向量寄存器(UCAxIV)
4波特率寄存器
- eUSCI_Ax波特率控制字寄存器(UCAxBRW)
- eUSCI_Ax自动波特率控制寄存器(UCAxABCTL)
5数据寄存器
- eUSCI_Ax接收缓存区寄存器(UCAxRXBUF)
- eUSCI_Ax发送缓存区寄存器(UCAxTXBUF)
常用波特率列表
- 300
- 600
- 1200
- 2400
- 4800
- 9600
- 19200
- 38400
- 43000
- 56000
- 57600
- 115200
MSP432中的UART
当MSP432要发送数据时,发送缓冲器中要发送的值装入发送移位寄存器中,再一位一位地从发送端口UCAxTXD发送出去。
当MSP432要接收数据时,数据从UCAxRXD一位一位地送入接收移位寄存器,然后装入接收缓存寄存器中。接收端在接收数据时可以实现错误检测、解码、帧听等功能。
初始化配置
- 时钟配置——时钟源、时钟频率等
- GPIO配置——TXD、RXD
- UART配置——数据帧格式、波特率等
- 中断配置
UART相关的SDK函数
void UART_clearInterruptFlag ( uint32_t moduleInstance,uint_fast8_t mask )
Clears UART interrupt sources.
void UART_disableInterrupt ( uint32_t modulelnstance,uint_fast8_t mask )
Disables individual UART interrupt sources.
void UART_disableModule ( uint32_t modulelnstance )
Disables the UART block.
void UART_enableInterrupt ( uint32_t modulelnstance,uint_fast8_t mask )
Enables individual UART interrupt sources.
void UART_enableModule ( uint32_t modulelnstance )
Enables the UART block.
uint_fast8_t UART_getEnabledInterruptStatus ( uint32_t modulelnstance )
Gets the current UART interrupt status masked with the enabled interrupts. This function is usefulto call in lSRs to get a list of pending interrupts that are actually enabled and could have causedthe lSR.
uint_fast8_t UART_getInterruptStatus ( uint32_t modulelnstance,uint8_t mask )
Gets the current UART interrupt status.
bool UART_initModule ( uint32_t modulelnstance,consteusCI_UART_ConfigV1 * config )
Initialization routine for the UART block.The values to be written into the UCAxBRW and UCAxMCTLW registers should be pre-computed and passed into the initialization function.
UART操作实例
程序功能:MSP432通过UART与PC通信。
描述:MSP432将通过串口收到的字符发回给PC,并在串口调试工具中显示出来。UART帧格式被配置为一个起始位,一个停止位,无校验位。使用的波特率为9600Baud。若使用UART0,P1.2与P1.3分别为接收端口与发送端口;若使用UART3,P9.6与P9.7分别为接收端口与发送端口。查看对应针脚可参阅官方手册表4-1。下面是MSP432通过UART0和UART3与PC通信:
UART0:UCA0RXD(P1.2),UCA0TXD(P1.3)
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK,
78,
2,
0,
EUSCI_A_UART_NO_PARITY,
EUSCI_A_UART_LSB_FIRST,
EUSCI_A_UART_ONE_STOP_BIT,
EUSCI_A_UART_MODE,
EUSCI_A_UART_OVERSAMPLINE_BAUDRATE_GENERATION
};
int main(void)
{
MAP_WDT_A_holdTimer();
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN1|GPIO_PIN2|GPIO_PIN3,GPIO_PRIMARY_MODULE_FUNCTION);
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
MAP_UART_initModule(EUSCI_A0_BASE,&uartConfig);
MAP_UART_enableModule(EUSCI_A0_BASE);
MAP_UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA0);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableMaster();
printf("Hello MSP432!\r\n");
UART_transmitData(EUSCI_A0_BASE,'A');
UART_transmitData(EUSCI_A0_BASE,'B');
while(1)
{
MAP_PCM_gotoLPM0();
}
}
void EUSCIA0_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A0_BASE);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
uint32_t val;
val = UART_receiveData(EUSCI_A0_BASE);
UART_transmitData(EUSCI_A0_BASE,val);
}
}
int fputc(int ch,FILE *f)
{
UART_transmitData(EUSCI_A0_BASE,ch & 0xFF);
return ch;
}
int fgetc(FILE *f)
{
while(EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG != UART_getInterruptStatus(EUSCI_A0_BASE,EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG));
return UART_receiveData(EUSCI_A0_BASE);
}
UART3:UCA3RXD(P9.6),UCA3TXD(P9.7)
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
const eUSCI_UART_Config uartConfig =
{
EUSCI_A_UART_CLOCKSOURCE_SMCLK,
78,
2,
0,
EUSCI_A_UART_NO_PARITY,
EUSCI_A_UART_LSB_FIRST,
EUSCI_A_UART_ONE_STOP_BIT,
EUSCI_A_UART_MODE,
EUSCI_A_UART_OVERSAMPLINE_BAUDRATE_GENERATION
};
int main(void)
{
MAP_WDT_A_holdTimer();
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P9,GPIO_PIN6|GPIO_PIN7,GPIO_PRIMARY_MODULE_FUNCTION);
CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);
MAP_UART_initModule(EUSCI_A3_BASE,&uartConfig);
MAP_UART_enableModule(EUSCI_A3_BASE);
MAP_UART_enableInterrupt(EUSCI_A3_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);
MAP_Interrupt_enableInterrupt(INT_EUSCIA3);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableMaster();
printf("Hello MSP432!\r\n");
UART_transmitData(EUSCI_A3_BASE,'A');
UART_transmitData(EUSCI_A3_BASE,'B');
while(1)
{
MAP_PCM_gotoLPM0();
}
}
void EUSCIA3_IRQHandler(void)
{
uint32_t status = MAP_UART_getEnabledInterruptStatus(EUSCI_A3_BASE);
if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG)
{
uint32_t val;
val = UART_receiveData(EUSCI_A3_BASE);
UART_transmitData(EUSCI_A3_BASE,val);
}
}
int fputc(int ch,FILE *f)
{
UART_transmitData(EUSCI_A3_BASE,ch & 0xFF);
return ch;
}
int fgetc(FILE *f)
{
while(EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG != UART_getInterruptStatus(EUSCI_A3_BASE,EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG));
return UART_receiveData(EUSCI_A3_BASE);
}
资料
MSP432P401R官方手册
|