stm32-Usart实验详解

写在最前

​ 本文为个人学习Stm32所做笔记,实验环境为正点原子Stm32zet6精英板。在学习时在想,既然正点原子使用中断来实现实验功能,那么怎么不用中断来实现同样的功能,想想应该不难,本文代码均采用固件库编写,并且没有使用中断来实现功能,详细解析在最后。

一、串行通信与并行通信的概念

  • 串行通信

    概念:通信时,通信双方仅仅只有一根数据线,在数据线上,每个时刻仅能传送一位数据,也就是说数据在数据线上一位一位的传送。

    优点:因为通信双方仅占用一根数据线,因此节约端口引脚

    缺点:传输速度慢

  • 并行通信

    概念:通信时,通信双方采用多根数据线进行通信,每个时刻可以传送多位数据。

    优点:传输速度快

    缺点:通信双方采用多根数据线进行数据传输,占用引脚资源多

  • 串行通信又可分为单工、半双工、全双工通信

    单工:数据传输仅仅只能朝一个方向进行

    半双工:数据传输可以双向进行,但同一时刻仅仅只能接收数据或者发送数据,接收数据和发送数据不能同时进行

    全双工:数据传输可以双向进行,并且接收数据和发送数据可以同时进行(两根数据线,一根只负责发,另一根只负责收)

二、同步通信和异步通信

​ 串行通信的通信方式还包括同步通信和异步通信两种:

  • 同步通信:通信双方带时钟同步信号传输,常见同步串行通信方式有SPI、I2C

  • 异步通信:通信双方不带同步时钟信号,是单总线形式,通信双方约定相同波特率来保证数据传输和接收的有效性;常见的异步串行通信方式有Uart、Usart.

    波特率:每秒钟传输多少个码元,一个码元可以是一个比特位,也可以是多个比特位

    Uart:全双工通用异步收发器

    Usart:全双工通用同步异步收发器
    请添加图片描述

三、Stm32-Usart框图

​ 数据接收和发送时分别涉及接收/发送数据寄存器、接收/发送移位寄存器,数据发送时,数据先写入发送数据寄存器,然后经发送移位寄存器传送至TX口;接收数据时,数据经RX口到接收移位寄存器,然后到接收数据寄存器,至此,数据可读。

​ 当有数据可读时,也就是有数据发送来时,状态寄存器SR对应的位会置位,标识有数据可读,用户可以从接收数据寄存器中读数据。发数据同理。
请添加图片描述

​ 注:摘自stm32中文参考手册

四、Usart串口通信实验

4.1 实验思路

​ 正点原子Stm32zet6精英板中,PA9和PA10复用为Usart1,PA9为发送端,PA10为接收端,即

PA9 – USART1_TX

PA10 – USART1_RX

同时,PA9和PA10连接到RS232转换器转换为USB接口,通过CH340虚拟为串口,在PC上安装CH340即可使用该USB串口,实际上是使用的PA9和PA10,也就是USART1。

4.2 USART1初始化

​ 串口初始化,由于将PA9和PA10复用为USART1,而PA9对应的是发送端,PA10对用的是接收端,因此需要配置PA9为复用推挽输出方式,PA10配置为浮空输入方式:

  1. 使能GPIOA和USART1的时钟
  2. 配置PA9为复用推挽输出模式,PA10为输入浮空模式
  3. 配置串口信息,波特率、数据位、停止位、奇偶校验位、硬件流控制、发送和接收使能
  4. 使能串口
/*用到的头文件*/
#include "stm32f10x_gpio.h" //GPIO相关宏定义,结构体声明
#include "stm32f10x_rcc.h" //时钟相关函数声明
#include "stm32f10x_usart.h" //串口相关宏定义、结构体声明和函数声明

/*
* USART1 --> PA9 -- TX, PA10 -- RX
*/
void usart_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef Usart_InitStructure;
	
	/*使能GPIOA和USART1的时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	/*配置PA9为推挽复用输出*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//推挽复用输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/*配置PA10为浮空输入*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	/*配置串口信息 -- 波特率,停止位,数据位等*/
	Usart_InitStructure.USART_BaudRate = 115200;//波特率115200
	Usart_InitStructure.USART_WordLength = USART_WordLength_8b;//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_Init(USART1, &Usart_InitStructure);
	
	/*使能串口*/
	USART_Cmd(USART1, ENABLE);
}

4.3 USART使用

​ 实现功能:判断是否有数据发送过来,若有数据过来,便将接收到的数据回传回去

​ USART_GetFlagStatus()函数讲解:

​ 通过查看函数源码以及Stm32中文参考手册,通过传入该函数的入口参数来判断CR寄存器对应的那些位置1,此处需要监测的是是否有数据可读,因此传入USART_FLAG_RXNE,此为宏定义,其值为0x00000020,通过阅读该函数源码发现,若是CR寄存器的第五位置1,该函数返回1,否则返回0,而CR寄存器的第5位 置1 表示有读数据寄存器有数据可读,置0 表示读数据寄存器无数据可读。

int main()
{
	uint16_t recvData = 0;
	
	usart_init();
	
	while(1)
	{
		/*判断是否收到数据,即读数据寄存器是否非空*/
		if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE))
		{
			recvData = USART_ReceiveData(USART1);
			USART_SendData(USART1, recvData);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昌昌.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值