【STM32嵌入式系统设计与开发—拓展】——1_11_1串口通信(USART)

这里写目录标题

  • 1、一般我们都怎么进行通信的?
  • (1)串行通行(Serial Communication)
  • (2)并行通信
  • (3)无线网络通信
  • (4)网络通信
  • (5)现场总线通信
  • 2、串口通信之间对比?
  • 3、通信类型有哪些?异步/同步/半双工/全双工又是什么?
  • 4、怎么理解在串口通信?
  • 5、使用的时候需要配置什么?
  • 推挽输出和复用推挽输出怎么选?
  • 为什么用浮空输入?
  • 串口定义的结构体?
  • 6、为什么能够printf();?
  • 一预处理、二定义、三个函数?
  • 半主机模式又是什么?
  • 1、一般我们都怎么进行通信的?

    (1)串行通行(Serial Communication)

    UART(Universal Asynchronous Receiver/Transmitter):实现方式:使用微控制器的UART模块,通过配置波特率、数据位、停止位和奇偶校验来进行通信。
    应用场景:微控制器之间的通信,调试信息输出等。

    SPI(Serial Peripheral Interface)
    实现方式:配置主设备和从设备的SPI模块,设置时钟极性、时钟相位和数据传输速率。
    应用场景:传感器、显示器、存储器等外设通信。

    I2C(Inter-Integrated Circuit)
    实现方式:配置I2C主从设备的地址,设置数据传输速率,并处理数据传输中的ACK/NACK信号。
    应用场景:短距离设备间通信,如EEPROM、传感器等。

    (2)并行通信

    并口(Parallel Port)
    实现方式:使用数据总线和控制信号线,传输多个数据位。通常在计算机和打印机等设备中使用。
    应用场景:早期计算机与打印机、扫描仪等外围设备通信。

    (3)无线网络通信

    Bluetooth
    实现方式:使用蓝牙模块(如HC-05、HM-10),进行配对和数据传输。
    应用场景:短距离无线通信,如无线耳机、键盘、鼠标等。

    Wi-Fi
    实现方式:使用Wi-Fi模块(如ESP8266、ESP32),配置SSID和密码,通过TCP/IP协议进行数据传输。

    Zigbee
    实现方式:使用Zigbee模块(如XBee),配置网络ID和通道,通过Zigbee协议进行数据传输。
    应用场景:低功耗无线通信,智能家居、传感器网络。

    (4)网络通信

    以太网(Ethernet)
    实现方式:使用以太网模块(如ENC28J60、W5500),配置IP地址、子网掩码和网关,通过TCP/IP协议进行数据传输。

    应用场景:有线局域网、工业自动化系统。
    光纤通信(Fiber Optic Communication)
    实现方式:使用光纤收发模块,通过光纤传输数据,适用于高速和长距离通信。
    应用场景:高速数据传输、远距离通信。

    (5)现场总线通信

    Modbus
    实现方式:使用Modbus协议库,通过串口、以太网等接口进行主从通信。
    应用场景:工业自动化和控制系统。

    Profibus
    实现方式:使用Profibus接口卡和协议栈,配置站地址和波特率。
    应用场景:工厂自动化和过程控制。

    2、串口通信之间对比?

    3、通信类型有哪些?异步/同步/半双工/全双工又是什么?

    4、怎么理解在串口通信?

    串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信
    单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,
    增强了单片机系统的硬件实力
    
    简单双向串口通信有两根通信线(发送端TX和接收端RX)
    TX与RX要交叉连接
    当只需单向的数据传输时,可以只接一根通信线
    当电平标准不一致时,需要加电平转换芯片
    

    5、使用的时候需要配置什么?

    波特率:串口通信的速率
    起始位:标志一个数据帧的开始,固定为低电平
    数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
    校验位:用于数据验证,根据数据位计算得来
    停止位:用于数据帧间隔,固定为高电平


    /*********************************************************************
     @Function  : USART1初始化
     @Parameter : bound : 波特率 
     @Return    : N/A
    **********************************************************************/   	
    void usart1_init(uint32_t bound)
    {	
    	GPIO_InitTypeDef GPIO_InitStructure; // 定义一个 GPIO 初始化结构体
    	USART_InitTypeDef USART_InitStructure; // 定义一个 USART 初始化结构体
    	
      /*时钟使能*/
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 使能 USART1 和 GPIOA 的时钟
    	
    	/*引脚复用*/  //PA9->TXD 
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;         // 配置 GPIOA 的引脚 9 为 USART1 的 TX 引脚
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 设置引脚速度为 50 MHz
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   // 设置引脚模式为复用推挽输出
    	GPIO_Init(GPIOA, &GPIO_InitStructure);            // 初始化 GPIOA 引脚 9
    	
    	/*引脚复用*/  //PA10->RXD
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;            // 配置 GPIOA 的引脚 10 为 USART1 的 RX 引脚
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 设置引脚模式为浮空输入
    	GPIO_Init(GPIOA, &GPIO_InitStructure);                // 初始化 GPIOA 引脚 10 
    	
      /*USART设置*/
    	USART_InitStructure.USART_BaudRate = bound;                 // 设置 USART 波特率
    	USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 设置 USART 字长为 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 模式为接收和发送模式
      USART_Init(USART1, &USART_InitStructure);                         // 初始化 USART1
    	
      USART_Cmd(USART1, ENABLE);                                       // 使能 USART1                  
    }
    

    推挽输出和复用推挽输出怎么选?

    复用推挽输出用于当一个 GPIO 引脚需要执行特定外设功能(如串口通信的发送引脚)时,使引脚能够在高低电平之间切换并与外设模块共享;在 USART 通信中,TX 引脚配置为复用推挽输出是因为它需要由串口模块驱动以发送数据,实现串口通信功能

    推挽输出(Push-Pull Output):用于简单的数字输出,比如控制一个 LED 的亮灭。它只是在高电平和低电平之间切换。

    复用推挽输出(Alternate Function Push-Pull Output):用于引脚需要执行特定功能(比如串口通信)的情况。除了在高低电平之间切换,还能和外设模块(比如串口、I2C、SPI)共享,引脚不再只是普通的输入输出,而是用来传输数据。

    为什么用浮空输入?

    浮空输入的优势包括:
    可以检测到微弱的信号:由于浮空输入的端口阻抗很大,类似于电压表内阻很大的情况,这样可以更灵敏地检测到外部信号的变化。
    适用于多种标准通讯协议:例如 IIC、USART 等总线设备,在这些应用中,浮空输入有助于保证数据传输的准确性和稳定性。

    串口定义的结构体?

    /**
    @brief USART 初始化结构体定义
    */
    typedef struct
    {
    uint32_t USART_BaudRate; /* 此成员配置 USART 通信波特率。 */
    
    uint16_t USART_StopBits; /* 指定传输的停止位数量。*/
    */
    uint16_t USART_Parity; /*!< 指定奇偶校验模式。 */
    uint16_t USART_Mode; /* 指定接收或发送模式是启用还是禁用。 */
    uint16_t USART_HardwareFlowControl; /* 指定硬件流控制模式是启用还是禁用。*/
    } USART_InitTypeDef;
    

    6、为什么能够printf();?

    将printf重定向到USART1(串口1)–这样我们就能通过串口1将信息打印到上位机(串口助手)

    //加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
    #if 1
    #pragma import(__use_no_semihosting)             
    /*********************************************************************
     @Function  : 标准库需要的支持函数 
     @Parameter : N/A
     @Return    : N/A
    **********************************************************************/              
    struct __FILE 
    { 
    	int handle; 
    }; 
    
    FILE __stdout;   
    
    /*********************************************************************
     @Function  : 定义_sys_exit()以避免使用半主机模式
     @Parameter : X :
     @Return    : N/A
    **********************************************************************/   
    void _sys_exit(int x) 
    { 
    	x = x; 
    } 
    
    /*********************************************************************
     @Function  : 重定义fputc函数
     @Parameter : ch :入口数据
    							 f :入口指针
     @Return    : ch :入口数据
    **********************************************************************/
    int fputc(int ch, FILE *f)
    {      
    	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
        USART1->DR = (u8) ch;      
    	return ch;
    }
    #endif 
    

    一预处理、二定义、三个函数?


    1预、#pragmaimport(__use_no_semihosting),确保不从C库中使用半主机函数
    2定、定义:__FILE结构体,避免HAL库某些情况下报错
    定义: FILE_stdout,避免编译报错实现
    3函数、_sys_exit和fputc(int ch, FILE *f)等三个函数


    A[开始] --> B{是否调用 printf 函数}
    B -->|是| C[进入 fputc 函数]
    C --> D{串口是否发送完毕}
    D -->|否| C
    D -->|是| E[返回 printf 函数]
    E --> F[继续程序执行]
    B -->|否| F
    graph TD
    A[开始] --> B{是否调用 printf 函数}
    B -->|是| C[进入 fputc 函数]
    C --> D{串口是否发送完毕}
    D -->|否| C
    D -->|是| E[返回 printf 函数]
    E --> F[继续程序执行]
    B -->|否| F
    

    半主机模式又是什么?

    半主机模式就是在开发ARM单片机程序的时候,让程序能借用电脑(就是开发用的那台电脑)的屏幕来显示输出内容,比如用printf函数输出的东西能在电脑屏幕上看到,还能通过电脑的键盘给程序输入内容。
    但真正把程序放到嵌入式设备里运行的时候,设备可没法直接用电脑的这些输入输出功能了,所以就得把这个模式关掉。不然程序可能会因为找不到电脑的帮忙而出问题。

    半主机模式就好比是在开发单片机程序时,开了个“后门”,能让程序把要输出的东西,比如像用printf输出的那些文字,都发到我们用来开发的电脑屏幕上显示,也能通过电脑键盘给程序输入东西。
    可等程序真正装到单片机里运行的时候,单片机可没法跟开发用的电脑连着了,这时候要是还开着这个“后门”,程序就会找不到地方去显示输出或者接收输入,就会乱套。所以得把这个模式关掉

    作者:iot鑫鹏

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【STM32嵌入式系统设计与开发—拓展】——1_11_1串口通信(USART)

    发表回复