串口通信

基本原理

处理器与外部设备的两种通信方法

  • 并行通信
    原理——数据各个位同时传输
    速度块,但占用引脚资源多
  • 串行通信
    原理——数据按位顺序传输
    占用引脚资源少,但速度较慢

串行通信

按数据传送方向分类

  • 单工
    数据传输只支持数据在一个方向上传输
    串口通信

  • 半双工
    允许数据在两个方向上传输,但同一时间只能有一个方向的传输
    是一种切换方向的单工通信串口通信

  • 全双工
    允许同时在两个方向上传输数据
    是两个单工通信方式的结合,要求发送和接收设备都有独立的接收和发送能力
    串口通信

通信方式

  • 同步通信
    带时钟同步信号的传输

  • 异步通信
    不带时钟同步信号的传输
    通信双方必须约定好波特率(传输的速率)

串行通信接口

串口通信

串口异步通信需要定义的参数

  • 起始位
  • 数据位
  • 奇偶校验位
  • 停止位
  • 波特率设置
    串口通信

串口相关寄存器

串口通信操作

串口设置步骤

  1. 串口时钟使能,GPIO 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  1. 串口复位
USART_DeInit(USART1);
  1. GPIO 端口模式设置
GPIO_Init(GPIOA,&GPIO_InitStrue);//输入输出模式从技术收车查
  1. 串口参数初始化
USART_Init(USART1,&USART_InitStrue);
  1. 开启中断并初始化 NVIC (需要中断时)
USART_ITConfig (USART1,USART_IT_RXNE,ENABLE);
NVIC_Init (&NVIC_InitStrue);
  1. 使能串口
USART_Cmd(USART1,ENABLE);
  1. 编写中断函数(需要中断时)
void USART1_IRQHandler(void)
  1. 串口数据收发
u8 ree;
ree = USART_ReceiveData;
USART_SendData(USART1,ree );
  1. 串口传输状态获取
USART_GetITStatus(USART1,USART_IT_RXNE)

串口有关函数

(位于stm32f10x_usart.h 和 stm32f10x_usart.c 文件)

  • 使能串口时钟

RCC—reset clock controller ——复位与时钟控制器
APB2——RXD TXD 位于 APB2 总线的PA9 和 PA10 上
periph ——周围的,末梢

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1);
  • 串口复位
    外设出现异常时,可以通过复位设置,实现该外设的复位,然后重新配置外设,使其重新工作
    一般在系统刚开始配置外设时,复位外设

deinit——反初始化函数
把已经初始化的外设,,变回未初始化的状态
效果与 init 相反

void USART_DeInit(USART_TypeDef* USARTx);//串口复位

例——复位串口1

USART_DeInit(USART1);
  1. 串口参数初始化
void USART_Init(USART_TypeDef*USARTx,USART_InitTypeDef* USART_InitStruct);

两个参数
1)指定初始化的串口
2)含有初始化该串口需要参数的结构体指针

其成员变量

USART_InitStructure.USART_BaudRate = bound; //波特率;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_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); //初始化串口

baud——波特——数据通信速度的表示单位
parity——奇偶校验位——传输和储存的数据中的增加的额外一位——校验错误

需要初始化的参数
波特率,字长,停止位,奇偶校验位,硬件数据流控制,收发模式

  1. 数据接收与发送

接受函数

uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

读取 USART_DR 寄存器接收的数据

发送函数

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

向 USART_DR 写入一个数据

接收和发送时通过 USART_DR(数据寄存器)来实现
该寄存器含有 TDR 和 RDR 两个寄存器
向该寄存器写数据,串口会自动发送
接收的数据,存于该寄存器内

  1. 串口状态

利用 USART_SR (状态寄存器)读取

读取串口状态函数

FlagStatus USART_GetFlagStatus(USART_TypeDef*USARTx, uint16_t USART_FLAG);

flag——旗帜
status——状态
两个参数
1)要读取的串口
2)判断寄存器状态
RXNE——接受缓冲器非空
TC——发送完成


判断是否非空

USART_GetFlagStatus(USART1, USART_FLAG_RXNE);

判断是否发送完成

USART_GetFlagStatus(USART1, USART_FLAG_TC);

在 FLAG 后加了假设的词,通过返回值,判断情况

  1. 串口使能
USART_Cmd(USART1, ENABLE);

enable——可以,使能

  1. 开启串口响应中断

使能串口中断的函数

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)

config——配置

两个参数
1)确定使能的串口
2)标志使能串口的类型
串口的中断类型有很多,需要选择使能的中断类型


当即接收到数据时(REXN √),要产生中断

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断,接收到数据中断

当发送数据结束后(TC √),要产生中断

USART_ITConfig(USART1,USART_IT_TC,ENABLE);//开启中断,当发送结束后中断
  1. 获取相应中断状态
    当使能了某个中断后,该中断发生了,就会设置状态寄存器中的某个标志位

判断中断是哪种中断使用的函数

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)

两个参数
1)要获取的串口
2)判断那种中断


使能了串口发送完成的中断(TC),如果中断发生了
在中断处理函数中调用该函数,判断是否串口发送完成中断

USART_GetITStatus(USART1, USART_IT_TC)

如果返回 set 则中断发生

代码

#include "stm32f10x.h"

void My_USART1_Init()//用来设置的函数,避免main函数太杂乱
{
	GPIO_InitTypeDef GPIO_InitStrue;//定义一个含初始化参数的结构体
	USART_InitTypeDef USART_InitStrue;//定义一个含有初始化该串口所需要参数的结构体
	NVIC_InitTypeDef NVIC_InitStrue;//定义一含有设置中断的参数的指针
	/*结构体的定义一定要放在最前面,各区域理清后要把结构体的定义挪到最开始*/
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能GPIOA的时钟
	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能串口的时钟
	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;//输入输出模式要去技术手册查询
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_InitStrue);
	
	GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_InitStrue);
	/*PA9和PA10初始化完成*/
	
	/*初始化串口,电脑要和下面的参数匹配*/
	
	USART_InitStrue.USART_BaudRate=115200;//只要通信双方波特率一致就可以
	USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStrue.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//mode收发模式,在这里设置发送和接收都使能
	USART_InitStrue.USART_Parity=USART_Parity_No;
	USART_InitStrue.USART_StopBits=USART_StopBits_1;
	USART_InitStrue.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStrue);//初始化完成√
	
	USART_Cmd(USART1,ENABLE);//使能串口1
	
	USART_ITConfig (USART1,USART_IT_RXNE,ENABLE);//打开接收中断,接收到数据就会开启中断服务
	/*因为使用了中断,要进行中断优先级的设置*/
	NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;//
	NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE ;
	NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;
	NVIC_Init (&NVIC_InitStrue);
}

void USART1_IRQHandler(void)//设置中断服务函数//因为在usart文件中也定义了同名的函数,此时要删除该文件夹
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE))
		{
			u8 ree;
			ree = USART_ReceiveData;//接收数据
			USART_SendData(USART1,ree );//发送数据
		}
}
int main()
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//在主函数内第一个调用中断函数
	My_USART1_Init();//调用设置的配置函数
	while(1);//初始化后保持主函一直数等待中断
}

编译烧录

上一篇:Linux shell脚本的字符串截取


下一篇:【STM32】使用DHT11温湿度传感器