春娇霹雳娃 发表于 2023-7-31 16:56

UART和USART有何区别?基于MM32G0001实现同步/异步串行接受发送器

本帖最后由 春娇霹雳娃 于 2023-8-1 09:30 编辑

#申请原创# @21小跑堂

1.引言
USART(Universal Synchronous/Asynchronous Receiver/Transmitter),是通用同步/异步串行接收/发送器。与UART相同点:均存在异步模式、多处理通信、智能卡功能、IrDA红外功能。
USART与UART的区别在于:

[*]USART多支持一个同步模式;
[*]在异步模式下,等同于UART;
[*]在同步模式下,可当做SPI来用,比如用USART来驱动SPI设备;



MM32G0001使用高性能的 Arm® Cortex-M0 为内核的 32 位微控制器,最高工作频率可达 48MHz,内置高速存储器,丰富的增强型 I/O 端口和多种外设。含16KB Flash,2KB SRAM。

其电路图如下图所示:


本实验基于MINI-G0001开发板,实现usart三个样例。

2.实验原理
USART结构框图:


波特率配置公式不同:

[*]异步通信模式:




[*]同步通信模式:



/* Set usart synchronous baudrate. */
void USART_SetBaudrateSync(USART_Type * USARTx, USART_SyncBaudrate_Type * sync)
{
    USARTx->BRR &= ~(USART_BRR_FFD_MASK | USART_BRR_MFD_MASK);
    USARTx->BRR |= USART_BRR_MFD( (sync->ClockFreqHz / sync->BaudRate) / 4u);
}

/* set usart asynchronous baudrate. */
void USART_SetBaudrateAsync(USART_Type * USARTx, USART_AsyncBaudrate_Type * async)
{
    USARTx->BRR &= ~(USART_BRR_FFD_MASK | USART_BRR_MFD_MASK);
    uint8_t N = 8u * (2u - async->OverSampling);
    USARTx->CR1 |= USART_CR1_OVER8(async->OverSampling);
    uint32_t temp = async->ClockFreqHz / async->BaudRate;
    USARTx->BRR |= USART_BRR_MFD( temp / N ) | USART_BRR_FFD( temp % N );
}
同步时钟:
在USART使用同步模式时,数据传输需要一条时钟线CLK及一条数据线
同步模式支持主模式和从模式:主模式时使用内部波特率生成器生成的时钟,同时输出时钟;从模式时由SCLK引脚输入时钟。



USART数据帧:


USART 内置检测电路检测一帧数据的开始,并对 RX 引脚进行采样, USART 采用 8 或 16 倍数据波特率的时钟采样 RX 引脚的数据。


奇偶校验:
偶校验: 校验位加上数据中’1’的总数为偶数
奇校验: 校验位加上数据中’1’的总数为奇数

[*]配置 USART_CR1 寄存器中的 PCE 位为’1’来使能奇偶校验控制,PS 位用来选择奇校验或偶校验



3.软件设计
配置引脚
void BOARD_InitPins(void)
{
    /* PA12 - USART_TX. */
    GPIO_Init_Type gpio_init;
    gpio_init.Pins= GPIO_PIN_12;
    gpio_init.PinMode= GPIO_PinMode_AF_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpio_init);
    GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_1);

    /* PA3 - USART_RX. */
    gpio_init.Pins= GPIO_PIN_3;
    gpio_init.PinMode= GPIO_PinMode_In_PullUp;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &gpio_init);
    GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_1);
}
开启时钟
/* USART. */
    RCC_EnableAPB1Periphs(RCC_APB1_PERIPH_USART1, true);
    RCC_ResetAPB1Periphs(RCC_APB1_PERIPH_USART1);配置USART
/* DEBUG UART. */
#define BOARD_DEBUG_USART_PORT      USART1
#define BOARD_DEBUG_USART_BAUDRATE    9600u
#define BOARD_DEBUG_USART_FREQ      CLOCK_APB1_FREQ
4.实验样例
usart_basic
使用异步模式,与串口通信工具进行数据收发,主函数如下:
int main(void){
    uint8_t c;

    BOARD_Init();

    app_usart_init();
    app_usart_putstr((uint8_t *)"\r\nusart_basic example.\r\n");

    while (1){
      c = app_usart_getchar();
      app_usart_putchar(c);}}usart_rx_interrupt

每当键入,LED会闪灯
int main(void)
{
    BOARD_Init();

    app_usart_init();

    while (1){}
}

/* Initialization USART asynchtonous mode. */
void app_usart_init(void){
    /* Initialization USART asynchronous mode. */
    USART_InitAsync_Type usart_init;
    usart_init.EnableSwapTxRxXferSignal = false;
    usart_init.Parity = USART_Parity_None;
    usart_init.StopBits = USART_StopBits_1;
    usart_init.WordLength = USART_WordLength_8b;
    usart_init.XferMode = USART_XferMode_RxTx;
    usart_init.XferSignal = USART_XferSignal_Normal;

    /* Set USART asynchronous baudrate. */
    USART_AsyncBaudrate_Type usart_baudrate;
    usart_baudrate.BaudRate = BOARD_DEBUG_USART_BAUDRATE;
    usart_baudrate.ClockFreqHz = BOARD_DEBUG_USART_FREQ;
    usart_baudrate.OverSampling = USART_OverSampling_16;

    USART_InitAsync(BOARD_DEBUG_USART_PORT, &usart_init);
    USART_SetBaudrateAsync(BOARD_DEBUG_USART_PORT, &usart_baudrate);
    USART_EnableInterrupts(BOARD_DEBUG_USART_PORT, USART_STATUS_RX_NOTEMPTY, true);
    NVIC_EnableIRQ(BOARD_DEBUG_USART_IRQn);
    USART_Enable(BOARD_DEBUG_USART_PORT, true);/* Enable USART. */}usart_tx_interrupt
观察到串口输出多遍键入的字符
void app_usart_putstr_init(uint8_t c)
{
    /* prepare the buffer. */
    for (uint32_t i = 0u; i < APP_USART_TX_BUFF_LEN; i++)
    {
      app_usart_tx_buff = c;
    }
    app_usart_tx_buff_idx = 0u;

    /* enable the tx interrupt to transmit the buffer. */
    USART_EnableInterrupts(BOARD_DEBUG_USART_PORT, USART_STATUS_TX_EMPTY, true);
}/* USART get data. */
uint8_t app_usart_getchar(void)
{
    while ( 0u == (USART_STATUS_RX_NOTEMPTY & USART_GetStatus(BOARD_DEBUG_USART_PORT) ) )
    {
    }
    return USART_GetData(BOARD_DEBUG_USART_PORT);
}
5.附件
工程文件:
原理图:


春娇霹雳娃 发表于 2023-8-2 11:35

caigang13 发表于 2023-8-2 20:00

同步串口需要时钟,实际很少这样用。

albertaabbot 发表于 2023-8-4 16:55

1、UART:universal asynchronous receiver and transmitter通用异步收发器;2、USART:universal synchronous asynchronous receiver and transmitter通用同步异步收发器。

春娇霹雳娃 发表于 2023-8-4 17:03

albertaabbot 发表于 2023-8-4 16:55
1、UART:universal asynchronous receiver and transmitter通用异步收发器;2、USART:universal synchron ...

lzmm 发表于 2023-8-4 17:22

它们在功能和特性上有一些区别。            

春娇霹雳娃 发表于 2023-8-4 17:28

lzmm 发表于 2023-8-4 17:22
它们在功能和特性上有一些区别。

maudlu 发表于 2023-8-4 17:33

工作方式不一样而已!               

uptown 发表于 2023-8-4 17:44

USART支持同步传输,可以通过外部时钟信号进行数据传输,而UART只支持异步传输。

pentruman 发表于 2023-8-4 17:56

USART相对UART的区别之一就是能提供主动时钟。

houjiakai 发表于 2023-8-4 18:09

USART通常提供了更多的异常检测功能,例如帧错误、奇偶校验错误等。

updownq 发表于 2023-8-4 18:16

UART是一种异步串行通信接口,用于在计算机系统中传输数据。它使用一个引脚进行数据传输,即发送数据和接收数据共用一个引脚。UART通信是一种简单的、不同步的通信方式,数据以字节为单位进行传输,每个字节之间使用起始位和停止位进行分隔。UART通常用于低速通信,例如串口通信。

USART是一种通用的串行通信接口,可以同时支持异步和同步通信。与UART不同,USART具有独立的发送和接收引脚,因此可以同时进行发送和接收操作。

belindagraham 发表于 2023-8-4 18:24

UART和USART在通信方式、数据位数、停止位、时钟极性和可靠性等方面存在一些区别

jimmhu 发表于 2023-8-4 18:41

UART是异步通信,它使用一个单独的时钟信号来同步数据传输;而USART是同步通信,它使用一个同步时钟信号来同步数据传输。

cemaj 发表于 2023-8-4 18:50

在选择使用哪种接口时,需要根据具体的应用需求来决定是否需要同步传输功能以及所需的数据传输速率。

alvpeg 发表于 2023-8-4 19:56

UART的时钟极性可以是正极或负极,而USART的时钟极性只能是正极。

tabmone 发表于 2023-8-4 20:08

使用USART在异步通信的时候,它与UART没有什么区别

backlugin 发表于 2023-8-4 20:16

UART不需要外部时钟信号,而USART在同步传输模式下需要外部时钟信号来同步数据传输。

dspmana 发表于 2023-8-4 20:25

UART是一种通用的异步串行通信接口,而USART在UART的基础上增加了同步传输的能力。

春娇霹雳娃 发表于 2023-8-4 20:52

maudlu 发表于 2023-8-4 17:33
工作方式不一样而已!

页: [1] 2
查看完整版本: UART和USART有何区别?基于MM32G0001实现同步/异步串行接受发送器