STM32F407——串口通信

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

STM32F407——串口通信

前言

本文将对串口通信的分类和基于 stm32 的串口配置进行介绍,以及如何使用串口调试助手进行串口收发功能的调试,旨在帮助还不会使用 stm32 单片机串口资源进行通信的家人们快速学会如何使用串口来进行通信。
(纯干货、快速上手、零基础也能会!!!)

一、串口通信的概念及分类

1、串口及串口通信概念

(1)串口,即串行接口,是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。

(2)串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。

2、串口分类

常用的有串口有三种:
(1)RS232标准的串口
这一类的串口采用的是 RS232 电平标准,其中高电平为 +15V ,低电平为 -15V ,这类串口抗干扰性强,但是对我这种平平无奇大学生来说用不上。就是下面这玩意:
STM32F407——串口通信
STM32F407——串口通信

(2)USB转串口
这类串口十分常用,主要用来调试串口(下面会将如何用)。在 STM32F407 中也有一个 USB 串口,如下图所示:
STM32F407——串口通信
板载 CH340 USB 转 TTL 芯片,可以说是个串口调试的工具。
(3)原生的串口
这一类主要用于控制器跟串口的设备或者传感器通信,不需要经过电平转换芯片来转换电平,直接就用 TTL 电平(高电平 3.3V 或 5V,低电平 0V)通信。大家平常用的蓝牙、传感器等很多都是采用这个。

二、串口配置与调试

1、配置步骤

以 STM32F407 的串口3为例,跟大家讲下如何配置一个串口,使其能进行数据收发。
(1)串口初始化
在这一步中,需要:
① 对该串口使用到的 IO 口进行初始化和使能相应的时钟树,并对端口进行复用映射;
② 中断配置 (主要是一个优先级);
③ 串口初始化配置(奇偶校验、收发配置等);
④ 串口使能;
按上述步骤编写函数,代码如下:

void USART3_Init(u32 bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	 
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE); //使能GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//使能USART3时钟	
	
	//串口3对应引脚复用映射
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_USART3); 
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_USART3); 
	
  	//USART3端口配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11 ; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOB,&GPIO_InitStructure); 
  
	//Usart3 NVIC 配置
  	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

   	//USART3 初始化设置
	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(USART3, &USART_InitStructure); //初始化串口3

  	USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断	
	USART_Cmd(USART3, ENABLE);                    //使能串口3 	
	
	TIM7_Int_Init(100-1,8400-1);	//10ms中断一次
	USART3_RX_STA=0;		//清零
	TIM_Cmd(TIM7,DISABLE);			//关闭定时器7
}

(2)编写发送与接收函数
这个其实不用编写,库里就有了,接收与发送分别是:

uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  
  /* Receive Data */
  return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
}
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_USART_DATA(Data)); 
    
  /* Transmit Data */
  USARTx->DR = (Data & (uint16_t)0x01FF);
}

这个大家知道一下这两个的功能和如何调用函数即可。如果要接收串口3的信息,这样调用:Receive = USART_ReceiveData(USART3);如果要通过串口3发送消息,则:USART_SendData(USART3,data)。等下在中断函数和串口打印函数中会用到。
(3)编写中断服务函数

void USART3_IRQHandler(void)                	//串口1中断服务程序
{
	
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		Res =USART_ReceiveData(USART3);//(USART3->DR);	//读取接收到的数据
		if((USART3_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART3_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
				else USART3_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)USART3_RX_STA|=0x4000;
				else
				{
					USART3_RX_BUF[USART3_RX_STA&0X3FFF]=Res ;
					USART3_RX_STA++;
					if(USART3_RX_STA>(USART3_MAX_RECV_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
  } 
}

中断函数是在发生中断时间后,主程序自动进入中断函数运行,运行结束后在退出中断函数,返回到进入中断函数之前的运行状态。我愿把他成为一个时光静止器,执行到这个函数时,外界暂停,此刻整个世界只有自己,我们可以利用这段时间尽情地做我们想做的事,对我们所接收的信息进行分析处理等等。
(4)编写串口打印函数
这一函数与 C 语言中的 printf 其实是类似的,可将接收到的信息打印到电脑上,主要用于调试,函数如下:

//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)  
{  
	u16 i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)USART3_TX_BUF,fmt,ap);
	va_end(ap);
	i=strlen((const char*)USART3_TX_BUF);		//此次发送数据的长度
	for(j=0;j<i;j++)							//循环发送数据
	{
		while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
		USART_SendData(USART3,USART3_TX_BUF[j]); 
	} 
}

完成这几步后,一个串口就算配置好了,那如何检测配好的串口是否能进行正常的信息收发呢?请继续往下看。

2、串口收发功能测试

要测试的话,咱们需要自费5块钱左右买来一个 USB 转 TTL 模块(我20岁,现在能全款买下一个 USB 转 TTL 模块,大家应该也可以)。然后按照模块 5V 端口接单片机 5V 电源,模块 GND 端口接单片机 GND,模块 TX 端口接单片机 RX 端,模块 RX 端口接单片机 TX 端(发接收,收接发,不能接错,否则通信不起来)这样的连接方式将该模块连接到单片机上串口用到的引脚,然后插入电脑,打开串口调试助手(个人推荐正点原子的 XCOM),打开后的界面如下所示:
STM32F407——串口通信
接下来,我们要在串口选择栏选择对应串口,设置对应波特率,如果你在配置的时候设置的是115200,那这里就选择115200,一定不能出错,否则会造成输出乱码或者无法输出。然后奇偶校验这些咱们就按默认来,不需要设置,因为在配置中也没设置奇偶校验,然后点击打开串口,此时该栏的黑点会变成红点。如图所示:
STM32F407——串口通信
之后我们就可以进行收发测试了,收发测试需要在中断函数或者主函数中加上这一行代码:

u3_printf("收到的消息:%c/r/n",Res);

我们发个字符 ‘1’ 试试:
STM32F407——串口通信
发 ‘1’ 收 ‘1’ ,说明我们串口收发没问题,这样我们就可以放心大胆地在接收中断中做文章了。
如果要改成串口4的话,只需要改个引脚,把 3 改成 4 就行了。移植代码如下:

#include "uart4.h"	
#include "delay.h"
#include "stdarg.h"	 	 
#include "stdio.h"	 	 
#include "string.h"	  

u8  UART4_RX_BUF[UART4_MAX_RECV_LEN]; 				//接收缓冲,最大UART4_MAX_RECV_LEN个字节.
u8  UART4_TX_BUF[UART4_MAX_SEND_LEN]; 			//发送缓冲,最大UART4_MAX_SEND_LEN字节

vu16 UART4_RX_STA=0; 

void uart4_init(u32 bound){
   //GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); //使能GPIOC时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4,ENABLE);//使能USART4时钟
 
	//串口1对应引脚复用映射
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_UART4); //GPIOC11复用为UART4
	GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_UART4); //GPIOC10复用为UART4	
	
	//USART1端口配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10; //GPIOC11和GPIOC10初始化
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//速度50MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOC,&GPIO_InitStructure); //初始化GPIOB11,和GPIOB10

   //USART1 初始化设置
	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(UART4, &USART_InitStructure); //初始化串口4
	
	USART_Cmd(UART4, ENABLE);  //使能串口4 
	
	//USART_ClearFlag(USART1, USART_FLAG_TC);
		
	USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启中断 

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器	
}

void UART4_IRQHandler(void)                	//串口4中断服务程序
{
	u8 Res;   

	if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{
		Res =USART_ReceiveData(UART4);//(USART1->DR);	//读取接收到的数据
		
		if((UART4_RX_STA&0x8000)==0)//接收未完成
		{
			if(UART4_RX_STA&0x4000)//接收到了0x0d
			{
				if(Res!=0x0a)UART4_RX_STA=0;//接收错误,重新开始
				else UART4_RX_STA|=0x8000;	//接收完成了 
			}
			else //还没收到0X0D
			{	
				if(Res==0x0d)UART4_RX_STA|=0x4000;
				else
				{
					UART4_RX_BUF[UART4_RX_STA&0X3FFF]=Res ;
					UART4_RX_STA++;
					if(UART4_RX_STA>(UART4_MAX_RECV_LEN-1))UART4_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}   		 
  } 
} 
void u4_printf(char* fmt,...)  
{  
	u16 i,j;
	va_list ap;
	va_start(ap,fmt);
	vsprintf((char*)UART4_TX_BUF,fmt,ap);
	va_end(ap);
	i=strlen((const char*)UART4_TX_BUF);//此次发送数据的长度
	for(j=0;j<i;j++)//循环发送数据
	{
	  while(USART_GetFlagStatus(UART4,USART_FLAG_TC)==RESET);  //等待上次传输完成 
		USART_SendData(UART4,(uint8_t)UART4_TX_BUF[j]); 	 //发送数据到串口3 
	}
	
}


结语

本文主要讲了串口的配置步骤和注意事项以及串口的调试。 关于 STM32F407 的串口串口通信我就讲这么多,个人认为纯干货,拿来开发(不是很难的)也够用了。一样的,欢迎各位批评指正,联系微信:Cyy15880234628文章来源地址https://www.toymoban.com/news/detail-403325.html

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

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

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

相关文章

  • stm32F407学习DAY.14 在DMA模式下进行USART串口数据收发(正点原子例程为例)

    目录 一、DMA配置 1、DMA1和DMA2的请求映射 2、DMA挂载总线 3、DMA相关库函数 ​4、DMA配置过程(以串口1为例) 1)进行时钟使能 2)等待DMA可配置 3)初始化DMA(串口1的TX为DMA2 数据流7 通道4,RX为DMA2 数据流5 通道4) a.DMA外设地址par: b.DMA存储器0地址mar: c.数据传输量ndtr: 4)

    2024年02月04日
    浏览(49)
  • 【DRV8323】电机驱动芯片寄存器配置指南,通过STM32F407的SPI通信配置

    笔者计划使用一块使用到STM32F407控制芯片与DRV8323s驱动芯片的板子,驱动BLDC。了解到需要使用SPI通信来配置DRV8323s驱动芯片,配置过程中涉及DRV8323数据手册中提及的几个寄存器,故写此文做个记录。 另外,DRV8323芯片和DRV8302、DRV8303、DRV8353都有极大的相似之处,可以相互参考

    2024年02月02日
    浏览(62)
  • 【STM32】BLDC驱动&控制开发笔记 | 07_SPI通信测试 - STM32F407用SPI配置DRV8323驱动芯片

    最近在埋头搞STM32 + 无刷直流电机控制,想实现用自己的STM32F407VGT6芯片板子,外加一块驱动板(目前选用到TI的DRV8302或者DRV8323驱动芯片),搞定电机驱动,最后实现比较好的控制效果。如果不是同一块芯片的同学也不用急着走,大体上都是可借鉴哒~ 本文主要实现使用SPI通信

    2024年02月08日
    浏览(54)
  • 从STM32F407到AT32F407(一)

    雅特力公司的MCU有着性能超群,价格优越的巨大优势,缺点是相关资料少一些,我们可以充分利用ST的现有资源来开发它。 我用雅特力的STM32F437开发板,使用原子 stm32f407的开发板自带程序,测试串口程序,原设定串口波特率为115200,但是输出乱码,波特率改成230400,串口输

    2024年02月02日
    浏览(60)
  • 关于STM32F407ZGT6的USB损坏后使用ST-Link和USART1实现串口功能

    开发板:STM32F407ZGT6; 目标:想使用软件“串口调试助手” 情况:开发板上的USB_UART口所在器件损坏或者直接没有;   解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作: 1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,

    2024年02月08日
    浏览(49)
  • 关于STM32F407ZGT6的USB_UART端口损坏后使用ST-Link和USART1实现串口功能

    开发板:STM32F407ZGT6; 目标:想使用软件“串口调试助手” 情况:开发板上的USB_UART口所在器件损坏或者直接没有;   解决办法:查看该开发板的原理图,可得:串口1的RX接TXD,串口1的TX接RXD,那么按如下步骤操作: 1、现在使用USB转TTL模块,将串口1的RX接USB转TTL模块的TXD,

    2024年02月07日
    浏览(51)
  • STM32F407的时钟

    时钟源用来为环形脉冲发生器提供频率稳定且电平匹配的方波时钟脉冲信号。它通常由石英 晶体振荡器和与非门组成的正反馈振荡电路组成,其输出送至环形脉冲发生器。 F4开发指南P107 F4开发指南P108 HSI高速内部时钟源 High Speed Internal。RC 振荡器,频率为 16MHz。可以直接作为

    2024年02月10日
    浏览(55)
  • STM32F407的介绍

    内核 32位 高性能ARM Cortex-M4处理器 时钟: 高达168MHz,实际还可以超频一点点 stm32f407的主频通过PLL倍频后能够达到168MHz,而且芯片内置一个16MHz的晶振和一个32KHz的晶振,可以满足不同功耗的需求。 支持FPU(浮点运算)和DSP指令 144引脚 114个IO口 存储器容量: 1024K FLASH, 192K

    2024年02月10日
    浏览(58)
  • 初识 STM32和STM32F407简介

    2007 年 6 月,ST 在北京发布了全球第一款基于 ARM Cortex M3 内核的 32 位通用微控制 器芯片:STM32F103,以优异的性能,丰富的资源,超高的性价比,迅速占领市场,从此一鸣 惊人,一发不可收拾,截止到 2020 年 6 月,STM32 累计出货量超过 45 亿颗。 战舰开发板使用的 STM32F103ZET6

    2023年04月08日
    浏览(74)
  • STM32F407 移植 FreeRTOS

    本实验是基于正点原子 STM32F407ZG 探索者开发板完成的,所以需要一个STM32F407ZG 探索者开发板 用于移植的基础工程(下面会讲) FreeRTOS源码(下面会讲) 本实验所有用到的代码:基于正点原子STM32F407的FreeRTOS移植工程.zip 1.1 移植前准备 1.1.1 基础工程 由于后续需要用到 LED、

    2024年02月08日
    浏览(70)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包