STM32 通用同步/异步通信

目录

一、串行通信简介

1.串行通信

2.串行异步通信和串行同步通信

3.串行异步通信的数据传输形式

二、STM32的USART

1.USART的特点

2.USART的结构

3.USART的使用方式

 三、USART的使用流程


一、串行通信简介

        CPU与外围设备之间的信息交换称为通信。基本的通信方式有并行通信串行通信两种。STM32单片机提供了功能强大的串行通信模块,即通用同步/异步收发器USART)。

1.串行通信

        串行通信是数据字节一位一位地依次传送的通信方式。串行通信的速度慢,但占用的传输线条数少,适用于远距离的数据传送。

        从硬件上看,串行通信有单工半双工全双工通信

  • 单工通信就是数据只允许向一个方向进行传送。
  • 半双工通信就是数据允许向两个方向进行传送,但一个设备的传送和接收过程不能同时进行。
  • 全双工通信就是数据允许向两个方向进行传送,且一个设备的传送和接收过程可以同时进行。
  • 2.串行异步、同步通信

             串行通信按照串行数据的时钟控制方式分为异步通信和同步通信。

            串行异步通信是一种常用的串行通信方式,一次通信传送一个字符帧。在发送字符时,发送的字符之间的时间间隔可以是任意的,接收端时刻做好接受的准备。串行异步通信的优点是通信设备简单价格低廉,但因为具有起始位和停止位,所以传输效率较低。串行异步通信只适用于点对点

            串行同步通信要求在进行通信前先建立同步,发送频率和接收方的接收频率要同步。串行同步通信的传输速度较快,可用于点对多,多用于同一PCB上芯片级之间的通信。缺点是需要使用专用的时钟控制线来实现同步。

    3.串行异步通信的数据传输形式

            串行异步通信需要制定一些共同遵守的约定,其中最重要的是字长波特率

            字长可以是8位或者9位,起始位为低电平,停止位为高电平,空闲帧全为1,断开帧全为0。发送和接收由一个共用的波特率发生器驱动。

            波特率即数据的传送速率。在串行异步通信中,每秒钟传送的二进制数的位数称为波特率,单位是比特/秒(bit/s),或波特(baud)。波特率的倒数就是每一位的传送时间,称为位传送时间,单位为秒(s)。

            

    二、STM32的USART

    1.USART的特点

  • 同步/异步全双工通信,低位先行
  • 可选的数据位长度(8位/9位)。
  • 可选的停止位长度(0.5位/1位/1.5位/2位)。
  • 可选的校验位(无校验/奇校验/偶校验)。
  • 可选的波特率
  • 支持硬件流控制。 
  • 2.USART的结构

            STM32有3~5个全双工的串行异步通信接口USART,简称串口。USART主要有发送引脚(RX)、接收引脚(TX)、清除发送(nCTS)、发送请求(nRTS)和发送器时钟输出(CK)等引脚来与外部设备相连,同时,其内部还包含了各种寄存器和功能模块等。

            常用的引脚有RX发送引脚TX接收引脚,使用这两个引脚,一般就可以实现双向通信。

     3.USART的硬件连接方式

            

     三、USART的使用流程

            STM32的USART一般使用异步通信方式,使用流程如下:

    1. 配置GPIO
    2. 配置USART
    3. 配置NVIC
    4. 编写中断服务函数(用于接收数据和进行其他操作)
    5. 发送数据
    6. 配置printf重定向(按需要选择配置或者不配置)
    #include "stm32f10x.h"                  // Device header
    
    
    /**********************************初始化USART1***********************************/
    void Serial1_Init(void)
    {
    	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA |RCC_APB2Periph_USART1,ENABLE );
        //开启GPIO和USART1时钟
    	
    
    
    	GPIO_InitTypeDef GPIO_InitStructure;
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;         //复用推挽输出
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;                //USART1的发送引脚是PA9
    	GPIO_Init(GPIOA,&GPIO_InitStructure);                 
    	
    	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;           //上拉输入
    	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;        
    	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;               //USART1的接收引脚是PA10
    	GPIO_Init(GPIOA,&GPIO_InitStructure);                      
    	
    
    
    	USART_InitTypeDef USART_InitStructure;
    	USART_InitStructure.USART_BaudRate=9600;                     //波特率,选择9600
    	USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx ; //配置为发送和接收模式
    	USART_InitStructure.USART_Parity=USART_Parity_No;            //校验位,不使用
    	USART_InitStructure.USART_StopBits=USART_StopBits_1;         //停止位,设长度1位
    	USART_InitStructure.USART_WordLength=USART_WordLength_8b;    //数据位,设长度8位
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
                                                                     //硬件流控制,不使用
    	USART_Init(USART1 ,&USART_InitStructure);           
    	
    
    	USART_ITConfig (USART1 ,USART_IT_RXNE ,ENABLE);               //开启USART1的接收中断
    	
    
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);               //选择优先级分组2
    	
    
    	NVIC_InitTypeDef NVIC_InitStructure;                          //使用到中断都要配置NVIC
    	NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;               //选择USART1通道
    	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE ;                //使能
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;       //抢占优先级设1
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;              //响应优先级设1
    	NVIC_Init(&NVIC_InitStructure);                         
    	
    	USART_Cmd (USART1,ENABLE );                                   //使能USART1                            
    }
    
    
    /*********************************USART1中断服务函数*********************************/
    void USART1_IRQHandler(void)                                      
    {
    	 
    	if(USART_GetITStatus (USART1,USART_IT_RXNE )==SET)  
    	{
            uint8_t value = 0;
    		value=USART_ReceiveData (USART1);                         //接收数据       
    		 
    		 
            //其他操作,如处理接收到的数据
    
    
    		USART_ClearITPendingBit (USART1,USART_IT_RXNE );
    	}
    }
    
    
    /*************************************发送数据***************************************/
        USART_SendData(USART1, Byte);	                          	   //发送数据
    	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  //等待发送完成
    
    
    /*************************************printf重定向***********************************/
    int fputc(int ch,FILE *f)          
    {
    	USART_SendData(USART1, ch);	                          	       //发送数据
    	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);  //等待发送完成
    	return ch;
    }
    //printf重定向到串口,需要在该文件#include <stdio.h>,作用是使用printf操作将数据打印到串口

    作者:鱼与仙人掌

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 通用同步/异步通信

    发表回复