嵌入式系统:UART

UART

在这里插入图片描述


(一)通信方式

1.串行通信与并行通信

(1)串行通信
在这里插入图片描述

  • 数据逐位发送

(2)并行通信
在这里插入图片描述

  • 多位同时发送

2.同步通信与异步通信

(1)同步通信

  • 在同一个时钟信号下进行数据传输

(2)异步通信

  • 在不同的时钟信号下进行数据传输

3.单工、半双工、全双工通信

(1)单工通信
在这里插入图片描述

  • 单向传输,收/发

(2)半双工通信
在这里插入图片描述

  • 双向传输,可发可收,但不能同时进行

(3)全双工通信
在这里插入图片描述

  • 双向传输,同时收发

(二)UART基本原理

1.通信方式

(1)异步串行通信

(2)半双工通信

2.UART时序

在这里插入图片描述

  • 时钟高电平空闲(数据发送)
  • 时钟低电平采样(数据接收)

3.数据帧

(1)目的:减小发送与接收的时序误差

(2)数据帧格式

  • idle:准备通信,电平拉高

  • start:开始通信,电平拉低

  • data:数据位(7/8)

    • LSB:低位数据发送
    • MSB:高位数据发送
  • Parity:奇偶校验位,检验数据

    • 奇校验:奇偶校验位置0或1,使得数据位与奇偶校验位1的个数为奇数
    • 偶校验:奇偶校验位置0或1,使得数据位与奇偶校验位1的个数为偶数
  • stop:停止通信,电平拉高


4.过采样(oversampling)与时钟误差

在这里插入图片描述

(1)目的:减小误码率

(2)原因:虽然有了数据帧可以大幅度减小误码率,但在数据帧内的少许数据可能产生误差


(3)过采样

在这里插入图片描述

  • 在嵌入式arm微控制器中,发送时钟频率为接收时钟的1/16
  • 重复检测接收数据16次,取中间几次投票确定

  • 时钟误差(5%左右)

在这里插入图片描述


(三)编程

1.编程流程

(1)GPIO复用为UART模式

(2)UART功能配置

  • 波特率(时钟信号)
  • 数据帧各模式设置

(3)UART模块使能

(4)UART中断配置

  • 中断优先级
  • 中断使能

(5)数据收发

  • 查询模式
  • 中断模式

2.编程实例

(1)寄存器编程

#include "msp.h"
#include "driverlib.h" 
/*
The recommended eUSCI_A initialization/reconfiguration process is:
1. Set UCSWRST.
2. Initialize all eUSCI_A registers with UCSWRST = 1 (including UCAxCTL1).
3. Configure ports.
4. Clear UCSWRST with software.
5. Enable interrupts (optional) with UCRXIE or UCTXIE.
*/
int main()
{WDTCTL = WDTPW + WDTHOLD;           //关闭看门狗//GPIO复用为HFXTPJ->SEL1 &=~(BIT2 | BIT3);PJ->SEL0 |= (BIT2 | BIT3);//解锁时钟寄存器(0x695A)CS->KEY = CS_KEY;//HCLK 16MHzCS->CTL2 |= CS_CTL2_HFXTFREQ_2 | CS_CTL2_HFXTDRIVE | CS_CTL2_HFXT_EN;//SMCLK 4MHzCS->CTL1 |= CS_CTL1_DIVS_2 | CS_CTL1_SELS_5;//SMCLK 时钟源使能CS->CLKEN |= CS_CLKEN_SMCLK_EN;//锁住时钟寄存器(0xA569)CS->KEY = CS_KEY_KEY_OFS;//GPIO复用为UARTP1->SEL0 |=  (BIT2 | BIT3);P1->SEL1 &=~ (BIT2 | BIT3);//UART模块复位(在复位状态下控制相关寄存器才能配置)EUSCI_A0->CTLW0 |= EUSCI_A_CTLW0_SWRST;//时钟源选择EUSCI_A0->CTLW0 |= EUSCI_A_CTLW0_SSEL__SMCLK;//波特率:4MHz 9600 (4000000 / (16 * 9600) = 26EUSCI_A0->BRW	 = 26;//校验位使能,默认配置(8位数据(低位优先) + 1位停止位 + 偶检验)EUSCI_A0->CTLW0 |= EUSCI_A_CTLW0_PEN;//过采样使能EUSCI_A0->MCTLW |= EUSCI_A_MCTLW_OS16;//释放复位EUSCI_A0->CTLW0 &= ~EUSCI_A_CTLW0_SWRST;//清除接收中断标志位EUSCI_A0->IFG	&=~EUSCI_A_IFG_RXIFG;//接收中断使能EUSCI_A0->IE 	|= EUSCI_A_IE_RXIE;while(1);
}void EUSCIA0_IRQHandler(void)
{//接收中断使能if(EUSCI_A0->IFG & EUSCI_A_IFG_RXIFG){//清除接收中断标志位EUSCI_A0->IFG	&=~EUSCI_A_IFG_RXIFG;//数据回传(发送 = 接收)EUSCI_A0->TXBUF  = EUSCI_A0->RXBUF;}}

(2)库函数编程

#include "msp.h"
#include void main(void)
{/* Halting WDT  */MAP_WDT_A_holdTimer();//GPIO复用为HFXTGPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,GPIO_PIN3 | GPIO_PIN2,GPIO_PRIMARY_MODULE_FUNCTION);//HCLK 16MHzCS_setExternalClockSourceFrequency(32000,16000000);CS_startHFXT(false);//SMCLK 4MHzCS_initClockSignal(CS_SMCLK,CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);CS_enableClockRequest(CS_SMCLK);//GPIO复用为UARTMAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);//UART功能配置eUSCI_UART_ConfigV1 uartConfig;uartConfig.uartMode				= EUSCI_A_UART_MODE;uartConfig.selectClockSource	= EUSCI_A_UART_CLOCKSOURCE_SMCLK;uartConfig.overSampling			= EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;uartConfig.clockPrescalar	 	= 26;uartConfig.firstModReg			= 0;uartConfig.secondModReg			= 0;uartConfig.msborLsbFirst		= EUSCI_A_UART_LSB_FIRST;uartConfig.dataLength			= EUSCI_A_UART_8_BIT_LEN;uartConfig.parity				= EUSCI_A_UART_ODD_PARITY;uartConfig.numberofStopBits		= EUSCI_A_UART_ONE_STOP_BIT;UART_initModule(EUSCI_A0_BASE, &uartConfig);//接收中断使能UART_enableInterrupt(EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT);//UART使能UART_enableModule(EUSCI_A0_BASE);while(1);
}void EUSCIA0_IRQHandler(void)
{uint32_t status = UART_getEnabledInterruptStatus(EUSCI_A0_BASE);if(status & EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG){UART_clearInterruptFlag(EUSCI_A0_BASE,EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG);UART_transmitData(EUSCI_A0_BASE, MAP_UART_receiveData(EUSCI_A0_BASE));}}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部