嵌入式系统: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));}}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
