目录
参考资料:
战舰/精英STM32F1开发板
《STM32F1开发指南-库函数版本》-5.3 usart串口文件夹介绍 & 第9章 串口实验
STM32F1xx官方资料:
《STM32中文参考手册V10》-第25章通用同步异步收发器(USART)
1. 串口通信原理讲解
1.1 串行通信接口背景知识
1.1.1 处理器与外部设备通信的两种方式
1.并行通信:
传输原理:数据各个位同时传输
优点:速度快
缺点:占用引脚资源多
2.串行通信:
传输原理:数据按位顺序传输
优点:占用引脚资源少
缺点:速度相对较慢
1.1.2 串行通信
1.按照数据传送方向,分为:
单工:数据传输只支持数据在一个方向上传输。
半双工:允许数据在两个方向上传输,但是在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信。
全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。
2.串行通信三种传送方式:
3.串行通信的通信方式:
同步通信:带时钟同步信号传输。-SPI,IIC通信接口
异步通信:不带时钟同步信号》-UART(通用异步收发器),单总线
4.常见的串行通信接口:
5.STM32的串口通信接口:
UART:通用异步收发器
UASRT:通用同步异步收发器
6.UART异步通信方式引脚连接方法:
7.UART异步通信方式引脚:
详情:STM32F103ZET6.pdf
8.UART异步通信方式特点:
● 全双工异步通信
● 分数波特率发生器系统,提供精确的波特率 ─ 发送和接收共用的可编程波特率,最高达4.5Mbits/s
● 可编程数据字长度(8位或9位)
● 可配置的停止位-支持1或2个停止位
● 可配置的使用DMA的多缓冲器通信
● 单独的发送器和接收器使能位
● 检测标志: 接收缓冲器 、发送缓冲器空、传输结束标志
● 多个带标志的中断源,触发中断
● 其他:校验控制,四个错误检测标志
9.串行通信过程:
1.2 STM32F1串口通信基础
1.2.1 STM32串口异步通信需要定义的参数
通信双方设置需相同
1.起始位
2.数据位(8位或9位)
3.奇偶校验位(第9位)
4.停止位(1,15,2位)
5.波特率设置
2. STM32串口寄存器库函数配置方法_串口通信实例
2.1 STM32串口常用寄存器和库函数
2.1.1 常用的串口相关寄存器
USART_SR状态寄存器
USART_DR数据寄存器
USART_BRR波特率寄存器
2.1.2 波特率计算方法
2.1.3 串口操作相关库函数(省略入口参数)
2.2 串口配置方法(手把手写简单的通信实例)
2.2.1 串口配置的一般步骤
1.串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
2.串口复位:USART_DeInit();这一步不是必须的
3.GPIO端口模式设置:GPIO_Init();
模式设置,详情见 STM32中文参考手册.pdf 8.1.11 表21 USART
4.串口参数初始化:USART_Init();
5.开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤):
NVIC_Init();
USART_ITConfig();
6.使能串口:USART_Cmd();
7.编写中断处理函数:USARTx_IRQHandler();
8.串口数据收发:
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接收数据,从DR读取接收到的数据
9.串口传输状态获取:
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx,unit16_t USART_FLAG);
void USART_ClearlTPendingBit(USART_TypeDef* USARTx,unit16_t USART_IT);
2.2.2 代码及注释
usart.c
#include "usart.h"
#include "stm32f10x.h"
#include "stm32f10x_usart.h"
GPIO_InitTypeDef GPIO_InitStruct;//定义GPIO指针
USART_InitTypeDef USART_InitStruct;//定义串口指针
NVIC_InitTypeDef NVIC_InitStruct;//定义中断指针
void My_USART1_Init(void)//初始化函数 无第2步
{
//第1步
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能串口1时钟
//第3步
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//输出口设置成推挽复用,见表21
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;//PA9是输出口
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//速度随意
GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化PA9
//第3步
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//输入口设置成浮空输入,见表21
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;//PA10是输入口
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;//速度随意
GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化PA10
//第4步
USART_InitStruct.USART_BaudRate=115200;//波特率
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不使用硬件流
USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//发送和接收都要,全双工
USART_InitStruct.USART_Parity=USART_Parity_No;//不使用奇偶校验,通信双方要么都使用,要么都不使用
USART_InitStruct.USART_StopBits=USART_StopBits_1;//一个停止位
USART_InitStruct.USART_WordLength=USART_WordLength_8b;//字长设为8
USART_Init(USART1,&USART_InitStruct);//初始化串口1
//第6步
USART_Cmd(USART1,ENABLE);//串口使能函数,使能串口1
//第5步
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//打开接收中断,RXNE接收
//第5步
NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;//设置中断通道:串口1
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//开启中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//设置抢占优先级1
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//设置子优先级1
NVIC_Init(&NVIC_InitStruct);//初始化中断
}
//第7步
void USART1_IRQHandler(void)//中断服务函数
{
int res;//定义一个变量
if(USART_GetITStatus(USART1,USART_IT_RXNE))//判断优先级
{
//第8步
res=USART_ReceiveData(USART1);//读取串口1接收到的数据,赋值给res
USART_SendData(USART1,res);//发送数据,两个参数:串口1、变量(数据)
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
usart.h
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
//extern int res; //全局变量
void My_USART1_Init(void);
void USART1_IRQHandler(void);
#endif