串口_串口通信 - CSDN
串口 订阅
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。 展开全文
串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口 (Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。
信息
别    称
通常指COM接口
简    称
串口
中文名
串行接口
外文名
Serial Interface
串行接口定义
串行接口 (Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。串行通讯的特点是:数据位的传送,按位顺序进行,最少只需一根传输线即可完成;成本低但传送速度慢。串行通讯的距离可以从几米到几千米;根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。
收起全文
精华内容
参与话题
  • 串口通信的基本知识

    万次阅读 多人点赞 2018-11-12 20:45:38
    串口通信的基本知识 本文介绍了串口通讯的基本概念、数据格式、通讯方式、典型的串口通讯标准等内容。 串口通讯,RS232,RS485,停止位,奇校验,偶校验 1 串口通讯  串口通讯(Serial Communication),是指外设和...

    串口通信的基本知识

    本文介绍了串口通讯的基本概念、数据格式、通讯方式、典型的串口通讯标准等内容。

    串口通讯,RS232,RS485,停止位,奇校验,偶校验

    1 串口通讯
        串口通讯(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进行传输数据的一种通讯方式。
        串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议。


    2 串口通讯的数据格式


        一个字符一个字符地传输,每个字符一位一位地传输,并且传输一个字符时,总是以“起始位”开始,以“停止位”结束,字符之间没有固定的时间间隔要求。
        每一个字符的前面都有一位起始位(低电平),字符本身由7位数据位组成,接着字符后面是一位校验位(检验位可以是奇校验、偶校验或无校验位),最后是一位或一位半或二位停止位,停止位后面是不定长的空闲位,停止位和空闲位都规定为高电平。实际传输时每一位的信号宽度与波特率有关,波特率越高,宽度越小,在进行传输之前,双方一定要使用同一个波特率设置。

    3 通讯方式
        单工模式(Simplex Communication)的数据传输是单向的。通信双方中,一方固定为发送端,一方则固定为接收端。信息只能沿一个方向传输,使用一根传输线。
    半双工模式(Half Duplex)通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。数据传输允许数据在两个方向上传输,但是,在任何时刻只能由其中的一方发送数据,另一方接收数据。因此半双工模式既可以使用一条数据线,也可以使用两条数据线。半双工通信中每端需有一个收发切换电子开关,通过切换来决定数据向哪个方向传输。因为有切换,所以会产生时间延迟,信息传输效率低些。
        全双工模式(Full Duplex)通信允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。在全双工模式中,每一端都有发送器和接收器,有两条传输线,信息传输效率高。
        显然,在其它参数都一样的情况下,全双工比半双工传输速度要快,效率要高。

    4 偶校验与奇校验
        在标准ASCII码中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。

    5 停止位
        停止位是按长度来算的。串行异步通信从计时开始,以单位时间为间隔(一个单位时间就是波特率的倒数),依次接受所规定的数据位和奇偶校验位,并拼装成一个字符的并行字节;此后应接收到规定长度的停止位“1”。所以说,停止位都是“1”,1.5是它的长度,即停止位的高电平保持1.5个单位时间长度。一般来讲,停止位有1,1.5,2个单位时间三种长度。

    6 波特率
        波特率就是每秒钟传输的数据位数。
        波特率的单位是每秒比特数(bps),常用的单位还有:每秒千比特数Kbps,每秒兆比特数Mbps。串口典型的传输波特率600bps,1200bps,2400bps,4800bps,9600bps,19200bps,38400bps。
        PLC/PC与称重仪表通讯时,最常用的波特率是9600bps,19200bps。PLC/PC或仪表与大屏幕通讯时,最常用的波特率是600bps。

    7 典型的串口通讯标准
        EIA RS232(通常简称“RS232”): 1962年由美国电子工业协会(EIA)制定。
        EIA RS485(通常简称“RS485”): 1983年由美国电子工业协会(EIA)制定。

    8 RS232串口
        RS232是计算机与通信工业应用中最广泛一种串行接口。它以全双工方式工作,需要地线、发送线和接收线三条线。RS232只能实现点对点的通信方式。
    8.1 RS232串口缺点
        ●接口信号电平值较高,接口电路芯片容易损坏。
        ●传输速率低,最高波特率19200bps。
        ●抗干扰能力较差。
        ●传输距离有限,一般在15m以内。
        ●只能实现点对点的通讯方式。
    8.2 RS232串口接口定义
        RXD:接收数据,TXD:发送数据,GND/SG:信号地。
    8.3 电脑DB9针接口定义
        电脑DB9针接口是常见的RS232串口,其引脚定义如下:
        2号脚:RXD(接收数据)
        3号脚:TXD(发送数据)
        5号脚:SG或GND(信号地)
        其它脚:我们不用

        

        电脑RS232串口与仪表串口连接图:
     
        

    9 RS485串口
    9.1 RS485串口特点
        ●RS485采用平衡发送和差分接收,具有良好的抗干扰能力,信号能传输上千米。
        ●RS485有两线制和四线制两种接线。采用四线制时,只能实现点对多的通讯(即只能有一个主设备,其余为从设备)。四线制现在很少采用,现在多采用两线制接线方式。
        ●两线制RS485只能以半双式方式工作,收发不能同时进行。
        ●RS485在同一总线上最多可以接32个结点,可实现真正的多点通讯,但一般采用的是主从通信方式,即一个主机带多个从机。
        ●因RS485接口具有良好的抗干扰能力,长的传输距离和多站能力等优点使其成为首选的串行接口。
    9.2 485抑制共模干扰示意图
        
    9.3 RS485串口接口定义
        A或Data+(D+)或+:信号正;
        B或Data-(D-)或-:信号负。
    9.4 计算机与RS485仪表通讯
        计算机自带的串口只有RS232,没有RS485,如果计算机要与RS485串口的仪表进行通讯,必须使用串口转换器或装上RS485串口转换卡后才能进行通讯。
    9.5 RS485串口的终端电阻
        ●一般情况下不需要增加终端电阻,只有在RS485通信距离超过100米的情况下,要在RS485通讯的开始端和结束端增加终端电阻,RS485典型终端电阻是120欧。
        ●终端电阻是为了消除在通信电缆中的信号反射在通信过程中,有两种信号因导致信号反射:阻抗不连续和阻抗不匹配。
        阻抗不连续,信号在传输线末端突然遇到电缆阻抗很小甚至没有,信号在这个地方就会引起反射。消除这种反射的方法,就必须在电缆的末端跨接一个与电缆的特性阻抗同样大小的终端电阻,使电缆的阻抗连续。由于信号在电缆上的传输是双向的,因此,在通讯电缆的另一端可跨接一个同样大小的终端电阻。
        引起信号反射的另一原因是数据收发器与传输电缆之间的阻抗不匹配。这种原因引起的反射,主要表现在通讯线路处在空闲方式时,整个网络数据混乱。要减弱反射信号对通讯线路的影响,通常采用噪声抑制和加偏置电阻的方法。在实际应用中,对于比较小的反射信号,为简单方便,经常采用加偏置电阻的方法。

    10 串口通讯硬件常见的注意事项
        ●通讯电缆端子一定接牢,不可有任何松动,否则,可能会烧坏仪表或上位机的通讯板。
        ●不可带电拔插通讯端子,否则,可能会烧坏仪表或上位机的通讯板,一定要关闭仪表电源后才能去拔插通讯端子或接通讯线。
        ●通讯用的屏蔽电缆最好选用双层隔离型屏蔽电缆,其次选用单层屏蔽电缆,最好不要选用无屏蔽层的电缆,且电缆屏蔽层一定要能完全屏蔽,有些质量差的电缆,屏蔽层很松散,根本起不到屏蔽的作用。单层屏蔽的电缆屏蔽层应一端接地,双层屏蔽的电缆屏蔽层其外层(含铠装)应两端接地,内层屏蔽则应一端接地。
        ●仪表使用RS232通讯时,通讯电缆长度不得超过15米。
        ●一般RS485协议的接头没有固定的标准,可能根据厂家的不同引脚顺序和管脚功能可能不尽相同,用户可以查阅相关产品RS485的引脚图。
        ●RS485通讯电缆最好选用阻阬匹配、低衰减的RS485专用通讯电缆(双绞线),不要使用普通的双绞电缆或质量较差的通讯电缆。因为普通电缆或质量差的通讯电缆,可能阻抗不匹配、衰减大、绞合度不够、屏蔽层太松散,这样会导致干扰将非常大,会造成通讯不畅,甚至通讯不上。
        ●仪表使用RS485通讯时,每台仪表必须手牵手地串下去,不可以有星型连接或者分叉,如果有星型连接或者分叉,干扰将非常大,会造成通讯不畅,甚至通讯不上。

        

        ●485总线结构理论上传输距离达到1200米,一般是指通讯线材优质达标,波特率9600,只有一台485设备才能使得通讯距离达到1200米,而且能通讯并不代表每次通讯都正常,所以通常485总线实际的稳定通讯距离远远达不到1200米。负载485设备多,线材阻抗不同时,通讯距离更短。
        ●仪表使用RS485通讯时,必要时,请接入终端电阻,以增强系统的抗干扰性,典型的终端电阻阻值是120欧。

    11 串口通讯软件设置要点
    11.1 有关通讯的一些基本概念
        ●主机与从机:在通讯系统中起主要作用、发布主要命令的称为主机,接受命令的称为从机。
        ●连续方式:指主机不需要发布命令,从机就能自动地向主机发送数据。
        ●指令方式:指主机向从机发布命令,从机根据指令执行动作,并将结果“应答”给主机的模式。
        ●输出数据类型:指在连续方式通讯时,从机输出给主机的数据类型。
        ●通讯协议:指主机与从机通讯时,按哪一种编码规则来通讯。
        ●波特率:主从机之间通讯的速度。
        ●数据位:每次传输数据时,数据由几位组成。
        ●校验位:数据传输错误检测,可以是奇校验、偶校验或无校验。
        ●地址:每一台从机的编号。
    11.2 主从机之间通讯设置要点
        ●要点一:主/从RS232/485硬件有无设置正确,通讯线有无接对。有些通讯板卡是RS422与RS485共用的,依靠板上跳线来实现的,有些仪表RS232/485也需要通讯跳线来实现。
        ●要点二:主机上的通讯端口有无设置正确;超时(一般设置为2s)、通讯延时(一般设置为5~20ms)、ACK信号延时(一般设置为0ms)有无设置正确。
        ●要点三:主/从机通讯协议有无选择正确。
        ●要点四:主/从机波特率有无选择正确。
        ●要点五:主/从机数据位有无选择正确。数据位可以选择7位,8位。
        ●要点六:主/从机校验位有无选择正确。校验位一般可选择偶校验、奇校验、无校验。
        ●要点七:主/从机停止位有无选择正确。停止位可以选择1位、1.5位还是2位。
        ●要点八:从机地址有无选择正确。
        ●要点九:主/从机的通讯方式有无选择正确。

     

    进行通讯测试的时候经常会进行线路测试,测试所用的串口线是否可用,方法有二如下:

     

    1  把串口线接到不同的串口,用串口调试工具从一个串口发数据,另一个能正常收到说明串口线是OK的。

    2  把串口线的一端短接(用金属把2,3号脚连通),用万用表测另一端的2,3号如果正常的话会有嘀嘀的短接报警声。

     

    展开全文
  • 7.串口(UART)

    千次阅读 2018-12-29 17:36:30
    1.什么是串口? 2.通信接口基础知识 3.使用串口需要注意的东西?  4.串口如何和电脑进行通信 5.编写程序思路 6.编写程序   1.什么是串口? UART(Universal Asynchronous Receiver Transmitter:通用...

    目录

    1.什么是串口?

    2.通信接口基础知识

    3.使用串口需要注意的东西?

     4.串口如何和电脑进行通信

    5.编写程序思路

    6.编写程序


     

    1.什么是串口?

    UART(Universal Asynchronous Receiver Transmitter:通用异步收发器), 一对一,以位为单位发送。

    •  串口通讯

        串口通讯(Serial Communication),是指外设和计算机间,通过数据信号线、地线等,按位进行传输数据的一种通讯方式。
        串口是一种接口标准,它规定了接口的电气标准,没有规定接口插件电缆以及使用的协议。

    2.通信接口基础知识

    2.1处理器与外部有线通信的两种方式

    • 并行通信  

       -传输原理:数据各个位同时传输。

       -优点:速度快    

       -缺点:占用引脚资源多

    • 串行通信  

      -传输原理:数据按位顺序传输。  

      -优点:占用引脚资源少  

      -缺点:速度相对较慢

    2.2串行通信分类(按照通信方向)

    • 单工: 数据传输只支持数据在一个方向上传输
    • 半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;
    • 全双工: 允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。

    2.3串行通信的通信方式

    • 同步通信:带时钟同步信号传输。    例如: -SPI,IIC通信接口
    • 异步通信:不带时钟同步信号。        例如: -UART(通用异步收发器),单总线(DS18B20温度传感器)

    一些常见的串口通信接口:

     

    补充几个重要的名词:

    • 波特率

    波特率就是每秒钟传输的数据位数。
    波特率的单位是每秒比特数(bps),常用的单位还有:每秒千比特数Kbps,每秒兆比特数Mbps。
        

      

    3.使用串口需要注意的东西?

    ①   物理层(电气层:接口决定):       通信接口(RS232,RS485,RS422,TTL)

    通信两端的接口类型必须匹配,否则无法进行通信,比如单片机和单片机直接,他们的电平全部是TTL电平,可以进行通信,但是电脑和单片机直接,前者是RS232电平,所以没有办法直接通信,需要进行电平的转换,才能进行通信,如下:

    情况一:单片机和单片机直接,都是使用TTL电平可以直接通信

    情况二:单片机和PC直接,需要进行电平转换

     常见电器接口电平标准

     

    ②   数据格式(数据层:芯片决定)

    ③   通信协议(协议层:程序决定)

    •  起始位:1个逻辑0数据位开始
    •  数据位(8位或者9位)
    •  奇偶校验位(第9位)
    •  停止位(1,1.5,2位)
    •  波特率设置

    例子:


     4.串口如何和电脑进行通信

    简图如下:

    补充:

    假设波特率为:115200,8位数据位,无校验位,一个停止位,一个开始位(共10位)简写:115200,8n1

    则传输一位的时间是:t = 1/115200 (s)  ,而传输一个字节需要10位;

    那么传输一个字节的时间是: t(1byte) =  10/115200 (s) 

    则一秒能传输的字节数是: 1/t  = 115200/10  = 11520 byte


    5.编写程序思路

    软件的设计大概可以分为这几步:

    1).设置IO的模式为串口模式

    查看原理图,可以看到GPH3/4 分别是串口0的 RXD和TXD

    查看S3C2400的芯片手册对上面两个引脚的定义:

    设置引脚为串口功能:

     

     设置引脚上拉:

    2).设置波特率

    • 查看数据手册,如何设置波特率:

    此时设置Pclk = 50MHz,设置波特率为:115200,那么 UBRDIVn = ?

    由公式:UBRDIVn = (int)( UART clock / ( buad rate x 16) ) –1

    则:UBRDIVn = (int)( 50000000 / ( 115200 x 16) ) –1  = 26

    • 使用哪个寄存器设置时钟来源?

    这些寄存器的内容是什么?

    此处时钟源为:50Mhz 

    在程序中使能串口的发送和接收功能: 设置为:0b01

    那么设置这个寄存器的值为:0x00000005 

    • 设置波特率,寄存器描述:

    设置波特率为:115200,设置UBRDIV的值为26 

    3).设置数据格式

    •  寄存器描述:

    即:往寄存器ULCON0写入值:0x00000003

    4).如何发送和接收数据

    • 发送:直接把内存的数据写入对应的buffer里面(写寄存器)

    • 接收:从buffer里面读取数据(读寄存器)

    5).发送和接收标志位

    • 发送:

    当发送数据,检测到UTRSTAT0的 第2为1,说明可以发送数据了,就可以往UTXH0寄存器里面写入一个字节的数据 

    • 接收:

    当接收数据,检测到UTRSTAT0的 第0为1,说明可以接收数据了,就可以读取URXH0寄存器里面一个字节的数据 


    6.编写程序:

    6.1.串口初始化函数

    按照上边的编程思路写一个串口初始化函数,如下:

    其中还包含三个函数:

    1、putchar()  //发送一个字节数据

    2、getchar()  //接收几个字节数据

    3、putSring() //发送字符串

    #include "s3c2440_soc.h"
    
    
    void uart0_init(void)
    {
    	/*IO引脚设置*/
    	/*GPH2/3 设置为Txd0,Rxd0*/
    	GPHCON &= ~((3<<4)|(3<<6));  //先对位进行清零
    	GPHCON |=  ((2<<4)|(2<<6));  //设置GPHCON[8:4]=0b1010
    	/*设置上拉功能,设置GPHUP[3:2]=0b00*/
    	GPHUP  &= ~((1<<2)|(1<<3));
    	/*设置波特率*/
    	/*======================================
    	 *1.设置 UCON0  寄存器设置 串口0的时钟源是 PLCK
    	 *2.使能串口的发送和接收,设置为中断或者查询模式*/
    	UCON0  = 0x00000005; 
    	UBRDIV0=26;  //设置波特率为:115200
    	/*设置数据格式:一位起始位,8位数据位,1位停止位,无校验位*/
    	ULCON0 = 0X00000003;
    	
    
    }
    
    /*发送一个字节的数据*/
    int putchar(int c)
    {
    	while(!(UTRSTAT0 & (1<<2)));
    	UTXH0 = (unsigned char)c;
    }
    /*读取一个字节的数据*/
    int getchar(void)
    {
    	while(!(UTRSTAT0 & (1<<0)));
    	return URXH0;
    }
    /*发送一个字符串*/
    int putString(const char *s)
    {
    	while(*s)
    	{
    		putchar(*s);
    		s++;
    	}
    	
    }

    6.2.编写启动文件 start.S

    1.设置堆栈指针sp

    2.设置系统时钟

    3.设置函数从main函数开始执行

    
    
    
    .text
    .global _start
    
    _start:
        /*关闭看门狗*/
    	ldr r0 ,=0x53000000
    	ldr r1 ,=0
    	str r1 ,[r0]
    	/*设置MPLL=400Mhz*/
    	/*LOCKTIME(0x4C000000) = 0xFFFFFFFF*/
    	ldr r0 ,=0x4C000000
    	ldr r1 ,=0xFFFFFFFF
    	str r1 ,[r0]
    	/*设置CLKDIVN(0x4C000014)=0x5*/
    	ldr r0, =0x4C000014
    	ldr r1, =0x5
    	str r1, [r0]
    	/*使CPU总线工作与异步模式*/
    	mrc p15,0,r0,c1,c0,0
    	orr r0,r0,#0xc0000000
    	mcr p15,0,r0,c1,c0,0
    	/*往寄存器MPLLCON(0x4C000004)?的MPLLCON[19:12]=92(0x5c) ,MPLLCON[9:4]=1,MPLLCON[1:0]=1.*/
    	ldr r0, =0x4C000004
    	ldr r1, =(0x5c<<12)|(1<<4)|(1<<0)
    	str r1, [r0]
    
    	/*设置内存:sp       栈*/
        /*自动分辨是nand/nor启动方式*/
    	/*思路:因为nand是支持直接读取的,不需要什么
    	  格式,而nor可以任意写,但是读取需要特定的
    	  格式,若一开始往0地址写入一个值,然后读出来
    	  如果读取的值和写入的值是一致的,说明是nand启动
    	  否则是nor启动*/
    	  mov r1 ,#0    //r1赋值为0
    	  ldr r0 ,[r1]  //读取0地址的值,以便后面恢复
    	  str r1 ,[r1]  //把0写入0地址里面
    	  ldr r2 ,[r1]  //从0地址读取值到r2
    	  cmp r1 ,r2    //判断r1和r2是否相等,相等为nand启动
    	  ldr sp ,=0x40000000+4096  //假设为nor启动
    	  moveq sp, #4096 //相当为nand启动,重新设置sp
    	  streq r0,[r1]   //恢复nand中0地址的值
    
    
    	  bl main
    halt:
    	b halt
    

    6.3编写主函数 main.c

    1.调用串口初始化函数

    2.调用串口函数进行数据的发送和接收

    #include "s3c2440_soc.h"
    #include "uart.h"
    
    
    int main()
    {
    	unsigned char c;
    	uart0_init();
    	putString(
    "Hello world!\r\n");
    	while(1)
    	{
    		c =getchar();
    		if(c== '\r')
    		{
    			putString("\n");
    		}
    		putchar(c);
    
    	}
    	return 0;
    
    
    }

    6.4.编写Makefile文件,对以上文件进行编译

    内容如下:

    all:
    	arm-linux-gcc -c -o led.o led.c
    	arm-linux-gcc -c -o uart.o uart.c
    	arm-linux-gcc -c -o main.o main.c
    	arm-linux-gcc -c -o start.o start.S
    	arm-linux-ld -Ttext 0 start.o led.o uart.o main.o -o uart.elf
    	arm-linux-objcopy -O binary -S uart.elf uart.bin	
    	arm-linux-objdump -D uart.elf > uart.dis
    
    clean:
    	rm *.bin *.o *.elf *.dis

    6.5.上传到Linux系统进行编译

    在Linux上使用make命令:

    6.6传回window系统,使用oflash进行烧录,使用串口调试助手

    • 设置通信协议,和程序中的一致

    • 开启串口

    系统复位,输出 Hello world !   回车进入下一行

    从键盘输入字母,ARM芯片收到后,发送回去给电脑,并打印输出在屏幕上

    这样一个简单的串口实验就玩成了。


    代码:https://download.csdn.net/download/qq_36243942/10886092

    展开全文
  • 串口、COM口、UART口, TTL、RS-232、RS-485区别详解

    万次阅读 多人点赞 2018-10-29 12:26:53
    调试时总是会遇到各种各样的接口,各种各样的转换板,...串口串口是一个泛称,UART、TTL、RS232、RS485都遵循类似的通信时序协议,因此都被通称为串口。 UART接口:通用异步收发器(Universal Asynchronous ...

    调试时总是会遇到各种各样的接口,各种各样的转换板,似懂非懂的感觉很不爽!

    首先,串口、UART口、COM口、USB口是指的物理接口形式(硬件)。而TTL、RS-232、RS-485是指的电平标准(电信号)。

    串口:串口是一个泛称,UART、TTL、RS232、RS485都遵循类似的通信时序协议,因此都被通称为串口。

    UART接口:通用异步收发器(Universal Asynchronous Receiver/Transmitter),UART是串口收发的逻辑电路,这部分可以独立成芯片,也可以作为模块嵌入到其他芯片里,单片机、SOC、PC里都会有UART模块。

    COM口:特指台式计算机或一些电子设备上的D-SUB外形(一种连接器结构,VGA接口的连接器也是D-SUB)的串行通信口,应用了串口通信时序和RS232的逻辑电平。

    USB口:通用串行总线,和串口完全是两个概念。虽然也是串行方式通信,但由于USB的通信时序和信号电平都和串口完全不同,因此和串口没有任何关系。USB是高速的通信接口,用于PC连接各种外设,U盘、键鼠、移动硬盘、当然也包括“USB转串口”的模块。(USB转串口模块,就是USB接口的UART模块)

     

    TTL,RS232,RS485都是一种逻辑电平的表示方式

    TTL:TTL指双极型三极管逻辑电路,市面上很多“USB转TTL”模块,实际上是“USB转TTL电平的串口”模块。这种信号0对应0V,1对应3.3V或者5V。与单片机、SOC的IO电平兼容。不过实际也不一定是TTL电平,因为现在大部分数字逻辑都是CMOS工艺做的,只是沿用了TTL的说法。我们进行串口通信的时候 从单片机直接出来的基本是都 是 TTL 电平。  

    TTL电平:全双工(逻辑1: 2.4V--5V   逻辑0: 0V--0.5V)

    1、硬件框图如下,TTL用于两个MCU间通信

    2、‘0’和‘1’表示

    RS232:是电子工业协会(Electronic Industries Association,EIA) 制定的异步传输标准接口,同时对应着电平标准和通信协议(时序),其电平标准:+3V~+15V对应0,-3V~-15V对应1。rs232 的逻辑电平和TTL 不一样但是协议一样。

    RS-232电平:全双工(逻辑1:-15V--5V  逻辑0:+3V--+15V)

    1、硬件框图如下,TTL用于MCU与PC机之间通信

    2、‘0’和‘1’表示

    RS485:RS485是一种串口接口标准,为了长距离传输采用差分方式传输,传输的是差分信号,抗干扰能力比RS232强很多。两线压差为-(2~6)V表示0,两线压差为+(2~6)V表示1

    RS-485:半双工、(逻辑1:+2V--+6V  逻辑0: -6V---2V)这里的电平指AB 两线间的电压差。

    1、硬件框图如下

    2、‘0’和‘1’表示


    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     

    COM口即串行通讯端口,简称串口。这里区别于USB的“通用串行总线”和硬盘的“SATA”。

    一般我们见到的是两种物理标准。D型9针插头,和 4针杜邦头两种。

    这是常见的4针串口,在电路板上常见,经常上边还带有杜邦插针。还有时候有第五根针,3.3V电源端。

    由于是预留在电路板上的,协议可以有很多种,要看具体设备。

     

     嵌入式里面说的串口,一般是指UART口, 但是我们经常搞不清楚它和COM口的区别,  以及RS232, TTL等关系,  实际上UART,COM指的物理接口形式(硬件), 而TTL、RS-232是指的电平标准(电信号).

     UART有4个pin(VCC, GND, RX, TX), 用的TTL电平,  低电平为0(0V),高电平为1(3.3V或以上)。

    下面这个就是D型9针串口(通俗说法)。在台式电脑后边都可以看到。

    记住,这种接口的协议只有两种:RS-232和RS-485。不会是TTL电平的(除非特殊应用)。

    9针串口的定义可以参考这里:http://wenku.baidu.com/view/5c170c6925c52cc58bd6be6e.html

    我们一般只接出RXD TXD两针,外加GND。  

     

    下图是个USB转TTL串口的小板,可以用USB扩展出一个串口。芯片为PL2303HX。

    网上经常混淆各种串口,但是这个确实是可以给STC单片机下载程序的。

     

    这是另一种,CP2102芯片的,也是USB转TTL串口。据说比PL2303的好,实际使用中没感觉出来。这个小板就多了+3.3V电源端,以适应不同的目标电路。

     

    下图为USB转RS-232串口:

    展开全文
  • STM32开发 -- 串口详解

    万次阅读 多人点赞 2019-04-25 21:59:51
    讲完GPIO,接下来看一下串口。 未完待续!!

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/80708964

    讲完GPIO,接下来看一下串口。
    串口通信,已经讲了很多次了。这次主要想看的是STM32单片机怎么配置串口。
    S5PV210开发 – 通信
    S5PV210开发 – UART 详解
    S5PV210开发 – 串口驱动开发
    UNIX再学习 – RS485 串口编程
    汽车行驶姿态 – 串口通信
    日常生活小技巧 – UART 回环测试

    一、通信接口

    处理器与外部设备通信的两种方式:

    并行通信:

    -传输原理:数据各个位同时传输。
    -优点:速度快
    -缺点:占用引脚资源多
    这里写图片描述

    串行通信:

    -传输原理:数据按位顺序传输。
    -优点:占用引脚资源少
    -缺点:速度相对较慢
    这里写图片描述

    串行通信,按照数据传送方向,分为:

    单工:
    数据传输只支持数据在一个方向上传输
    这里写图片描述
    半双工:
    允许数据在两个方向上传输,但是,在某一时刻,只允许数
    据在一个方向上传输,它实际上是一种切换方向的单工通信;
    这里写图片描述
    全双工:
    允许数据同时在两个方向上传输,因此,全双工通信是两个
    单工通信方式的结合,它要求发送设备和接收设备都有独立
    的接收和发送能力。
    这里写图片描述

    串行通信的通信方式:

    **同步通信:**带时钟同步信号传输。
    如:SPI,IIC通信接口
    **异步通信:**不带时钟同步信号。
    如:UART(通用异步收发器),单总线

    常见的串行通信接口:

    这里写图片描述

    二、STM32的串口通信接口

    UART:通用异步收发器(universal asynchronous receiver and transmitter)
    USART:通用同步异步收发器(universal synchronous asynchronous receiver and transmitter)

    其中:
    通用同步异步收发器(USART)
    小容量产品:是指闪存存储器容量在16K至32K字节之间的STM32F101xx、 STM32F102xx和STM32F103xx微控制器。
    中容量产品:是指闪存存储器容量在64K至128K字节之间的STM32F101xx、 STM32F102xx和STM32F103xx微控制器。
    大容量产品:是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控制器。
    互联型产品:是指STM32F105xx和STM32F107xx微控制器。
    除非特别说明,本章描述的模块适用于整个STM32F10xxx微控制器系列。

    我使用的是 STM32F105xx,所以是互联型产品包含3个USART和2个UART。(USART1/USART2/USART3/UART4/UART5)

    三、UART异步通信方式引脚连接方法

    -RXD:数据输入引脚。数据接收。
    -TXD:数据发送引脚。数据发送。
    串口交叉线
    这里写图片描述
    串口直通线
    这里写图片描述

    四、UART异步通信方式特点

    ● 全双工的,异步通信
    ● 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位),总线空闲

    五、串口通信过程

    这里写图片描述

    六、STM32串口异步通信需要定义的参数

    起始位
    数据位(8位或者9位)
    奇偶校验位(第9位)
    停止位(1,15,2位)
    波特率设置
    这里写图片描述

    七、串口配置

    串口设置的一般步骤可以总结为如下几个步骤:
    1、串口时钟使能,GPIO时钟使能
    2、串口复位
    3、GPIO端口模式设置
    4、串口参数初始化
    5、开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
    6、使能串口
    7、编写中断处理函数

    下面, 我们就简单介绍下这几个与串口基本配置直接相关的几个固件库函数。 这些函数和定义主要分布在 stm32f10x_usart.h 和stm32f10x_usart.c 文件中。
    1.串口时钟使能。 串口是挂载在 APB2 下面的外设,所以使能函数为:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
    

    2.串口复位。 当外设出现异常的时候可以通过复位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。 复位的是在函数 USART_DeInit()中完成:

    void USART_DeInit(USART_TypeDef* USARTx);//串口复位
    

    比如我们要复位串口 1,方法为:

    USART_DeInit(USART1); //复位串口 1
    

    3.串口参数初始化。 串口初始化是通过 USART_Init()函数实现的,

    void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
    

    这个函数的第一个入口参数是指定初始化的串口标号,这里选择 USART1。
    第二个入口参数是一个 USART_InitTypeDef 类型的结构体指针, 这个结构体指针的成员变量用来设置串口的一些参数。 一般的实现格式为:

    USART_InitStructure.USART_BaudRate = bound; //波特率设置;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式
    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); //初始化串口
    

    从上面的初始化格式可以看出初始化需要设置的参数为:波特率,字长,停止位,奇偶校验位,硬件数据流控制,模式(收,发)。 我们可以根据需要设置这些参数。
    4.数据发送与接收。 STM32 的发送与接收是通过数据寄存器 USART_DR 来实现的,这是一个双寄存器,包含了 TDR 和 RDR。当向该寄存器写数据的时候,串口就会自动发送,当收到数据的时候,也是存在该寄存器内。
    STM32 库函数操作 USART_DR 寄存器发送数据的函数是:

    void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
    

    通过该函数向串口寄存器 USART_DR 写入一个数据。
    STM32 库函数操作 USART_DR 寄存器读取串口接收到的数据的函数是:

    uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
    

    通过该函数可以读取串口接受到的数据。
    5.串口状态。 串口的状态可以通过状态寄存器 USART_SR 读取。 USART_SR 的各位描述如图 9.1.1 所示:
    这里写图片描述
    这里我们关注一下两个位,第 5、 6 位 RXNE 和 TC。
    RXNE(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将该位清零,也可以向该位写 0,直接清除。
    TC(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如果设置了这个位的中断,则会产生中断。该位也有两种清零方式: 1)读 USART_SR,写USART_DR。 2)直接向该位写 0。
    状态寄存器的其他位我们这里就不做过多讲解,大家需要可以查看中文参考手册。
    在我们固件库函数里面,读取串口状态的函数是:

    FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
    

    这个函数的第二个入口参数非常关键, 它是标示我们要查看串口的哪种状态, 比如上面讲解的RXNE(读数据寄存器非空)以及 TC(发送完成)。例如我们要判断读寄存器是否非空(RXNE), 操作库函数的方法是:

    USART_GetFlagStatus(USART1, USART_FLAG_RXNE);
    

    我们要判断发送是否完成(TC),操作库函数的方法是:

    USART_GetFlagStatus(USART1, USART_FLAG_TC);
    

    这些标识号在 MDK 里面是通过宏定义定义的:

    #define USART_IT_PE ((uint16_t)0x0028)
    #define USART_IT_TXE ((uint16_t)0x0727)
    #define USART_IT_TC ((uint16_t)0x0626)
    #define USART_IT_RXNE ((uint16_t)0x0525)
    #define USART_IT_IDLE ((uint16_t)0x0424)
    #define USART_IT_LBD ((uint16_t)0x0846)
    #define USART_IT_CTS ((uint16_t)0x096A)
    #define USART_IT_ERR ((uint16_t)0x0060)
    #define USART_IT_ORE ((uint16_t)0x0360)
    #define USART_IT_NE ((uint16_t)0x0260)
    #define USART_IT_FE ((uint16_t)0x0160)
    

    6.串口使能。 串口使能是通过函数 USART_Cmd()来实现的,这个很容易理解,使用方法是:

    USART_Cmd(USART1, ENABLE); //使能串口
    

    7.开启串口响应中断。 有些时候当我们还需要开启串口中断,那么我们还需要使能串口中断,使能串口中断的函数是:

    void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT,
    FunctionalState NewState)
    

    这个函数的第二个入口参数是标示使能串口的类型, 也就是使能哪种中断, 因为串口的中断类型有很多种。 比如在接收到数据的时候(RXNE 读数据寄存器非空),我们要产生中断,那么我们开启中断的方法是:

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断
    

    我们在发送数据结束的时候(TC, 发送完成) 要产生中断,那么方法是:

    USART_ITConfig(USART1, USART_IT_TC, ENABLE);
    

    8.获取相应中断状态。 当我们使能了某个中断的时候,当该中断发生了,就会设置状态寄存器中的某个标志位。 经常我们在中断处理函数中,要判断该中断是哪种中断,使用的函数是:

    ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
    

    比如我们使能了串口发送完成中断,那么当中断发生了, 我们便可以在中断处理函数中调用这个函数来判断到底是否是串口发送完成中断,方法是:

    USART_GetITStatus(USART1, USART_IT_TC)
    

    返回值是 SET,说明是串口发送完成中断发生。

    八、串口程序完整代码

    参看:USART串口通信配置

    #include "stm32f10x.h"
    u8 Uart1_Get_Flag  = 0;
    // 串口初始化函数
    void My_USART1_Init(void)
    {
        GPIO_InitTypeDef GPIO_InitStrue;
        USART_InitTypeDef USART_InitStrue;
        NVIC_InitTypeDef NVIC_InitStrue;
    
        // 1,使能GPIOA,USART1时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    
        // 2,设置PGIO工作模式-PA9 PA10复用为串口1
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;//USART1_TX PA.9
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
        GPIO_Init(GPIOA,&GPIO_InitStrue); //初始化 GPIOA.9
    
        GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入
        GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;//USART1_RX PA.10
        GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
        GPIO_Init(GPIOA,&GPIO_InitStrue); //初始化 GPIOA.10
    
        // 3,串口1初始化配置
        USART_InitStrue.USART_BaudRate=115200;//波特率设置
        USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//收发模式
        USART_InitStrue.USART_Parity=USART_Parity_No; //无奇偶校验位
        USART_InitStrue.USART_StopBits=USART_StopBits_1; //一个停止位
        USART_InitStrue.USART_WordLength=USART_WordLength_8b;//字长为 8 位
    
        USART_Init(USART1,&USART_InitStrue);//初始化串口
    
        // 4,打开串口1
        USART_Cmd(USART1,ENABLE);//使能串口
    
        // 5,使能串口1中断-接收数据完成中断
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启中断
    
        // 6,设置中断优先级-主函数中设置中断优先级分组
        NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;
        NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;//IRQ 通道使能
        NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级 1
        NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;//子优先级 1
        NVIC_Init(&NVIC_InitStrue);//中断优先级初始化
    
    }
    
    void USART1_Puts(char * str)
    {
        while(*str)
        {
            USART_SendData(USART1, *str++);
            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
        }
    }
    
    // 中断服务函数
    void USART1_IRQHandler(void)
    {
        u8 res;
        if(USART_GetITStatus(USART1,USART_IT_RXNE))// 接收到数据
        {
            USART_ClearITPendingBit(USART1,USART_IT_RXNE);
            res= USART_ReceiveData(USART1); // 获得串口1接收到的数据
    	    Uart1_Get_Flag=1;
        }
    }
    
    // 主函数
    int main(void)
    {   
        // 设置中断优先级分组位2 - 2位抢占2位相应
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
        // 调用函数 初始化USART1相关引脚配置
        My_USART1_Init();
        if (Uart1_Get_Flag){
    	   Uart1_Get_Flag = 0;
    	   USART1_Puts(res);
        }
    
    return 0;
    }
    

    九、串口其他需要了解的

    串口相关寄存器

    上面串口部分其实基本上已经讲完了。
    但是我们用的库函数版本是3.5的。在串口配置中还要配置USART 时钟的。
    首先看下串口相关的寄存器:

    USART_SR 状态寄存器
    USART_DR 数据寄存器
    USART_BRR 波特率寄存器
    USART_CR1 控制寄存器
    

    具体的配置看STM32中文参考手册了解一下,直接用串口库函数就好了。

    十、串口操作相关库函数

    获取状态标志位函数-操作USART_SR寄存器

    // 获取状态标志位
    FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
    // 清除状态标志位
    void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);
    // 获取中断状态标志位
    ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);
    // 清除中断状态标志位
    void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);
    

    接收发送数据函数-操作USART_DR寄存器

    // 发送数据到串口(通过写USART_DR寄存器发送数据)
    void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
    // 接收数据(从USART_DR寄存器读取接收到的数据)
    uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
    

    串口配置函数

    // 串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能
    void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
    // 使能串口
    void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
    // 使能相关中断
    void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);
    

    我们用的库函数V3.5里面还有:
    这里写图片描述

    串口复位
    void USART_DeInit(USART_TypeDef* USARTx)
    串口时钟的初始化:
    void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct)
    串口通信DMA中断
    void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)
    

    所以除了上述的串口配置,还可以添加如下的配置:

    	USART_InitTypeDef USART_InitStrue;
        USART_ClockInitTypeDef  USART_CLK_InitStrue;
        USART_InitStrue.USART_BaudRate            = baud_rate;//波特率设置
        USART_InitStrue.USART_WordLength          = USART_WordLength_8b;//字长为 8 位
        USART_InitStrue.USART_StopBits            = USART_StopBits_1;//一个停止位
        USART_InitStrue.USART_Parity              = USART_Parity_No ;//无奇偶校验位
        USART_InitStrue.USART_HardwareFlowControl =    USART_HardwareFlowControl_None;//无硬件数据流控制
        USART_InitStrue.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;//收发模式
        USART_CLK_InitStrue.USART_Clock           = USART_Clock_Disable;//USART 时钟失能
        USART_CLK_InitStrue.USART_CPOL            = USART_CPOL_Low;//SCLK引脚上时钟输出的极性
        USART_CLK_InitStrue.USART_CPHA            = USART_CPHA_2Edge;//SLCK引脚上时钟输出的相位
        USART_CLK_InitStrue.USART_LastBit         = USART_LastBit_Disable;//是否在同步模式下
        USART_Init(USART1,&USART_InitStrue);//初始化串口
        USART_ClockInit(USART1, &USART_CLK_InitStrue);//初始化USART时钟
    
    

    PS:刚开始有点不太理解,为什么要用到串口时钟。
    回顾了一下上面讲到的:
    我使用的是 STM32F105xx,所以是互联型产品,包含3个USART和2个UART。(USART1/USART2/USART3/UART4/UART5)

    UART:通用异步收发器,如RS232
    USART:通用同步异步收发器,如 IIC通信, SPI通信
    同步通信,例如IIC通信是需要时钟的。

    我又有疑问了?
    那如果UART和USART都不使用时钟,两者配置有什么区别?
    上一讲讲到APB的时候有提到:
    APB1(低速)、APB2(高速)
    APB2****负责 AD,I/O,高级TIM,串口1。
    APB1负责 DA,USB,SPI,I2C,CAN,串口2345,普通TIM,PWR
    说明:
    由于UART的TX和RX和AFIO都挂在APB2桥上,因此采用固件库函数RCC_APB2PeriphClockCmd()进行初始化。UARTx需要分情况讨论,如果是UART1,则挂在APB2桥上,因此采用RCC_APB2PeriphClockCmd()进行初始化,其余的UART2~5均挂在APB1上。

    正好对应了网上看的这段话:
    UART1的时钟:PCLK2(高速);
    UART2、UART3、UART4、UART5的时钟:PCLK1(低速)。

    下面为手册上USART和UART配置的区别:
    这里写图片描述
    这里写图片描述
    我们程序的配置如下:

    void	Bsp_Usart_Init(u8	USART_ID,	u32 baud_rate)
    {
    	GPIO_InitTypeDef        gpio_init;
    	USART_InitTypeDef       usart_init;
        USART_ClockInitTypeDef  usart_clk_init;
    
        /* ----------------- INIT USART STRUCT ---------------- */
        usart_init.USART_BaudRate            = baud_rate;
        usart_init.USART_WordLength          = USART_WordLength_8b;
        usart_init.USART_StopBits            = USART_StopBits_1;
        usart_init.USART_Parity              = USART_Parity_No ;
        usart_init.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        usart_init.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
    
        usart_clk_init.USART_Clock           = USART_Clock_Disable;
        usart_clk_init.USART_CPOL            = USART_CPOL_Low;
        usart_clk_init.USART_CPHA            = USART_CPHA_2Edge;
        usart_clk_init.USART_LastBit         = USART_LastBit_Disable;
    
    	/*-------------------USART1   用作GSM通信 -----------*/
    	if (USART_ID == DEF_USART_1)
    	{
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    		
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    		GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);  //通讯角映射到PB6,PB7	
    				
    		/* Configure GPIOA.9 as push-pull              USART1-TX         */
    		gpio_init.GPIO_Pin   = BSP_GPIOB_USART1_TX_PINS;
    		gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
    		gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
    		GPIO_Init(GPIOB, &gpio_init);
    				
    		/* Configure GPIOA.10 as input floating        USART1-RX         */
    		gpio_init.GPIO_Pin   = BSP_GPIOB_USART1_RX_PINS;
    		gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    		//gpio_init.GPIO_Mode  = GPIO_Mode_IPU;
    		GPIO_Init(GPIOB, &gpio_init);		
    
    		/* ------------------ SETUP USART1 -------------------- */
    		USART_Init(USART1, &usart_init);
    		USART_ClockInit(USART1, &usart_clk_init);
    		    
    		// Clean interrupt flag, and disable txd & rxd interrupt
    		USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
    		USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
    	
    		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    		USART_ClearITPendingBit(USART1, USART_IT_TXE);
    		
    		USART_GetFlagStatus(USART1, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/						
    		USART_Cmd(USART1, ENABLE);	
    	}
    	else if (USART_ID == DEF_USART_2)
    	{
    		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);	
    		/* ----------------- SETUP USART2 GPIO ---------------- */
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			
    		/* Configure GPIOA.2 as push-pull                       */
    		gpio_init.GPIO_Pin   = GPIO_Pin_2;
    		gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
    		gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
    		GPIO_Init(GPIOA, &gpio_init);		
            /* Configure GPIOA.3 as input floating                  */
    		gpio_init.GPIO_Pin   = GPIO_Pin_3;
    		gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    		GPIO_Init(GPIOA, &gpio_init);
    		/* ------------------ SETUP USART2 -------------------- */
    		USART_Init(USART2, &usart_init);
    		//USART_ClockInit(USART2, &usart_clk_init);
    	
    		// Clean interrupt flag, and disable txd & rxd interrupt
    		USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
    		USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
    	
    		USART_ClearITPendingBit(USART2, USART_IT_RXNE);
    		USART_ClearITPendingBit(USART2, USART_IT_TXE);
    	
    		USART_GetFlagStatus(USART2, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/
    		USART_Cmd(USART2, ENABLE);
    	}
    	else if (USART_ID == DEF_USART_3)
    	{
    		RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    				                                                                /* Configure GPIOB.10 as push-pull                      */
    		gpio_init.GPIO_Pin   = GPIO_Pin_10;
    		gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
    		gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
    		GPIO_Init(GPIOB, &gpio_init);
    				
    		gpio_init.GPIO_Pin   = GPIO_Pin_11;
    		gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    		GPIO_Init(GPIOB, &gpio_init);
    		/* ------------------ SETUP USART3 -------------------- */
    		USART_Init(USART3, &usart_init);
    		USART_ClockInit(USART3, &usart_clk_init);
    		// Clean interrupt flag, and disable txd & rxd interrupt
    		USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
    		USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
    	
    		USART_ClearITPendingBit(USART3, USART_IT_RXNE);
    		USART_ClearITPendingBit(USART3, USART_IT_TXE);
    		USART_GetFlagStatus(USART3, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/
    		USART_Cmd(USART3, ENABLE);
    	}
    	//--------------------UART4   打印	 调试窗口
    	else if (USART_ID == DEF_UART_4)
    	{
    		RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
    		
    		/* ----------------- SETUP USART4 GPIO ---------------- */
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    		/* Configure GPIOC.10 as push-pull                       */
    		gpio_init.GPIO_Pin   = GPIO_Pin_10;
    		gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
    		gpio_init.GPIO_Mode  = GPIO_Mode_AF_PP;
    		GPIO_Init(GPIOC, &gpio_init);
    		/* Configure GPIOC.11 as input floating                 */
    		gpio_init.GPIO_Pin   = GPIO_Pin_11;
    		gpio_init.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
    		GPIO_Init(GPIOC, &gpio_init);	
    		
    		/* ------------------ SETUP UART4 -------------------- */
    		USART_Init(UART4, &usart_init);
    		USART_ClockInit(UART4, &usart_clk_init);
    	
    		// Clean interrupt flag, and disable txd & rxd interrupt
    		USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);
    		USART_ITConfig(UART4, USART_IT_TXE, DISABLE);
    	
    		USART_ClearITPendingBit(UART4, USART_IT_RXNE);
    		USART_ClearITPendingBit(UART4, USART_IT_TXE);
    	
    		USART_GetFlagStatus(UART4, USART_FLAG_TC);/* 记得加上,不先读一下第一字节会发不出去,*/
    		USART_Cmd(UART4, ENABLE);		
    	}
    }
    

    十一、初始化GPIO的工作模式

    如果关注上面的GPIO配置,你可以发现:
    TX的GPIO工作模式为:GPIO_Mode_AF_PP;//复用推挽输出
    RX的GPIO工作模式为:GPIO_Mode_IN_FLOATING;//浮空输入
    这是为什么呢?通过查找STM32中文参考手册 外设的GPIO配置来确定:
    这里写图片描述

    总结:
    STM32的串口部分,到此讲完了。
    基本上,配置部分都是固定套路,只要往上套就可以了。

    其实有时间,能总结一下挺好的。就好比之前这个配置可能照猫画虎套路一下就可以了。但是为什么要这么配置?如果不是为了写这篇文章,我是不会看手册,更不会知道的。

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/80708964

    展开全文
  • 关于各种串口

    千次阅读 2016-07-25 19:22:27
    初学单片机串口通信,对各种概念弄得一团糟,由此想到做一个整理。 串口 并口 USB RS232 485TTL诸如此类到底是什么关系 首先数据通信分为串口与并口 通俗点来说串口是单车道 并口是八车道 (PS: 为什么是八车道 这...
  • 串口通讯协议

    万次阅读 多人点赞 2018-03-02 10:02:47
    文章转载自http://www.cnblogs.com/firege/p/5805753.html20.1 串口通讯协议简介串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师...
  • COM口、UART口、串口的区别

    千次阅读 2018-09-29 09:55:46
    最近在接触串行通信,很多小知识在作者的文章讲的挺明白的,有趣的多看看呗!...1、串口、COM口是指的物理接口形式(硬件)。而TTL、RS-232、RS-485是指的电平标准(电信号)。 2、接设备的时候,一般...
  • UART接口与COM口的区别

    万次阅读 2017-12-24 10:13:28
     嵌入式里面说的串口,一般是指UART口, 但是我们经常搞不清楚它和COM口的区别, 以及RS232, TTL等关系, 实际上UART,COM指的物理接口形式(硬件), 而TTL、RS-232是指的电平标准(电信号).  UART有4个pin(VCC, GND, ...
  • 串口、COM口、TTL、RS-232的区别详解

    千次阅读 2018-06-27 17:32:16
    Point: 1、串口、COM口是指的物理接口形式(硬件)。而TTL、RS-232、RS-485是指的电平... 3、PL2303、CP2102芯片是 USB 转 TTL串口 的芯片,用USB来扩展串口(TTL电平)。 4、MAX232芯片是 TTL电平与RS232电平...
  • 介绍几款串口监控工具

    万次阅读 2020-09-17 09:35:00
    特在网上找了几款串口监控软件,作了简单对比: 一、Device Monitoring Studio 网址:http://www.hhdsoftware.com 程序截屏: 软件功能比较强大,是收费软件,免费试用15天。从截图可以看出,选择了通信端口...
  • 虚拟串口软件和串口调试助手的简单使用

    万次阅读 多人点赞 2015-11-14 20:26:29
    为解决计算机的物理串口个数的限制,在进行串口调试实验时,应尽可能采用虚拟串口软件。VSPD(Virtual Serial Ports Driver)虚拟串口软件是由Eltima软件公司设计的虚拟串口软件,使用方便且稳定。同时,使用虚拟...
  • MATLAB利用串口接收数据,并实时显示图形,点这里
  • 所需软件: vspd :虚拟串口创建软件。 xcom V2.0:串口助手。 详细步骤如下: 1,下载及安装vspd软件,创建虚拟串口COM1,COM2。 2,打开vmware在设置中添加串口
  • 神奇的python(六)之python的串口操作(pyserial)

    万次阅读 多人点赞 2020-02-16 23:11:42
    简介:最近项目突然要使用python串口操作,这不,查资料,翻文档,是时候写一份串口操作的简要用法,以后有时间可以使用pyqt再写个界面,弄个串口调试终端。 (1) 安装pyserial库 pip install pyserial (2) ...
  • Windows上 万能的串口调试助手

    万次阅读 2018-06-02 11:08:13
    之前自己找了很久的串口调试助手,还自己去编写,现在发现了一个非常好用的串口工具:ScriptCommunicator。 这是一个开源软件,功能强大。 ScriptCommunicator软件下载地址:...
  • 查看串口是否可用,可以对串口发送数据比如对com1口,echo lyjie126 > /dev/ttyS0 查看串口名称使用 ls -l /dev/ttyS* 一般情况下串口的名称全部在dev下面,如果你没有...查看串口驱动:cat /proc/tty/drivers/serial
  • 常用串口调试工具比较(详细)

    万次阅读 2018-03-30 08:55:43
    目前有许多免费的串口调试工具,比较常用的有:1、友善串口调试助手(v2.6.5)优点: 1)使用方便,不丢包; 2)串口自动识别,支持COM9以上串口; 3)支持多串口调试; 4)支持历史发送记录; 5)广泛支持各种...
  • Keil串口仿真调试

    万次阅读 2015-08-29 10:08:48
    ★用到的软件 ●Keil开发ruan
  • C# 串口多线程接收

    万次阅读 2013-01-07 11:04:00
    private void ReadPort() { while (true) { if (sComm.IsOpen) { int count = sComm.BytesToRead; if
  • linux在shell下的串口的一些操作

    万次阅读 2015-12-28 10:55:50
    echo aaa > /dev/ttyS0... cat /proc/tty/drivers/serial 查看串口信息 stty查看Arduino的USB串口 先设置串口参数 使用stty -F stty -F /dev/ttyUSB0 raw speed 9600 读取串口 使用
1 2 3 4 5 ... 20
收藏数 203,110
精华内容 81,244
关键字:

串口