【物联网】一文读懂UART通信协议

这篇具有很好参考价值的文章主要介绍了【物联网】一文读懂UART通信协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

硬件实现细节

软件实现细节

UART传输的过程

奇偶校验

stm32单片机上代码实现

HAL库开发

标准库开发

UART是通用异步串行接口(Universal Asynchronous Receiver/Transmitter)的缩写。它是一种用于串行异步全双工通信的通信协议,常用于将计算机和外部设备(如传感器、显示器、模块等)进行串行数据传输。

UART使用一对数据线(一条用于发送数据,一条用于接收数据)来进行通信,通信过程中不需要时钟信号,所以称为异步。发送和接收的数据以字节为单位进行传输,并通过起始位、数据位、校验位和停止位进行格式化,需要注意的是主从之间的接收和发射端口要反接,就是主机TX端要接从机RX端。

uart通信协议,小黑与物联网,单片机,嵌入式硬件

UART具有简单、易于实现和广泛应用的特点,适用于短距离、低速度的数据传输。在计算机和外设之间的串行通信中,UART常常作为主设备和从设备之间的接口。

UART的实现细节通常分为硬件和软件两个方面。

硬件实现细节

1. 发送器(Transmitter):负责将要发送的数据位逐位发送出去。通常由移位寄存器(Shift Register)实现,通过时钟信号将数据逐位移出。

2. 接收器(Receiver):负责接收传输线上的数据位,将其逐位存储在接收缓冲器中。通常也由移位寄存器实现,通过时钟信号将数据逐位移入。

3. 波特率发生器(Baud Rate Generator):用于生成发送和接收时钟信号,控制每个比特的持续时间,从而确定通信的速率。波特率发生器通常由计数器和时钟源构成。

4. 控制逻辑(Control Logic):负责控制发送器、接收器和波特率发生器的操作,包括启动传输、停止传输、校验计算等。

5. 缓冲器(Buffer):用于暂存发送和接收的数据,确保数据的顺序传输和正确接收。

软件实现细节

1. 数据格式和协议:确定数据的格式,如数据位数、校验方式等。常见的协议包括8位数据位、无校验、1位停止位(8N1)。

2. 发送操作:将要发送的数据写入发送缓冲器,并通过控制逻辑控制发送器将数据逐位发送出去。

3. 接收操作:通过控制逻辑控制接收器将接收到的数据位逐个读取并存入接收缓冲器。

4. 中断处理:UART通常支持中断机制,在发送或接收完成后产生中断,通知CPU进行相应的处理。

5. 错误检测和处理:校验位的计算和校验、数据位的解析和处理,以及错误处理(如重发、错误指示等)。

UART传输的过程

1. 起始位(Start Bit):传输开始前,发送线发送一个低电平作为起始位,表示数据的开始。接收线检测到低电平后,开始接收数据。

2. 数据位(Data Bits):发送端将数据位逐位发送,从低位到高位,以二进制形式传输数据。接收端在时钟的边沿进行采样,以确定数据位的值。

3. 校验位(Parity Bit):可选项,用于检测数据位传输过程中的错误。发送端在数据位后面发送校验位,其值与数据位的校验规则相关。接收端通过校验位来验证数据的正确性。

4. 停止位(Stop Bit):传输完成后,发送线发送一个或多个高电平作为停止位,表示数据的结束。接收线检测到高电平后,完成数据的接收。

UART的传输速率由波特率(Baud Rate)决定,表示每秒传输的比特数。波特率确定了每个比特的持续时间,从而影响了数据的传输速度。并且发送端和接收端的波特率必须一致,才能正确地接收和解析数据。否则,数据可能会被错误地解析或丢失。

奇偶校验

上面讲到的校验位就是使用奇偶校验方法对uart传输的数据进行校验,奇偶校验是一种在UART通信中常用的校验方式,用于检测数据位传输过程中的错误。它可以通过校验位来验证数据的正确性。

奇偶校验的实现方式如下:

1. 奇校验(Odd Parity):发送端在每个数据字节中已发送的数据位之后,追加一个校验位,使得整个数据字节中的1的数量(包括数据位和校验位)为奇数。例如,如果数据位中有偶数个1,发送端会在校验位中插入一个1,使得总数为奇数。

2. 偶校验(Even Parity):发送端在每个数据字节中已发送的数据位之后,追加一个校验位,使得整个数据字节中的1的数量(包括数据位和校验位)为偶数。例如,如果数据位中有奇数个1,发送端会在校验位中插入一个1,使得总数为偶数。

在接收端,接收器会对接收到的数据进行校验,计算数据位和校验位中1的数量,然后与校验方式进行比较。如果接收到的1的数量与校验方式不匹配,则认为数据出现错误。

奇偶校验的原理是通过增加一个校验位来帮助检测单个位错误的可能性。当接收到的数据位发生错误时,校验位的值将发生变化,接收端可以通过比较校验位与数据位的奇偶性来检测错误。

奇偶校验可以提高数据传输的可靠性,但它只能检测出一位的错误,并不能纠正错误。如果发生多位错误,奇偶校验无法检测到或纠正。因此,在实际应用中,通常需要结合其他更强大的错误检测和纠正机制来保证数据的可靠性。

stm32单片机上代码实现

HAL库开发

#include "stm32f4xx_hal.h" // 包含HAL库的头文件

UART_HandleTypeDef huart2; // UART句柄对象

void SystemClock_Config(void);

int main(void) {
  // 初始化HAL库
  HAL_Init();
  
  // 配置系统时钟
  SystemClock_Config();
  
  // 使能串口时钟
  __HAL_RCC_USART2_CLK_ENABLE();

  // 配置串口参数
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  HAL_UART_Init(&huart2);
  
  // 发送数据
  char txData[] = "Hello, World!";
  HAL_UART_Transmit(&huart2, (uint8_t*)txData, strlen(txData), HAL_MAX_DELAY);
  
  // 接收数据
  char rxData[50]; // 接收缓冲区
  HAL_UART_Receive(&huart2, (uint8_t*)rxData, sizeof(rxData), HAL_MAX_DELAY);
  
  while (1) {
    // 运行其他任务
  }
}

// 配置系统时钟
void SystemClock_Config(void) {

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 16;
  RCC_OscInitStruct.PLL.PLLN = 336;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}

上述代码使用了STM32的HAL库来简化UART通信的操作。首先,通过初始化HAL库和配置系统时钟来准备系统。然后,通过使能串口时钟、配置串口参数和初始化UART句柄对象来配置UART模块。接下来,可以使用`HAL_UART_Transmit()`函数发送数据,使用`HAL_UART_Receive()`函数接收数据。

标准库开发

#include "stm32f4xx.h"      // 包含STM32标准库的头文件

void USART2_Init(void);
void USART2_Write(char ch);
char USART2_Read(void);

int main(void) {
    USART2_Init();          // 初始化USART2
    
    // 发送数据
    USART2_Write('H');
    USART2_Write('e');
    USART2_Write('l');
    USART2_Write('l');
    USART2_Write('o');
    
    // 接收数据
    char received_data;
    while (1) {
        received_data = USART2_Read();
        // 处理接收到的数据
    }
}

// USART2初始化
void USART2_Init(void) {
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);         // 使能USART2时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);          // 使能GPIOA时钟
    
    // 配置USART2的引脚
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;        // PA2为USART2的TX引脚,PA3为USART2的RX引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                  // 复用功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                // 推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;             // GPIO速度为50MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                  // 上拉
    GPIO_Init(GPIOA, &GPIO_InitStructure);                        // 初始化GPIOA
    
    // 将引脚映射到USART2
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);     // 将PA2引脚映射到USART2的TX引脚
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);     // 将PA3引脚映射到USART2的RX引脚
    
    // 配置USART2的参数
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;                     // 波特率为9600
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;    // 数据位为8位
    USART_InitStructure.USART_StopBits = USART_StopBits_1;         // 停止位为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(USART2, &USART_InitStructure);                      // 初始化USART2
    
    USART_Cmd(USART2, ENABLE);                                     // 使能USART2
}

// 发送数据到USART2
void USART2_Write(char ch) {
    while (!(USART2->SR & USART_FLAG_TXE));    // 等待发送缓冲区为空
    USART2->DR = (ch & 0xFF);
}

// 从USART2接收数据
char USART2_Read(void) {
    while (!(USART2->SR & USART_FLAG_RXNE));   // 等待接收缓冲区有数据
    return (char)(USART2->DR & 0xFF);
}

上述代码通过调用相应的库函数和使用相关的寄存器配置来初始化USART2,并实现了通过USART2发送和接收数据的功能。

在嵌入式系统、通信设备、物联网等领域,UART被广泛使用于串口通信。许多微控制器和单片机芯片都集成了UART硬件模块,简化了串口通信的实现。文章来源地址https://www.toymoban.com/news/detail-767089.html

到了这里,关于【物联网】一文读懂UART通信协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 详解UART通信协议以及FPGA实现

      从《浅谈UART,TTL,RS-232,RS-485的区别》这篇文章,我们知道了UART是一种串行、异步、全双工的通信协议,属于协议层;传输过程一般采用RS-232,RS-485电平标准,将所需传输的数据一位接一位地传输;整体传输框架如下:   串口通信由发送端和接收端构成,两根信号线

    2024年04月28日
    浏览(39)
  • 嵌入式五大通信协议详解 (一) UART

    GUN C编译器拓展语法学习笔记(一)GNU C特殊语法部分详解 GUN C编译器拓展语法学习笔记(二)属性声明 GUN C编译器拓展语法学习笔记(三)内联函数、内建函数与可变参数宏 数组存储与指针学习笔记(一)数据类型与存储、数据对齐、数据移植、typedef   通用异步收发传输器

    2024年02月05日
    浏览(57)
  • 串行通信协议UART,IIC,SPI的对比分析

    常见串行通信有三个,即UART (Universal Asynchronous Receiver/Trasmitter,异步串行收发器),IIC,SPI。下面将分别介绍三种串行通信的过程。 UART是一种异步全双工串行通信协议。UART通信就是常说的串口通信。其数据传输方式为: 1.串口通信的信号线只需要两条线就可以完成,即发

    2024年02月13日
    浏览(35)
  • 串口通信协议--UART、RS-232、RS-485、RS-422

    近期学习了单片机及数电相关知识,故决定系统地学习一些通信协议。手边书本仅介绍了串口低速接口的相关协议。 串行通信 是指通过使用一条数据线(需要地线或控制线),将数据一位一位地一次传输,每一位数据占据一个固定的时间长度。 特点 :抗干扰,节省数据线,

    2024年02月05日
    浏览(63)
  • FPGA协议篇:UART通信及Verilog最易懂实现方式/通用于任何工程/带握手信号 ----UART_TX

            UART(Universal Asynchronous Receiver/Transmitter)是一种通用的 异步收发传输协议 ,用于在计算机系统和外部设备之间进行串行数据传输。UART 协议定义了数据的传输格式和通信规则,使得不同设备之间能够进行可靠的数据交换。 首先先把设计代码放到这里: UART_TX完整代

    2024年03月27日
    浏览(52)
  • 一文搞懂UART、RS232、RS485、TTL等常用的接口与协议

    PC机常用的按照接口数量细分为A型(15针),B型(25针),C型(37针),D型(50针),E型(9针)。其中,串行通信常用的是RS232——9针的DB9接口,显示器用的是VGA——15针的DB15接口。现在的笔记本电脑都已取消这种接口,一方面是因为这种接口比较笨重、逐渐被市场淘汰,另

    2024年02月01日
    浏览(46)
  • 物联网开发笔记(74)- 使用Micropython开发ESP32开发板之UART串口通信

    一、目的         这一节我们学习如何使用我们的ESP32开发板来进行串口通信,使用串口实现数据收发。 二、环境         ESP32 + USB转TTL线(3.3V) + Thonny IDE + 几根杜邦线 + Win10 接线方法:         ESP32和USB转TTL线都接在电脑USB口上,USB转TTL线的Tx接ESP32 P32,USB转TTL线

    2024年02月16日
    浏览(55)
  • 详解UART、I2C、SPI常用通信协议(全是细节)

            UART、I2C和SPI是我们在嵌入式开发中比较常见的通信协议了,没有最好的通信协议,每个通信协议都有自己的优缺点。如果想要通信速度快,SPI 将是理想的选择;如果用户想要连接多个设备而不是过于复杂,I2C 将是理想的选择,因为它最多可以连接 127 个设备并且易

    2024年02月15日
    浏览(41)
  • 串行通信协议(I2C、SPI、UART、SCCB、CAN)

    推荐一部书,在这本书里面介绍了I2C、SPI、UART和CAN等通信协议,写的蛮不错的。 串行通信 :设备与设备之间,传输数据按顺序依次1bit位接1bit位进行传输。 并行通信 :设备与设备之间,通过多条传输线,可以同时传输多个bit位的信号。 1.简单的双向两线制总线协议标准、半

    2024年02月14日
    浏览(65)
  • 匿名上位机V7.12协议编程(基于STM32F407+CubeMX+UART外设通信)

    本篇以STM32F407VET6主控为基础进行论述。 文章的目的在于记录和引导, 传递一些编写通信类功能会用到的基本思想 ,以及组合这些功能的思想。 匿名上位机V7版本的功能在本篇没有全部写出来,而是针对本上位机常用的功能举例来描述。 相信读者通过仔细阅读笔者的思想引

    2023年04月14日
    浏览(86)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包