STM32学习笔记7(串口通信)

一、简介

1、电平标准 

2、串口参数及时序 

        串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口。它由起始位、数据位、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据。
起始位: 标志一个数据帧的开始,固定为低电平。

数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行,8 位或 9 位数据。

校验位:用于数据验证。

停止位:用于数据帧间隔,可由0.5、 1、 1.5或2个高电平表示。

二、STM32的USART

        USART通用同步异步收发器,是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。UART只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART。

1、USART功能框图 

功能引脚 

 数据寄存器 

        USART 数据寄存器(USART_DR)只有低 9 位有效,并且第 9 位数据是否有效要取决USART 控制寄存器 1(USART_CR1)的 M 位设置,当 M 位为 0 时表示 8 位数据字长,当 M位为 1 表示 9 位数据字长,我们一般使用 8 位数据字长。 

控制器 

        使用 USART 之前需要向 USART_CR1 寄存器的 UE 位置 1 使能 USART, UE 位用来开启供给给串口的时钟。发送或者接收数据字长可选 8 位或 9 位,由 USART_CR1 的 M 位控制

发送器: 

        当 USART_CR1 寄存器的发送使能位 TE 置 1 时,启动数据发送。停止位时间长短是可以通过 USART 控制寄存器 2(USART_CR2)的 STOP[1:0]位控制。当发送使能位 TE 置 1 之后,发送器开始会先发送一个空闲帧(一个数据帧长度的高平),接下来就可以往 USART_DR 寄存器写入要发送的数据。在写入最后一个数据后,需要等待 USART 状态寄存器(USART_SR)的 TC 位为 1,表示数据传输完成,如果USART_CR1 寄存器的 TCIE 位置 1,将产生中断。

接收器: 

        如果将 USART_CR1 寄存器的 RE 位置 1,使能 USART 接收,使得接收器在 RX 线开始搜索起始位。在确定到起始位后就根据 RX 线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器数据移到 RDR 内,并把 USART_SR 寄存器的 RXNE 位置1,同时如果 USART_CR2 寄存器的 RXNEIE 置 1 的话可以产生中断。

小数波特率生成 

        USART波特率与比特率相等,波特率越大,传输速率越快。USART 的发送器和接收器使用相同的波特率。

波特率计算: 

        fPLCK 为 USART 时钟, USARTDIV 是一个存放在波特率寄存器(USART_BRR)的一个无符号定点 数。USART1 使用 APB2 总线时钟,最高可达 72MHz,其他 USART 的最高频率为36MHz。

        USARTDIV 是一个存放在波特率寄存器(USART_BRR)的 一 个 无符 号 定点 数。 其中DIV_Mantissa[11:0] 位 定义 USARTDIV 的 整 数 部分 ,DIV_Fraction[3:0]位定义 USARTDIV 的小数部分。

校验控制

        当使用校验位时,串口传输的长度将是 8 位的数据帧加上 1 位的校验位总共 9 位,此时 USART_CR1 寄存器的 M 位需要设置为1,即 9 数据位。将 USART_CR1 寄存器的 PCE 位置 1 就可以启动奇偶校验控制,接收数据时如果出现奇偶校验位验证失败,会将 USART_SR 寄存器
的 PE 位置 1,并可以产生奇偶校验中断。

中断控制

三、USART 初始化结构体

1) USART_BaudRate:波特率设置。一般设置为 2400、 9600、 19200、 115200。标准库函数        会根据设定值计算得到 USARTDIV值,从而设置 USART_BRR 寄存器值。
2) USART_WordLength:数据帧字长,可选 8位或 9位。它设定 USART_CR1寄存器的 M 位的        值。如果没有使能奇偶校验控制,一般使用 8 数据位;如果使能了奇偶校验则一般设置为 9 数      据位。
3) USART_StopBits:停止位设置,可选 0.5 个、 1 个、 1.5 个和 2 个停止位,它设定                    USART_CR2 寄存器的 STOP[1:0]位的值,一般我们选择 1 个停止位。
4) USART_Parity : 奇 偶 校 验 控 制 选 择 。它 设 定USART_CR1 寄存器的 PCE 位和 PS 位的      值。
5) USART_Mode: USART模式选择,有 USART_Mode_Rx和 USART_Mode_Tx,允许使用逻        辑或运算选择两个,它设定 USART_CR1 寄存器的 RE 位和 TE 位

 四、USART 代码编程 

编程步骤: 

1) 使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟;
2) 初始化 GPIO,并将 GPIO 复用到 USART 上;
3) 配置 USART 参数;
4) 配置中断控制器并使能 USART 接收中断;
5) 使能 USART;
6) 在 USART 接收中断服务函数实现数据接收和发送。 

1、发送数据 

void USART_Config(void)
{
	USART_InitTypeDef  USART_InitStructure;
	GPIO_InitTypeDef   GPIO_InitStructure;
	
    //开启USART和GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
    //GPIO端口配置(发送端口PA9)
	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);
	
    //USART端口配置
	USART_InitStructure.USART_BaudRate=115200;
	USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode=USART_Mode_Tx;
	USART_InitStructure.USART_Parity=USART_Parity_No;
	USART_InitStructure.USART_StopBits=USART_StopBits_1;
	USART_InitStructure.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStructure);

    //USART端口使能
	USART_Cmd(USART1, ENABLE);
}

//发送一位数据
void Usart_SendByte(uint16_t Byte)
{
	USART_SendData(USART1, Byte);
	
    //等待数据寄存器中的数据移动到移位寄存器中   USART_SR 位7 TXE
    //0:数据还没被转移到移位寄存器
    //1:数据已经被转移到移位寄存器
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

//发送数组
void USART_SendArray(uint8_t *Array,uint16_t Length)
{
	uint16_t i;
	for(i=0;i<Length;i++)
	{
		Usart_SendByte(Array[i]);
	}
}

//发送字符串
void USART_SendString(uint8_t *str)
{
	uint8_t i;
	
	for(i=0;str[i]!='\0';i++)
	{
		Usart_SendByte(str[i]);
	}
}

2、printf与scanf重定向 

在 bsp_usart.c文件中加#include<stdio.h>

int fputc(int ch,FILE *f)
{
	Usart_SendByte(ch);
	return ch;
}
int fgetc(FILE* f)
{
	//等待串口输入数据
	while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_RXNE)==RESET);
	
	return (int)USART_ReceiveData(DEBUG_USARTx);
}

3 、接收数据并发送

void USART_Config(void)
{
	USART_InitTypeDef  USART_InitStructure;
	GPIO_InitTypeDef   GPIO_InitStructure;
	NVIC_InitTypeDef   NVIC_InitStructure;
	
    //开启USART和GPIO时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	//GPIO发送端口PA9配置为推挽复用模式
	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);
	
	//GPIO接收端口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_InitStructure.USART_BaudRate=115200;
	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;
	USART_Init(USART1,&USART_InitStructure);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	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_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	//使能串口
	USART_Cmd(USART1, ENABLE);
}

//中断函数
void USART1_IRQHandler(void)
{
	uint8_t ucTemp;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
	{		
		ucTemp = USART_ReceiveData(USART1);
		USART_SendData(USART1,ucTemp);    
	}	 
}







 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值