嵌入式系统: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复用为HFXT
	PJ->SEL1 &=~(BIT2 | BIT3);
	PJ->SEL0 |= (BIT2 | BIT3);
	
	//解锁时钟寄存器(0x695A)
	CS->KEY = CS_KEY;
	
	//HCLK 16MHz
	CS->CTL2 |= CS_CTL2_HFXTFREQ_2 | CS_CTL2_HFXTDRIVE | CS_CTL2_HFXT_EN;
	//SMCLK 4MHz
	CS->CTL1 |= CS_CTL1_DIVS_2 | CS_CTL1_SELS_5;
	//SMCLK 时钟源使能
	CS->CLKEN |= CS_CLKEN_SMCLK_EN;
	
	//锁住时钟寄存器(0xA569)
	CS->KEY = CS_KEY_KEY_OFS;

	//GPIO复用为UART
   	P1->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) = 26
	EUSCI_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 <ti/devices/msp432p4xx/driverlib/driverlib.h>


void main(void)
{
	/* Halting WDT  */
    MAP_WDT_A_holdTimer();
	
	//GPIO复用为HFXT
	GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ,GPIO_PIN3 | GPIO_PIN2,GPIO_PRIMARY_MODULE_FUNCTION);
	
	//HCLK 16MHz
	CS_setExternalClockSourceFrequency(32000,16000000);
	CS_startHFXT(false);
	
	//SMCLK 4MHz
	CS_initClockSignal(CS_SMCLK,CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_4);
	CS_enableClockRequest(CS_SMCLK);
	
	//GPIO复用为UART
	MAP_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));
    }

}
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值