STM32 学习————串口通信

这篇具有很好参考价值的文章主要介绍了STM32 学习————串口通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、串口介绍

众所周知,串口通信是MCU最基本的通信方式,对于STM32来说也是如此。本文重点讲述STM32单片机的串口通信,主要包括的内容是:通信基础知识、串口通信原理、USART有关寄存器和自定义编写串口通信函数。

1.处理器与外部设备通信的两种方式

  1. 通信目的:的将一个设备数据传送到另一个设备,扩展硬件系统。
  2. 通信协议:制定通信规则,通信双方按照协议规则进行数据收发。
  3. 并行通信:

   -⤴️传输原理:数据各个位同时传输。

   -⤴️优点:速度快

   -⤴️缺点:占用引脚资源多

       4.串行通信:

  -⤴️传输原理:数据按位顺序传输。

  -⤴️优点:占用引脚资源少

   -⤴️缺点:速度相对较慢

2.串行通信的分类 

        串行通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式,如SPI、USART、EEPROM通信等。串口通信实现了上位机(一般就是我们的电脑)与下位机(也就是我们的嵌入式设备,如51单片机,STM32)之间的信息交互。上位机可通过串口调试助手等实现数据的发送接收。

  • 😉a单工:数据传输只支持数据在一个方向上传输,发送端->接收端。(只收不发和只发不收)
  • 😉b半双工:允许数据在两个方向上传输,但是在某一时刻,只允许数据在一个方向上传输。实际上是一种能切换方向的单工通信。(能发能收,但不能同时进行)
  • 😉c全双工:允许数据同时在两个方向上传输。全双工通信是两个单工通信方式的结合,它要求发送和接受设备都有独立的接收和发送能力。(能发能收,且能同时进行)
  • stm32 串口通信,stm32,学习,嵌入式硬件
😇按照是否带有时钟同步信号分为:
  • 同步通信:带时钟同步信号(SCK,SCL....)。传输信息发送设备与信息接收设备需要时钟同步,两者间除数据线互连外,还需要有额外的时钟线进行互连,比如:SPI,IIC通信接口。
  • 异步通信:不带时钟同步信号。信息发送设备与接收设备之间只需要数据线连接,无需额外的时钟线互联。虽然双方没有时钟线互联,但是通信双方是需要有约定的,比如说波特率(波特率确定了,每个位传输的时间就确定了),起始位,停止位,奇偶校验位等。接收设备根据约定利用自己的本地时钟对数据进行采样。比如:UART(通用异步收发器),单总线(1-wire)。

常见的串行通信接口:

 stm32 串口通信,stm32,学习,嵌入式硬件

🤬UART异步通信方式的引脚连接:

TXD:数据输出脚,数据发送。RXD:数据输入脚,数据接收。

stm32 串口通信,stm32,学习,嵌入式硬件

 二、STM32的串口通信基础

😋STM32的串行通信接口:UART:通用异步收发器 ;      USART:通用同步异步收发器

STM32F4XX目前最多支持8个UART,STM32F103支持5个UART。 

这里需要注意的是:TX引脚要连接另一个控制器的RX引脚,反之RX亦然。

😋 UART异步通信方式引脚(STM32F407ZGT6的6个串口):芯片数据手册查。

stm32 串口通信,stm32,学习,嵌入式硬件

😋UART异步通信方式特点: 

  • 全双工异步通信。
  • 支持小数波特率发生器系统,提供精确的波特率。
  • 可配置8倍或者1倍过采样,为速度容差和时钟容差的灵活配置提供可能。
  • 可编程的数据字长(8或9位),是否带奇偶校验位。
  • 可配置的停止位(1或2位)。
  • 可配置使用DMA多缓冲器通信(支持DMA)。
  • 单独的发送器和接收器使能位。
  • 可触发中断。
  • 校验控制,四个错误检测标志。

😋STM32串口通信过程: 

数据发送过程:

stm32 串口通信,stm32,学习,嵌入式硬件

 数据接收过程:

stm32 串口通信,stm32,学习,嵌入式硬件

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

  •  起始位:比如下面范例,一开始电平为高,到起始位电平拉低告诉接收方要接收有用的数据了。
  • 数据位:(8位或9位,9位是带奇偶校验位)低位先行。要发送0011,就要1100这样顺序。
  • 奇偶校验位(第9位):奇校验:包括校验位在内的9个数据会出现奇数个1。偶校验同理。
  • 停止位:与起始位差不多。
  • 波特率设置:决定了每隔多长时间发送一位 / 接收一位。
typedef struct {
 uint32_t USART_BaudRate; // 波特率
 uint16_t USART_WordLength; // 字长
 uint16_t USART_StopBits; // 停止位
 uint16_t USART_Parity; // 校验位
 uint16_t USART_Mode; // USART 模式
 uint16_t USART_HardwareFlowControl; // 硬件流控制
 } USART_InitTypeDef;

😋STM32串口框图: 

stm32 串口通信,stm32,学习,嵌入式硬件

 😋串口配置的一般步骤:

  • 串口时钟使能:RCC_APBxPeriphClockCmd();
  • GPIO 时钟使能RCC_AHB1PeriphClockCmd();
  • 引脚复用映射:GPIO_PinAFConfig();
  • GPIO端口模式设置:GPIO_Init();模式设置为:GPIO_Mode_AF
  • 串口参数初始化:USART_Init();
  • 开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤):
  • NVIC_Init(); USART_ITConfig();//使能相关中断
  • 使能串口:USART_Cmd();
  • 编写中断处理函数:USARTx_IRQHandler();
  • 串口数据收发:void USART_SendData();//发送数据到DR
  • uint16_t USART_ReceiveData()//从DR读取接收到的数据
  • 串口传输状态获取:FlagStatus USART_GetFlagStatus();
  • void USART_ClearITPendingBit();

😋NVIC配置中断优先级 

我们在串口接收信息时采用了触发中断事件,所以要配置一下串口中断的优先级:

void Usart_Init(u32 bound)
{
//	结构体定义变量
	GPIO_InitTypeDef GPIO_Type_USART; //GPIO结构体
	USART_InitTypeDef USART_Type; //串口结构体
	NVIC_InitTypeDef NVIC_InitStruct; //中断结构体
//	串口时钟使能 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//	GPIO时钟使能
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
//	引脚复用映射--将PA9和PA10引脚连接到串口1的硬件
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
//	GPIO端口模式设置
	GPIO_Type_USART.GPIO_Pin=GPIO_Pin_9 | GPIO_Pin_10; 
	GPIO_Type_USART.GPIO_Mode=GPIO_Mode_AF;//复用功能模式
	GPIO_Type_USART.GPIO_OType=GPIO_OType_PP; //推挽输出
	GPIO_Type_USART.GPIO_PuPd= GPIO_PuPd_UP;//上拉
	GPIO_Type_USART.GPIO_Speed=GPIO_Speed_100MHz; //100MHZ
//	初始化GPIO
	GPIO_Init(GPIOA,&GPIO_Type_USART);
//	串口参数配置
//配置串口1相关参数:波特率、无校验位、8位数位、1位停止位
	USART_Type.USART_BaudRate=bound; //波特率
	USART_Type.USART_WordLength=USART_WordLength_8b; //数据长度
	USART_Type.USART_StopBits=USART_StopBits_1;//停止位
	USART_Type.USART_Mode=USART_Mode_Rx |USART_Mode_Tx;//收发模式
	USART_Type.USART_Parity=USART_Parity_No;//无奇偶校验
	USART_Type.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件流控制
//	串口初始化
	USART_Init(USART1,&USART_Type); //初始化串口1
	
//	串口接收中断使能
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
//	开启空闲中断-使能
	USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
	
//	中断配置
	NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;   //启用或禁用的IRQ通道--串口1中断通道
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=3;  //抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=3; //响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能
	
	NVIC_Init(&NVIC_InitStruct); //初始化NVIC寄存器
	
//	使能串口
	USART_Cmd(USART1,ENABLE); //使能串口1	 
}

//USART外设发送一个字符串
void USART1_Send(u8 *arr)
{
// TC
//	0:传送未完成
//	1:传送已完成
	while(*arr!='\0')
	{
		while(USART_GetITStatus(USART1,USART_FLAG_TXE)!=RESET);//传输数据寄存器空标志
		USART_SendData(USART1,*arr);
		arr++;
	}
    
}

//USART外设接收一个字符串
u8 USART1_Receive(void)
{
		
		while(USART_GetITStatus(USART1,USART_FLAG_RXNE)!=RESET);//接收中断不空标志
		return USART_ReceiveData(USART1);
}
//字符串处理函数 
void USART1_Receive_str(u8 *arr)
{
	while(1)
	{
		*arr=USART1_Receive();
		if(*arr =='\r' ||*arr =='\n' )
		{	
			*arr='\0';
			return; 
		}
		arr++;
	}
}
u8 arr[50]={0}; //临时数组
u8 flage; //标志位
//中断服务函数 
int len=0;
//中断服务函数 
void USART1_IRQHandler(void)
{	
	//检查标志位
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //空闲中断
	{
		arr[len++]=USART_ReceiveData(USART1); //字符发送
		
		//USART_SendData(USART1,d); //字符接收
	}
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //接收中断
	{
		arr[len]='\0';
		flage=1;
		USART_ReceiveData(USART1);//清空缓冲区和中断标志位
	}
    //memset(arr,0,sizeof(arr));
	//USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清除标志位
	
}

通过中断接收

stm32f10x_it.c中编写USART1中断源相对应得中断函数,利用了固件库函数中的
USART_ReceiveData(DEBUG_USARTx);接收函数
USART_SendData(DEBUG_USARTx, x);发送函数
USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE);判断标志位函数

USART_ReceiveData(USART1);//清空缓冲区和中断标志位

NVIC--向量中断控制器(串口)---在文件misc.c中查找--配置优先级
中断服务函数,在启动文件里找-----写中断服务函数,完事了清除标志位,,

配置了中断优先级,主函数必须调用 优先级分组 

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置优先级分组 2:抢占 2:响应文章来源地址https://www.toymoban.com/news/detail-788928.html

💦重定向


//想要使用printf函数,就必须引用该头文件,否则就会报错
/* 告知连接器不从C库链接使用半主机的函数 */
#pragma import(__use_no_semihosting)  //预处理指令

/* 定义 _sys_exit() 以避免使用半主机模式 */
void _sys_exit(int x)
{
    x = x;
}

/* 标准库需要的支持类型 */
struct __FILE
{
    int handle;
};

FILE __stdout;
/*  */
int fputc(int ch, FILE *stream)
{
    /* 堵塞判断串口是否发送完成 */
	while(!USART_GetFlagStatus(USART1,USART_FLAG_TC)); //等待USART_FLAG_TC发送完成标志位置为1
	USART_SendData(USART1, ch);
  return ch;
}	

到了这里,关于STM32 学习————串口通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式学习笔记——STM32的USART通信概述

    上两篇文章中,已经实现了GPIO的通用输出以及通用输出模式,从本文开始,笔者将开始有关GPIO的复用功能的介绍,首先是最常用复用功能——串口,本文主要是介绍一些关于通信以及串口的基本概念。 通信协议:通信双方进行信息交换(接收或发送)要满足的规则,而这个规

    2023年04月08日
    浏览(59)
  • 嵌入式学习笔记——STM32的USART收发字符串及串口中断

    上一篇中,介绍了串口收发相关的寄存器,通过代码实现了一个字节的收发,本文接着上面的内容,通过功能函数实现字符串的收发,然后引入中断解决收发过程中while()死等的问题。 根据昨天的字符发送函数,只需要稍作修改即可实现发送函数了,一个字符串的结尾会有一

    2024年02月03日
    浏览(79)
  • 嵌入式硬件——stm32F103C8T6

    如下图:    处理器核心:STM32F103C8T6内置了ARM Cortex-M3处理器,这是一种高性能、低功耗的32位RISC处理器,适用于嵌入式系统。 时钟速度:它可以工作在不同的时钟速度,最高主频可达72 MHz。 存储器:包括64KB的Flash程序存储器用于存储程序代码,以及20KB的SRAM用于存储数据和

    2024年02月05日
    浏览(65)
  • 嵌入式毕设分享 stm32人脸识别快递柜系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年04月10日
    浏览(73)
  • 嵌入式开发--STM32用DMA+IDLE中断方式串口接收不定长数据

    之前讲过用 利用IDLE空闲中断来接收不定长数据 ,但是没有用到DMA,其实用DMA会更加的高效,MCU也可以腾出更多的性能去处理应该做的事情。 IDLE顾名思义,就是空闲的意思,即当监测到串口空闲超过1个串口的数据帧时,会使状态寄存器(SR或ISR)的IDLE位置位,如果此时控制

    2024年04月17日
    浏览(64)
  • 嵌入式毕设分享 stm32智能鱼缸监控投喂系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年03月17日
    浏览(80)
  • 嵌入式毕设分享 stm32 RFID智能仓库管理系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(74)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(71)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(87)
  • STM32的时钟系统(嵌入式学习)

    时钟是指用于计量和同步时间的装置或系统。时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,例如:串口数据的发送、AD转换、定时器计数等。因此时钟对于计算机系统是至关重要的,通常时钟系

    2024年02月16日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包