MCU微课堂 | CKS32F107xx USART(一)

USART介绍

通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIRENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。

USART主要特性

  • 全双工的,异步通信

  • NRZ标准格式

  • 分数波特率发生器系统

—发送和接收共用的可编程波特率,最高达4.5Mbits/s

  • 可编程数据字长度(8位或9位)

  • 可配置的停止位-支持1或2个停止位

  • LIN主发送同步断开符的能力以及LIN从检测断开符的能力

—当USART硬件配置成LIN时,生成13位断开符;检测10/11位断开符

  • 发送方为同步传输提供时钟

  • IRDA SIR编码器解码器

—在正常模式下支持3/16位的持续时间

  • 模拟智能卡功能

—智能卡接口支持ISO7816-3标准里定义的异步智能卡协议

—智能卡用到的0.5和1.5个停止位

  • 单线半双工通信

  • 可配置的使用DMA的多缓冲器通信

—在SRAM里利用集中式DMA缓冲接收/发送字节

  • 单独的发送器和接收器使能位

  • 检测标志

—接收缓冲器满

—发送缓冲器空

—传输结束标志

  • 校验控制

—发送校验位

—对接收数据进行校验

  • 四个错误检测标

—溢出错误

—噪音错误

—帧错误

—校验错误

  • 10个带标志的中断源

—CTS改变

—LIN断开符检测

—发送数据寄存器空

—发送完成

—接收数据寄存器满

—检测到总线为空闲

—溢出错误

—帧错误

—噪音错误

—校验错误

  • 多处理器通信--如果地址不匹配,则进入静默模式

  • 从静默模式中唤醒(通过空闲总线检测或地址标志检测)

  • 两种唤醒接收器的方式:地址位(MSB,第9位),总线空闲

USART功能概述

任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。

TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。

1、字符发送

在USART发送期间,在TX引脚上首先移出数据的最低有效位。在此模式里,USART_DR寄存器包含了一个内部总线和发送移位寄存器之间的缓冲器。

每个字符之前都有一个低电平的起始位;之后跟着的停止位,其数目可配置。USART支持多种停止位的配置:0.5、1、1.5和2个停止位。

配置步骤:

  1. 通过在USART_CR1寄存器上置位UE位来激活USART

  2. 编程USART_CR1的M位来定义字长。

  3. 在USART_CR2中编程停止位的位数。

  4. 如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器。

  5. 利用USART_BRR寄存器选择要求的波特率。

  6. 设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。

  7. 把要发送的数据写进USART_DR寄存器(此动作清除TXE位)。在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。

  8. 在USART_DR寄存器中写入最后一个数据字后,要等待TC=1,它表示最后一个数据帧的传输结束。当需要关闭USART或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。

2、字符接收

在USART接收期间,数据的最低有效位首先从RX脚移进。在此模式里,USART_DR寄存器包含的缓冲器位于内部总线和接收移位寄存器之间。

配置步骤:

  1. 将USART_CR1寄存器的UE置1来激活USART。

  2. 编程USART_CR1的M位定义字长

  3. 在USART_CR2中编写停止位的个数

  4. 如果需多缓冲器通信,选择USART_CR3中的DMA使能位(DMAR)。按多缓冲器通信所要求的配置DMA寄存器。

  5. 利用波特率寄存器USART_BRR选择希望的波特率。

  6. 设置USART_CR1的RE位。激活接收器,使它开始寻找起始位。

当一字符被接收到时

  • RXNE位被置位。它表明移位寄存器的内容被转移到RDR。换句话说,数据已经被接收并且可以被读出(包括与之有关的错误标志);

  • 如果RXNEIE位被设置,产生中断;

  • 在接收期间如果检测到帧错误,噪音或溢出错误,错误标志将被置起;

  • 在多缓冲器通信时,RXNE在每个字节接收后被置起,并由DMA对数据寄存器的读操作而清零;

  • 在单缓冲器模式里,由软件读USART_DR寄存器完成对RXNE位清除。RXNE标志也可以通过对它写0来清除。RXNE位必须在下一字符接收结束前被清零,以避免溢出错误。

USART程序编写

  1. 开启GPIO、USART1时钟;

  2. 对USART引脚进行配置,PA9映射TX,PA10映射RX;

  3. 对USART参数进行配置、开启USART的RXNE中断;

  4. 对中断参数进行配置;

/*******************************************************************************

* Function Name  : USART_Configuration

* Description    : Configure USART1

* Input          : None

* Output         : None

* Return         : None

* Attention   : None

*******************************************************************************/

void CKS_USART_Init(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;


  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);


  /*USART1_TX -> PA9 , USART1_RX -> PA10*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);     


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;         

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

/* USART configuration ------------------------------------------------------*/

  USART_InitStructure.USART_BaudRate = 115200;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART1, &USART_InitStructure);


/* Enable USART RXNE interrupt */

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

  USART_Cmd(USART1, ENABLE);


/* NVIC configuration ------------------------------------------------------*/

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

5. 编写USART1_IRQHandler函数;

我们利用USART的IDLE状态位进行不定长度数据接收,当USART被RXNE中断触发后,程序将在该中断函数中轮询,直至串口空闲后IDLE状态位被置位。

/*******************************************************************************

* Function Name  : USART1_IRQHandler

* Description    : This function handles USART1 global interrupt request.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void USART1_IRQHandler(void)

{

  uint8_t i = 0;

uint8_t j = 0;


if(USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET)

{

/* get usart data until IDLE flag is set */

while(!USART_GetFlagStatus(USART1, USART_FLAG_IDLE))

{

if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)

{

CKS_Uart_Buff[i++] = USART_ReceiveData(USART1);

}

}


/* clear uart IDLE flag */

j = USART1->SR;

j = USART1->DR;


/* clear uart RXNE flag */

USART_ClearFlag(USART1, USART_IT_RXNE);

}

}

来源:中科芯MCU

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。