STM32学习笔记之:第三章串口(UART)

        由于现在学习的是以寄存器库为基础来实现功能,所以以后的知识点和代码都是以寄存器库来配置的,还有目前现在用的板子是STM32F407VET6,该笔记只是自己的见解和理解,大佬勿喷。

4.1 通信协议的介绍

UART串口:通信协议(通信接口)

        什么是通信协议:一个已经固定规则,两个或者两个以上的器件想要正常通信,器件之间必须要遵循规则,这个规则就是通信协议    

通信协议特点:(通信协议名词补充)

1.同步与异步

        同步:步调一致(两个器件之间通信速度相同)        异步:通信速度不一样(两个器件之间通信速度不相同)

        同步:两个设备/器件之间步调一致,两个设备之间有一根时钟线进行连接,同步两个器件之间的通信速度、决定两个器件之间数据传输方式(IIC、SPI等)

        异步:两个设备/器件之间步调不一致,没有时钟线相连,需要保证两个器件之间的通信速度相同,两个设备/器件之间才能正常,需要分别规定两个器件之间通信速度,保证两个器件之间通信速度相同

(UART异步通信  ---  波特率)

 

总结:同步通信:有时钟线连接,并且时钟线可以控制两个设备之间的速度,让速度保持一致

           异步通信:没有时钟线连接,需要用户自行规定两个设备的数据传输速度

2.单工、半双工、全双工

        单工、半双工、全双工:针对两个设备/器件之间数据发送(数据线数量、传输数据方向有关)

单工:两个器件/设备之间,在相同环境下,器件A与器件B在整一个传输过程中,器件A只能发送数据到器件B,传输方向单一(数据传输方向为单向传输)

半双工:两个器件/设备之间,在相同环境下,器件A与器件B在整一个传输过程中,在这一时刻器件A发送数据到器件B,下一时刻器件B也能发送数据器件A,半双工传输方向可以改变,在特定条件下,数据传输方向需要进行切换,传输方向可变

总结:单工、半双工它们只有一根数据线

全双工:两个器件/设备之间,在相同环境下,器件A与器件B在整一个传输过程中,器件A既能发送数据到器件B ,器件B也能发送数据到器件A,会有两根数据线,一根数据线负责发送数据、宁外一根负责接收

说明:一般全双工通信都会有发送端(TX/TXD)和接收端(RX/RXD)

            会有两根数据线负责数据传输             发送要比接收先

3.串行与并行

        数字量由0/1组成,数据一般以字节为单位,1byte = 8bit

串行:独木桥,人需要按照顺序一个接一个通过,数据需要一个一个进行发送(不能同时发送多个数据)

优点:简单,代码好写并不容易出错           

缺点:传输速度较慢

并行:高速,车道,能同时并排走很多辆车,数据可以同时发送多个

优点:传输速度快

缺点:较复杂、代码不好写并数据容易出错

4.现场总线/板级总线

现场总线:工业控制现场总线(可远距离传输数据)   ---  长距离传输

         如:485总线---千米级别    UART

                can总线---十千米级

板级总线:芯片之间通信(距离长会被干扰)   --- 短距离传输

         如:IIC/SPI/8080并行

5.有线通信/无线通信

有线:可靠性强      传输距离远:线的长度

        UART、IIC、SPI、CAN等

无线:方便      传输距离短

        GSM(2G)  蓝牙(BLE)  433(500m)  2.4G       wifi频宽:2.4Ghz      5Ghz     Lora(低功耗)

6.通信配置方式:UART

配置控制器通信:(串口控制器  --- 实现MCU与PC之间通信)    配置USART控制器   配置USART寄存器

        根据寄存器去配置器件                不需要去理解时序图

        优点:简单     UART                   缺点:移植性较差

IO模拟通信:(IIC --- IO模拟方式去写代码   SPI   UART)

        需要用户去理解时序图(将时序图翻译成代码)  ---  初学者比较难

        优点:移植性强

4.2 UART概述

4.2.1什么是UART& UART的作用

UART: 通用串行数据总线

例子:wifi与MCU通信、PC电脑与MCU通信、传感器与MCU通信、MCU与MCU通信

                注意:通信是产品的基础,也是核心

        UART是一种通讯协议,一个标准的通信协议,这是一个固定的通信协议,我们需要遵循这个通讯协议,才能进行器件间的通信

4.2.2UART通信原理

串口拓扑图:

  1. UART通信方式:异步全双工串行通信

4.3.3 UART数据帧格式(重点)

数据帧:UART完整一帧数据

 数据帧:起始位 + 数据位 + 校验位 + 停止位

起始位:占1bit,表示一帧数据的开始

数据位:   占5 - 8bit(可选)

校验位:用来校验发送或者接收的数据

        UART的校验方式:奇偶校验   -->  奇校验   /  偶校验     在UART不会去使用

停止位:占0.5bit - 2bit(可选),表示一帧数据结束

假设器件A需要接收数据:0101 1110,使用奇校验        1001 1110

        ①校验数据里面'1'的个数        5个

        ②如数据中‘1’的个数为奇数的话,校验则返回‘0’,如数据中‘1’的个数为偶数,校验则返回‘1’

偶校验同理

一般UART通信不使用奇偶校验:

        ①验证错误率低

        ②无法知道错误的数据位

        ③减少代码流程 

4.3.4 UART四要素(非常重要)

只要清楚四要素的作用和学会如何配置四要素,就能完成UART初始化代码

需要再哪里找到四要素:    PC端上位机 

波特率:决定数据传输速度       在STM32中常用9600     115200

9600:一秒传输9600个比特位(1s传输9600bit数据)

停止位:XCOM中1 - 1.5bit可选,在STM32中1bit、2bit可选

数据位:传输数据的长度,8bit

校验位:奇偶校验 ,一般不使用

4.3 STM32F407VET6的UART

STM32串口控制器:USART       ---   片上外设

芯片片上外设介绍 ---》请参考中文参考手册    

UART :异步串口 -->  USART:同步异步串口

4.3.1 简介

        通用同步异步收发器 (USART) 能够灵活地与外部设备进行全双工数据交换,满足外部设备对工业标准 NRZ 异步串行数据格式的要求。满足:异步串行全双工通信 ,USART 通过小数波特率发生器提供了多种波特率。(计算)

        它支持同步单向通信和半双工单线通信;还支持 LIN( 局域互连网络)、智能卡协议与 IrDA(红外线数据协会) SIR ENDEC 规范,以及调制解调器操作 (CTS/RTS)。而且,它还支持多处理器通信。

        通过配置多个缓冲区使用 DMA 可实现高速数据通信。   DMA数据搬运工

4.3.2串口控制器框图(重要)

中文参考手册      第26章    功能说明

控制器引脚部分:        TX:数据发送口(GPIO口)        RX:数据接收口  (GPIO口)

nCTS:

        清除以发送(Clear To Send),n 表示低电平有效。如果使能 CTS 流控制,

        发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,

        如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。

nRTS:

        请求以接收(Request To Send),n 表示低电平有效。如果使能 RTS 流控制,

        当 USART 接收器准备好接收新数据时就会将 nRTS 变成低电平;当接收寄存器已满时,

        nRTS 将被设置为高电平。该引脚只适用于硬件流控制。

                nCTS和nRTS这两个管脚会占用IO口,一般不使用硬件流传输控制

数据传输框图部分

        发送数据过程:

        写入到发送数据寄存器(TDR)里面,数据进入到发送数据寄存器后自动载入发送位移寄存器,再通过发送位移寄存器将数据一位一位发送到外界       USART1->DR = data;

        接收数据过程:

        接收位移寄存器接收一位一位数据,接收位移寄存器将一位一位数据自动载入接收数据寄存器里面,如果想获取接收到的数据,则读取接收数据寄存器里面的值  , data = USART1->DR;

        DR(数据寄存器) :

        因为数据寄存器包含两个寄存器,一个用于发送 (TDR),一个用于接收 (RDR),因此它具有双重功能(读和写)

        当发送数据时,TDR开始工作     USART1->DR = data;

        当接收数据时,RDR开始工作     data = USART1->DR;

通信协议控制部分:

看寄存器的描述  --- 中文参考手册

波特率框图部分:

波特率计算:   需要将波特率计算出来并把结果写入USART_BRR寄存器

如需要设置波特率,则需要设置DIV_F和DIV_M,利用公式计算DIV_F和DIV_M

Tx/Rx波特率:已知条件

fck:总线的频率       USART1需要对应总线频率    --  APB2  84Mhz   已知条件

OVER8:代表过采样    已知    0 :16倍过采样 /   1:8倍过采样

USARTDIV:未知量

                USARTDIV = Fck / 8*(2 - OVER8) / 波特率

DIV_F:相当于USARTDIV小数部分(注意并不是直接把小数提取)

                DIV_F = (USARTDIV - DIV_M)*8*(2 - OVER8)

DIV_M:相当于USARTDIV的整数部分(提取整数)

小数部分计算公式:

                 DIV_F = (USARTDIV - DIV_M)*8*(2 - OVER8)

 4.4 串口控制器相关寄存器

状态寄存器 : 涉及标志位

控制寄存器:配置某个器件寄存器(初始化外设)

状态寄存器 (USART_SR)

7 TXE:发送数据寄存器为空 (Transmit data register empty)

TDR 寄存器的内容已传输到移位寄存器时,该位由硬件置 1。如果 USART_CR1 寄存器

TXEIE = 1,则会生成中断。通过对 USART_DR 寄存器执行写入操作将该位清零。

0:数据未传输到移位寄存器 ,表示此时不可以发送数据

1:数据传输到移位寄存器,表示此时可以发送数据

硬件:自动置1

软件:手动置1

6 TC:发送完成 (Transmission complete)

如果已完成对包含数据的帧的发送并且 TXE 1,则该位由硬件置 1。如果 USART_CR1 寄存

器中 TCIE = 1,则会生成中断。该位由软件序列清零(读取 USART_SR 寄存器,然后写入

USART_DR 寄存器)。TC 位也可以通过向该位写入‘0’来清零。建议仅在多缓冲区通信

时使用此清零序列。

0:传送未完成

1:传送已完成

代表发送数据完成,此位自动置1

5 RXNE:读取数据寄存器不为空 (Read data register not empty)

RDR 移位寄存器的内容已传输到 USART_DR 寄存器时,该位由硬件置 1。如果

USART_CR1 寄存器中 RXNEIE = 1,则会生成中断。通过对 USART_DR 寄存器执行读入

操作将该位清零RXNE 标志也可以通过向该位写入零来清零。建议仅在多缓冲区通信时使

用此清零序列。

0:未接收到数据

1:已准备好读取接收到的数据

数据寄存器 (USART_DR)

波特率寄存器 (USART_BRR)

控制寄存器 1 (USART_CR1)

15 OVER8:过采样模式 (Oversampling mode)

016 倍过采样

18 倍过采样

13 UEUSART 使能 (USART enable)

该位清零后,USART 预分频器和输出将停止,并会结束当前字节传输以降低功耗。此位由软

件置 1 和清零。

0:禁止 USART 预分频器和输出

1:使能 USART

注意:器件使能一般在硬件初始化最后

12 M:字长 (Word length)

该位决定了字长。该位由软件置 1 或清零。

01 起始位,8 数据位,n 停止位

11 起始位,9 数据位,n 停止位

第9位:校验位

3 TE:发送器使能 (Transmitter enable)

该位使能发送器。该位由软件置 1 和清零。

0:禁止发送器

1:使能发送器

2 RE:接收器使能 (Receiver enable)

该位使能接收器。该位由软件置 1 和清零。

0:禁止接收器

1:使能接收器并开始搜索起始位

控制寄存器 2 (USART_CR2)

13:12 STOP:停止位 (STOP bit)

这些位用于编程停止位。

001 个停止位

010.5 个停止位

102 个停止位

111.5 个停止位

 

USART属于片上外设

如果片上外设需要与外界建立通信需要借助GPIO

USART  -->  PC

4.5 IO口的复用功能如何配置

复用

        USART:片上外设      --》  IO     需要跟外界通信        

        USART1_TX     USART1_RX --- 复用到对应IO

说明:

         每个IO口都有自己固定的复用功能,并不是每个IO口都可以复用任何功能

         如何知道IO口具体的复用功能------------查表(数据手册)

如何配置复用功能

①确定IO(根据具体的复用功能确定IO)  

        根据自己需要的复用功能去查看哪个管脚支持这个复用功能(STM32F407VET6)    ------  通常通过原理图就可以确定/数据手册

USART1_TX   ---  PA9     ---   复用模式

USART1_RX  ---   PA10  ---   复用模式       

②确定低位复用寄存器和高位复用寄存器的位   

        看复用功能高位寄存器     PA9:[7-4]         PA10:[11-8]             

③确定标识

        中文参考手册      7.3.2   GPIO引脚复用器和映射

 

USART1对应标识为AF7

PA9:[7-4]       -->  AF7   

④确定数值    AF7 : 7

        去查看具体寄存器下面的说明(中文参考手册)  

                        GPIOA-> AFRH |= 7 << 4;          //将PA9复用到USART1     

                        GPIOA->AFRH |= 7 << 8;           //将PA10复用到USART1

注意:低位复位寄存器和高位复位寄存器调用方式

例子:

USART1_TX

确定IOPA9

确定复用寄存器的位: 4 - 7

确定标识:AF7

确定写入值:    7 

GPIOA->      AFRH |= 7 << 4;          //将PA9复用到USART1   

4.6 USAR初始化

4.6.1 软件设计

USART1初始化函数:

步骤:①分析原理图

USART1_TX   ---  PA9  --- 复用模式

USART1_RX   ---  PA10  --- 复用模式

②代码流程

USART1初始化函数

{

        //打开GPIOA的时钟  ---  AHB1

        //配置PA9和PA10位复用模式

        //配置复用关系(复用功能寄存器)

        //打开USART1时钟  ---  APB2

        //初始化USART1

        //CR1

        //CR2

        //利用公式计算DIV_M、DIV_F

        //将DIV_M、DIV_F写入BRR寄存器

        //使能USART1

}

4.6.2 printf重定向方法

printf  --->  fputc   --->    stdio.h

printf(“hello world”);

步骤:

①包含#include “stdio.h”,点击编译

②Ctrl键 + F进入搜索替换工具

        

 ③找到fputc函数的外部声明

④调用fputc函数进行修改

注意:STM32中printf换行需要”\r\n”

4.6.3 代码设计

usart.c

#include "usart1.h"

/*
函数功能:USART1初始化
返回值:void
形参:u32 bps	波特率
作者:jerry
版本:1.0
函数说明:
USART1_TX   ---  PA9  --- 复用模式
USART1_RX   ---  PA10  --- 复用模式

低位寄存器:GPIOA->AFR[0]
高位寄存器:GPIOA->AFR[1]
*/

void Usart1_Init(u32 bps)
{
	
	float USARTDIV = 0;
	u32 DIV_M ,DIV_F;
	
	//1、打开GPIOA、USART1时钟
	RCC->AHB1ENR |= (1 << 0);
	RCC->APB2ENR |= (1 << 4);//打开USART1时钟
	//2、PA9、PA10初始化
	GPIOA->MODER &=~(0xf << 18);//清零
	GPIOA->MODER |= (0xa << 18);//将PA9和PA10配置为复用模式
	//3、配置复用关系(IO映射)
	GPIOA->AFR[1] |= 7 << 4;	//将PA9复用到USART1
	GPIOA->AFR[1] |= 7 << 8;	//将PA10复用到USART1
	//4、USART1初始化
	USART1->CR1 &=~ (1 << 15);	//16倍过采样:OVER8 = 0
	USART1->CR1 &=~ (1 << 12);	//数据长度为8bit
	USART1->CR1 |= (1 << 3);	//发送器使能
	USART1->CR1 |= (1 << 2);	//接收器使能
	
	USART1->CR2 &=~(3 << 12);	//停止位为1bit
	//5、计算波特率
	USARTDIV = 84000000 / 16.0 / bps;
	DIV_M = (u32)USARTDIV;			//整数部分
	DIV_F = (USARTDIV-DIV_M) * 16;	//小数部分
	USART1->BRR |= DIV_M << 4 | DIV_F;	//设置BRR寄存器
	
	//6、使能接收中断和空闲中断
	USART1->CR1 |= (1 << 5);	//使能接收中断	RXNE
	USART1->CR1 |= (1 << 4);	//空闲接收中断	IDLE
	
	//7、配置NVIC 
	//计算编码值		占先:1		次级:1
	u32 pri=NVIC_EncodePriority (5, 1, 1);
	//设置优先级
	NVIC_SetPriority(USART1_IRQn, pri);
	//使能中断源
	NVIC_EnableIRQ(USART1_IRQn);

	//使能USART1
	USART1->CR1 |= (1 << 13);	//使能USART1
}

/*
函数功能:USART1发送1byte数据函数
返回值:void
形参:u8 data 发送1byte数据
作者:jerry
版本:1.0
函数说明:
①等待数据可以发送 --- 标志位(SR寄存器)等待1
②发送数据
*/

void usart1_send_byte(u8 data)
{
	//①等待数据可以发送 --- 标志位(SR寄存器)等待1
	while(!(USART1->SR & (1 << 7)));
	//②发送数据
	USART1->DR = data;
}

/*
函数功能:USART1接收1byte数据函数
返回值:u8	接收到的1byte数据
形参:void
作者:jerry
版本:1.0
函数说明:
①等待数据可以接收 --- 接收到数据后置一
②接收数据
*/
u8 usart1_rec_byte(void)
{
	//①等待数据可以接收 --- 接收到数据后置一
	while(!(USART1->SR & 1 << 5));//没有接收到数据时等待(0),接收到数据后跳出(1)
	//②接收数据
	return USART1->DR;
}

/*
	printf重定向		printf("1234567");	--->	XCOM
	注意:printf重定向函数,不需要声明和调用
*/
int fputc(int c, FILE * stream)
{
	usart1_send_byte(c);
	return c;
}

usart.h

#ifndef _USART1_H
#define _USART1_H



#include "stm32f4xx.h"
#include "stdio.h"





void Usart1_Init(u32 bps);
void usart1_send_byte(u8 data);
u8 usart1_rec_byte(void);

#endif

以上就是我对USAT的一点拙见,由于我现在用的板子是STM32F407VET6,所以后面的代码和图片都是基于这块板子的。后面会继续更新相关我的STM32的学习之路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值