首页 > 其他分享 >STM32笔记(10)——USART

STM32笔记(10)——USART

时间:2024-09-01 13:24:36浏览次数:11  
标签:10 USART NVIC STM32 Mode InitStruct GPIO USART1

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

USART结构框图:

 

基本简化结构: 

若TDR数据转移至移位寄存器中,则会置TXE标志位 

若移位寄存器中数据转移至RDR中,则会置RXNE标志位 

数据: 

 

起始位:标志一个数据帧的开始,固定为低电平

数据位:1为高,0为低,LSB(从最低位开始传输) 

停止位:标志一个数据帧的结束,固定为高电平

检验位:奇校验 偶校验 无校验

 一帧分为10位或11位,10位下默认无检验位,11位下有检验位,停止位决定连发间隔(0.5/1/1.5/2)位,一般选择1位

数据监测:

一帧数据,分位16倍波特率采样,7 8 9位为中央进行数据采样,若采样位有2个0,则会置NE标志位, 进行噪声提醒

波特率计算公式:

                              波特率 = fPCLK2/1 / (16 * DIV)

数据模式: 

若要传输连续分割性数据则可以利用数据包进行传输 

 

   利用状态机进行检测 

配置流程: 

RCC→GPIO→USART→USART_IT→NVIC→运行控制(cmd)(若只需要发送功能可以不用配置中断)

初始化例程: 

#include "stm32f10x.h"                  // Device header

uint16_t num,flag;
void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate=9600;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStruct.USART_Parity=USART_Parity_No;
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStruct);
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel= USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct);
	
	USART_Cmd(USART1,ENABLE);
	
}

void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
	{
		num=USART_ReceiveData(USART1);
		flag=1;
	  USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}

void Send_Byte(uint16_t i)
{
	USART_SendData(USART1,i);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

数据包例程 :

#include "stm32f10x.h"                  // Device header

uint8_t RXpacket[4];
uint8_t TXpacket[4];
uint16_t RXStatus,RXflag;
uint16_t pointer;
void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate=9600;
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	USART_InitStruct.USART_Parity=USART_Parity_No;
	USART_InitStruct.USART_StopBits=USART_StopBits_1;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART1,&USART_InitStruct);
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct);
	
	USART_Cmd(USART1,ENABLE);
}

void Send_Byte(uint8_t data)
{
	USART_SendData(USART1,data);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}


void Send_Array(uint8_t *Array, uint16_t Length)
{
	uint16_t i;
	for (i = 0; i < Length; i ++)		
	{
		Send_Byte(Array[i]);		
	}
}

void Send_TXpacket(void)		//FF __  __  __  __ FE FF为包头,FE为包尾
{
	Send_Byte(0xFF);
	Send_Array(TXpacket,4);
	Send_Byte(0xFE);
}


void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
	{
		if(RXStatus==0)
		{
			if(USART_ReceiveData(USART1)==0XFF)
				RXStatus=1;
		}
		else if(RXStatus==1)
		{
			RXpacket[pointer]=USART_ReceiveData(USART1);
			pointer++;
			if(pointer>=4)
			{
				pointer=0;
				RXStatus=2;
			}	
		}
		else if(RXStatus==2)
		{
			if(USART_ReceiveData(USART1)==0XFE)
			{
				RXStatus=0;
				RXflag=1;
			}
		}
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}

标签:10,USART,NVIC,STM32,Mode,InitStruct,GPIO,USART1
From: https://blog.csdn.net/2301_80055728/article/details/141759097

相关文章

  • 人工智能100个AI术语
    你好,我是三桥君人工智能(AI)技术的快速发展正深刻地改变着我们的世界。作为产品经理,深入了解并掌握AI的最新动态与技术是保持竞争力的关键。然而,对于多数人而言,涉猎专业的AI知识并非易事。鉴于此,我萌生了推动这一学习过程的想法。为此,三桥君整理了一套包含100个AI术语的资料......
  • STM32硬件篇:W25Q64
    W25Q64简介W25Qxx系列是一种低成本、小型化、使用简单(使用SPI通信协议)的非易失性(掉电不丢失)存储器,常用于数据存储、字库存储、固件程序存储等场景。【注意】W25Qxx芯片只支持SPI的模式0和模式3。存储介质:NorFlash(闪存)时钟频率:80MHz/160MHz(DualSPI)/320MHz(QuadSPI)------......
  • P10958 启示录 解题报告
    更好的阅读体验用记忆化搜索写数位dp真的很好写!题目传送门题目大意:\(T\)组数据,每次询问第\(x\)个含有至少\(3\)个连续\(6\)的数是什么。思路:考虑数位dp。一般数位dp问题有两种常见形式:询问\([l,r]\)内有多少个符合条件的数;询问满足条件的第\(k\)大(小)的......
  • Window10:开启snmp
    控制面板 ->程序->启用或关闭Windows功能打开发现找不到"简单网络管理协议(SNMP)"如果能看到,勾选保存即可,否则进行如下步骤处理以管理员身份启动powershell获取SNMPSERVICE全名Get-WindowsCapability-Online-Name"SNMP*"当前状态是:NotPresent --翻译为不存在......
  • 对称二叉树-101
    题目描述给你一个二叉树的根节点root,检查它是否轴对称。解题思路这里我们相当于是比较根节点左右两颗子树,我们依次向左右子树的左右两个方向进行遍历,我们比较左子树的左孩子和右子树的右孩子,左子树的右孩子和右子树的左孩子,这里如果不好理解可以看下面这个图片,如果两个子节......
  • STM32的寄存器详解
    目录前言一、 STM32单片机寄存器概述1.寄存器的作用2.寄存器的分类二、STM32内核寄存器1.程序计数器(PC)2.堆栈指针(SP)3.链接寄存器(LR)4.控制寄存器(CONTROL)三、STM32外设寄存器1.GPIO寄存器2.USART寄存器3.TIM定时器寄存器4.ADC寄存器四、寄存器的访问方式......
  • 题解:洛谷 P10996 【MX-J3-T3】Tuple
    原题链接介绍一种(也许是正解的)卡常做法先说总体思路:对于每个三元组\((x,y,z)\),若有一个\(w\)满足\((x,y,w),(x,z,w),(y,z,w)\)均存在,则找到了一个合法的四元组\((x,y,z,w)\)。\(20\\rm{Pts}\)做法如果暴力搜索,在遍历每一个三元组时,每一次都扫描所有的\(w\in[1,N]\)......
  • 题解:洛谷 P10497 [USACO03Open] Lost Cows
    原题链接思路+算法首先,考虑读入到\(a_i\)时,如果要得到此时的最优解(指所有牛的编号不重不漏地覆盖\([1,i]\)的所有编号),对于第\(i\)头奶牛,因为在它前面有\(a_i\)头奶牛的编号小于它,所以第\(i\)头奶牛的编号应当为\(a_i+1\)。如果有一头新的奶牛\(i+1\)加入到这个......
  • 题解:洛谷 P10878 [JRKSJ R9] 在相思树下 III
    原题链接解析在操作一时,最小值如果在最后一位,其无法更新任何数,会被删除;否则不在最后一位时一定会被其右侧更大的数更新。所以在操作一时,最小值一定会被更新掉。同理,在操作二时,最大值一定会被更新掉。由此,操作一决定了答案的下限,操作二决定了答案的上限。所以可以得出贪心策略......
  • CUDA教程之 10 掌握 CUDA 矩阵乘法:共享内存、Tile 内存合并和 Bank 冲突简介(教程含源
    介绍在使用CUDA进行GPU编程的世界中,优化性能是关键。实现此目标的最强大技术之一是使用共享内存。本博客将引导您完成使用共享内存执行矩阵乘法的CUDA程序,特别关注理解分块内存合并和存储体冲突。在本文结束时,您将牢固掌握共享内存如何显著加快您的计算速度以及如何......