串口通信:
1、串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。
2、单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力

串口参数及时序
在这里插入图片描述
波特率决定了每隔多少秒发送一位数据。
校验可以选择三种方式:无校验位,奇校验位,偶校验位(判断发送数据出现1次数,例如如果选择偶校验,发送一个字节,如果数据为0000 0111,这时校验位要补1)
(本节展示串口收发的功能,通常使用波特率为9600,8位数据位,即无校验位,停止位长度为1的时序。)

USART简介:
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步 / 异步收发器
USART 是 STM32 内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序(及转化为协议规定的波形发送出去),从 TX 引脚发送出去,也可自动接收 RX 引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
自带波特率发生器,最高达 4.5Mbits/s
可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
可选校验位(无校验 / 奇校验 / 偶校验)
支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN
STM32F103C8T6 USART资源:USART1、USART2、USART3(USART1是APB2总线的设备,剩下的是APB1的设备)

USART基本结构:
在这里插入图片描述
初始化模板:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
//把PA9配置为复用推挽输出,供USART的TX使用
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
//初始化PA10引脚
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//可选浮空或上拉输入
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
 
//初始化USART 9600波特率 无流控 无校验 8位字长 1位停止位 选择发送和接收模式
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate=9600;//波特率
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制
USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//串口模式,同时开启接收和发送
USART_InitStructure.USART_Parity=USART_Parity_No;//校验位选择无校验
USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位长度
USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长选择8位
USART_Init(USART1,&USART_InitStructure);
	
//开启RXNE标志位到NVIC的输出
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
//优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
	
USART_Cmd(USART1,ENABLE);
代码为CSDN博主「sakabu」的
原文链接:https://blog.csdn.net/sakabu/article/details/135857053

在这里插入图片描述

由图可见USART1的TX和RX分别对应PA9和PA10引脚,初始化PA9时要配置成复用推挽输出模式。
关于USART的结构体参数USART_Mode,需要接收或发送的哪一个功能就选哪一个,两个都要就用“|”操作或起来。

接受一个数据方法:
方法一:查询
在主函数里不断判断RXNE标志位,如果置1了,就说明收到数据了,那再调用ReceiveData,读取DR寄存器就行了。
在这里插入图片描述
在这里插入图片描述
这里说明读完DR寄存器,会自动帮我们清楚标志位,无需再手动清除标志位。

这里与发送数据同理,也是等待发送寄存器TXE标志位置1,说明已经发送一个数据,就可以继续发送数据,避免数据覆盖
在这里插入图片描述
发送一个数据代码示例:

void Serial_SendByte(uint8_t Byte)
{
	USART_SendData(USART1,Byte);
	while(USART_GetFlagStatus (USART1 ,USART_FLAG_TXE)==RESET );	//等待标志位为1
}

方法二:
模板里使用中断触发来接收数据,首先开启RXNE到中断的通道,用USART_ITConfig函数,再配置NVIC优先级分组等参数;
中断函数示例:

void USART1_IRQHandler(void)	//中断入口函数
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE))		//读取中断标志位
	{
	//进入中断进行的操作
		Serial_RXData=USART_ReceiveData(USART1);
		Serial_RXFlag=1;
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}

(注意如果你读取了DR数据寄存器,它会自动帮你清楚标志位,如果没有读取需要手动清除)

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐