我们先来看一下RS-232与TTL电平的区别
我们通常说的TTL电平,就是直接从单片机或直接从芯片中出来的。
从图中可以看到,TTL电平里的1是由+5V来表示的,而RS232串口中的1是由-15V来表示的,于TTL电平表示的逻辑正好相反。
由于RS232协议中峰值相差30V,所以容错能力非常强,在工业设备通信中应用比较广泛。
下面我们来看一下RS232标准串口通讯结构图
控制器发出来的TTL电平需要经过一个电平转换芯片,才能使用RS232标准传输数据。
我们常使用DB9中的2针脚和3针脚,最多再接个5针脚
我们来看一下USB转串口的通讯结构图
USB转串口主要用于设备跟电脑通信
原生的串口通信主要是控制器跟串口的设备或者传感器通信,不需要经过电平转换芯片来转换电平,直接就用TTL电平通信。
**起始位:**由1个逻辑0的数据位表示
**结束位:**由0.5、1、1.5或2个逻辑1的数据位表示
**有效数据:**在起始位后紧接着的就是有效数据,有效数据的长度常被约定为5、6、7或8位长。
**校验位:**可选,为的是提高数据的抗干扰性
两个设备在进行通信前,双方需要先约定好起始位和结束位。
我们先来看一下STM32串口功能框图。
我们先把串口的功能框图分为4部分来分析,
先来看串口通信的引脚,其中TX和RX是我们用得最多的两个引脚。
**TX:**数据发送
**RX:**数据接收
我们知道了每个引脚对应的功能了,接下来我们要查询串口对应的是哪一个GPIO
下面我们打开STM32F10x数据手册——Pinouts and pin description
从表中可以看到,串口1的时钟信号对应PA8引脚,发送端口对应PA9引脚,接收端口对应PA10引脚。
部分引脚具有复用功能,我们在配置时,可以通过查询这个表格来进行配置。
下面我们讲第二部分,数据寄存器
**USART_DR:**9位有效,包含一个发送数据寄存器TDR和一个接收数据寄存器,一个地址对应了两个物理内存。
由于串口是全双工的,所以可以同时收发。
**数据位的长度(字长)**由USART1_CR1控制寄存器中的M位决定,如果M:0就是8bit,反之9bit
停止位由USART1_CR2控制寄存器中的STOP来决定
校验位由USART1_CR1控制寄存器中的PCE、PS、PEIE来决定,如果校验出错,由PEIE来进行中断使能。再由USART_SR状态寄存器中的PE来产生中断
我们接下来需要重点掌握数据的发送和数据的接收流程是怎么样的。
首先,我们通过串口控制寄存器USART_CR1中的UE来给串口使能。
然后,我们需要通过串口控制寄存器中的TE和RE位,来进行发送使能和接收使能。
上面两个都打开以后,串口才能正常地发送和接收数据。
数据从CPU或者DMA过来以后,先放到发送数据寄存器(TDR),然后再放到发送移位寄存器,再一位一位地通过TX端口发送出去。
这个过程中的状态改变会涉及到两个寄存器发生变换,一个是当数据从发送数据寄存器转移到发送移位寄存器时,TXE(Transmit empty)寄存器会置1,意味着发送寄存器为空,这个时候数据还在发送移位寄存器中,并没有发送出去,当发送移位寄存器把数据全部通过TX端口发送出去后,另外一个寄存器TC(Transmit complete)会置1。
首先,数据从RX引脚过来,再放到接收移位寄存器,然后再放到接收数据寄存器(RDR),当数据放到接收数据寄存器以后,会有一个寄存器RXNE(Read data register not empty)置1,当我们检测到RXNE寄存器为1时,就可以读取数据了。
USART_BRR:通过波特率寄存器来控制
波特率的计算需要结合外设挂载的时钟来看。在设置波特率时,我们常用的波特率有115200、9600等。
我们为了得到这个波特率,需要通过一个公式的计算
从上面公式可以看出,我们还需要算出USARTDIV的值并存到USART_BRR寄存器中去。整数部分存在整数的寄存器中,小数部分存在小数的寄存器中就行了。
那么,理论部分已经全部讲完了,下面我们来看看代码部分,其实就是把上面说的数据发送过程和数据接收过程用代码来描述出来就行了。
主要内容分为两个实验来讲解:
实现功能:
- 单片机给电脑发送数据,电脑上位机把数据打印出来。
- 电脑上位机给单片机发送数据,单片机接收到数据之后立马返回给电脑,并打印出来。
编程步骤:
-
初始化串口需要用到的GPIO
本次实验使用USART1来做演示,通过查看图8,可以发现,USART1对应的发送引脚和接收引脚分别为PA9和PA10,所以我们先对这两个GPIO进行初始化。
-
初始化串口,USART_InitTypeDef
-
中断配置(接收中断,中断优先级)
-
使能串口
-
编写发送和接收函数
-
编写中断服务函数
实现功能:
- 电脑给单片机发命令,用于控制开发板上的RGB灯。
编程步骤
-
初始化串口需要用到的GPIO
与上面的实验类似,我们需要先配置串口发送和接收引脚对应的GPIO,不同的是,我们还需要配置LED灯的GPIO,因为我们要通过LED灯的亮灭来展示实验现象。
串口发送和接收引脚对应的GPIO我就不配置了,上面实验配置的代码一模一样,我只配置LED的GPIO。
- 初始化串口
初始化串口的代码与上面实验相同,仅仅去掉中断部分。
- 使能串口
上同。
- 编写发送函数
我们向串口发送1时,让LED亮绿灯,发送2时亮红灯,发送3时,亮蓝灯。