STM32 串口通讯及实现

2023-05-16

目录

    • 一、串口通讯概述
      • 1、广义的串口
      • 2、狭义的串口
      • 3、串口数据定义
      • 4、串口通讯应用
    • 二、STM32串口工程标准库实现
      • 1、串口的初始化
      • 2、串口数据发送.
      • 3、串口的数据接收


一、串口通讯概述

1、广义的串口

  广义的串口是针对并口来说的。串口是指设备之间通过一根数据信号线按数据位形式一位一位地传输数据的通讯端口,同一时刻只能传输一位(bit)数据。并口则是指用多条数据线进行传输的通讯方式,可以同一时刻并排传输多个数据位的数据端口。

2、狭义的串口

  狭义的串口我们就特指COM口,或者称做UART口。硬件上常用的两大电压标准有TTL(只有正电压)和RS232标准(有正负电压),STM32单片机上基本都使用的TTL标准,判别电压为基准供电电压的一半。我们看到的单片机上的串口一般分为两种,一种叫USART,通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter),另一种为UART,通用异步收发器(Universal Asynchronous Receiver and Transmitter),唯一的区别很明显,就是有和没有同步通讯方式。通常硬件至少要有一对Tx和Rx加上一个GND地,有了这三个引脚就可以工作了,其它同步引脚等其它引脚可以不使用。

3、串口数据定义

  完整的侦结构见下图,从一个起始位开始,接着是着多位有效数据,一般常规定义为8位,后面的就效验位,为可以选,最后一个就是停止标志位,也就是说8位有效数据的时候一个完整的帧结构就需要10位。
  波特率是描述串口通讯的速度指标,有很多种,双方约定好就可以正常通讯,我们常用的有9600、115200、921600,定位bps,位每秒。
在这里插入图片描述

4、串口通讯应用

  串口是我们使用的最基础的通信方式之一,因为引脚少,连接方便,它经常用来打印log,或作为短距离较少数据的通信方式,也可以替代I2C等偏低速通信方式。


二、STM32串口工程标准库实现

1、串口的初始化

  在STM32工程main的最开始,大while()循环之前,我们的各种外设都需要初始化,如下面串口的初始化代码, 它是用来驱动串口的初始化函数uart1_init(),输入参数为波特率baud_rate,从注释中可以看到,初始化要进行以下操作步骤:
1、使能时钟;
2、自动复用的引脚,
3、配置引脚的初始化状态方式;
4、配置串口的通信属性;
5、使能串口;
6、初始化嵌套向量中断控制器中的相关中断参数,为接收做准备。

//初始化IO 串口1 
//bound:波特率
void uart1_init(u32 baud_rate)
{
   //GPIO端口设置
   GPIO_InitTypeDef GPIO_InitStructure;
   USART_InitTypeDef USART_InitStructure;
   //#if EN_USART1_RX	
   NVIC_InitTypeDef NVIC_InitStructure;
   //#endif
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟

   //串口1对应引脚复用映射
   GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
   GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1
   
   //USART1端口配置
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
   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(GPIOA,&GPIO_InitStructure); //初始化

   //USART1 初始化串口属性设置
   USART_InitStructure.USART_BaudRate = baud_rate;//波特率设置
   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); //初始化串口1
   
   USART_Cmd(USART1, ENABLE);  //使能串口1 
   
   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启相关中断
   //Usart1 NVIC 配置
   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断通道
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
   NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;		//子优先级3
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
   NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

}

2、串口数据发送.

  (1) 代码实现发送给串口1较为简单,一句话搞定:

Usart_SendString( USART1, send_data);

  • 参数USART1为串口的名称,它对应着外设的内存地址映射。
  • 参数send_data则是我们要发送的字符串数据,或者说是字符串指针。

   (2) 重定向printf()到USART1:

  • 重定向打印输出到串口1,需要定义fputc(),将打印数据的状态寄存器和数据寄存器映射到串口1,这样串口1就是打印数据口了。

int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}


/*****************  发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx,ch);
		
	/* 等待发送数据寄存器为空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
	unsigned int k=0;
  do 
  {
      Usart_SendByte( pUSARTx, *(str + k) );
      k++;
  } while(*(str + k)!='\0');
  
  /* 等待发送完成 */
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  {}
}


//重定向printf到USART1
int fputc(int ch, FILE *f)
{ 	
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
	USART1->DR = (u8) ch;      
	return ch;
}
 

3、串口的数据接收

   因为单片机串口接收是一个字节一个的接收的,接收到一个字节就会进入到中断服务函数中。我们可以在中断中进行字节判断,如下面的代码实例,也可以接收一段字符后做字符串匹配判断。这里需要注意几点:

  • 中断服务程序的命名是有严格要求的,请注意不要写错,否者写错了也不给报错,很难找到问题原因。
  • 中断服务程序中运行的时间越短越好,也就是说代码,尽量少做判断越精简越好。
u16 num1 = 0;//数据累加计数
char USART_RX1_BUF[HOST_REC_LEN];//接收缓冲字节.

// 串口中断服务函数
void USART1_IRQHandler(void)
{		
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//enum{RESET = 0, SET = !RESET} FlagStatus
	{	
		USART_RX1_BUF[num1] = (uint8_t)USART_ReceiveData(USART1);
 	
		// 当接收到的值等于\r\n结尾时截取数据
		if(num1 > 2 && USART_RX1_BUF[num1-1] == '\r' && USART_RX1_BUF[num1] == '\n')
		{
			USART_RX1_BUF[num1+1]='\0';
			SetUARTFlag(1);//设置UART1标志
			num1 = 0;
			return;
		}
		//超出长度溢出时截断数据
		else if(num1 >= LimitSize_1)
		{
			USART_RX1_BUF[num1]=0x0d;//回车
			USART_RX1_BUF[num1+1]=0x0a;//换行
			USART_RX1_BUF[num1+2]='\0';
			SetUARTFlag(1);//设置UART1标志
			num1 = 0;
		}
		//正常累加,判断异常数据
		else
   		{
   		 	if(USART_RX1_BUF[0]!=0)
				num1 ++;
			else 
				num1 = 0;
	 	 }  
		 
	}	 
	
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 串口通讯及实现 的相关文章

  • 如何在 Cortex-M3 (STM32) 上从 RAM 执行函数?

    我正在尝试从 Cortex M3 处理器 STM32 上的 RAM 执行函数 该函数会擦除并重写内部闪存 所以我肯定需要在 RAM 中 但我该怎么做呢 我尝试过的是 使用 memcpy 将函数复制到 RAM 中的字节数组 检查它是否正确对齐
  • GCC - 如何停止链接 malloc?

    我正在努力将我的代码缩减到最小的骨架大小 我使用的是只有 32k 闪存的 STM32F0 需要很大一部分闪存用于数据存储 我的代码已经有大约 20k 闪存大小 其中一些是由于使用了 STM32 HAL 函数 我可以在以后需要时对其进行解释和
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • 如何让printf在STM32F103上工作?

    我是 STM32F103 世界的新手 我有一个STM32F103的演示代码 我正在使用arm none eabi来编译它 我尝试了在谷歌上可以找到的内容 但到目前为止没有任何效果 我已经花了三天时间来解决这个问题 任何人都可以给我一个运行良
  • CMSIS 库是否应该包含在版本控制中? [复制]

    这个问题在这里已经有答案了 通常 我曾经在版本控制中包含芯片供应商 ST 提供的设备特定标头和源以及 CMSIS Core 标头 数量不多 也没有更新的习惯 我使用STM32微控制器 但我不使用立方体框架 or the 标准外设库 最近 我
  • 优化 ARM Cortex M3 代码

    我有一个 C 函数 它尝试将帧缓冲区复制到 FSMC RAM 这些函数将游戏循环的帧速率降低至 10FPS 我想知道如何分析反汇编的函数 我应该计算每个指令周期吗 我想知道CPU把时间花在哪里 在哪个部分 我确信该算法也是一个问题 因为它的
  • 134-基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真+源程序...

    资料编号 134 一 功能介绍 1 采用stm32单片机 LCD1602显示屏 独立按键 ds1302时钟 DHT11温湿度 电机 蜂鸣器 制作一个基于stm32单片机矿井瓦斯天然气浓度温湿度检测自动通风系统Proteus仿真 2 通过DH
  • STM32F4 通过软复位跳转到引导加载程序,无需 BOOT0 和 BOOT1 引脚

    我问这个问题是因为可以在这里找到类似问题的答案 通过应用程序跳转到 STM32 中的引导加载程序 即从用户闪存在引导模式下使用引导 0 和引导 1 引脚 用户 JF002 JF002回答 当我想跳转到引导加载程序时 我在其中一个备份寄存器中
  • STM32用一个定时器执行多任务写法

    文章目录 main c include stm32f4xx h uint32 t Power check times 电量检测周期 uint32 t RFID Init Check times RFID检测周期 int main Timer
  • STM32F103

    提示 来源正点原子 参考STM32F103 战舰开发指南V1 3PDF资料 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 提示 这里可以添加本文要记录的大概内容 开发环境硬件普中科技 接线图在g
  • [屏驱相关]【SWM166-SPI-Y1.28C1测评】+ 有点惊艳的开箱

    耳闻华芯微特许久了 看到论坛得评测活动赶紧上了末班车 毕竟对有屏幕得板子也是很喜欢得 京东快递小哥客客气气 微笑着把快递给了我 好评 直接拆了包 在此之前没看过视频号 所以这个圆盘盘得模具还是有点惊喜的 正面照如下 开机有灯光秀 还有动画
  • [MM32硬件]搭建灵动微MM32G0001A6T的简易开发环境

    作为学习单片机的经典 自然是通过GPIO点亮LED 或者是响应按钮的外部中断例程 这我们看看SOP8封装的芯片MM32G0001A6T得引脚 除了VDD和GND固定外 我们可以使用PA14 PA1 PA13 PA15 PA2 PA3这六个G
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • for循环延时时间计算

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 pandas是什么 二 使用步骤 1 引入库 2 读入数据 总结 前言 之前做led点亮的实验 好像是被delay函数影响了 因为delay参数设置的不对
  • 嵌入式开发--STM32G4系列片上FLASH的读写

    这个玩意吧 说起来很简单 就是几行代码的事 但楞是折腾了我大半天时间才搞定 原因后面说 先看代码吧 读操作 读操作很简单 以32位方式读取的时候是这样的 data IO uint32 t 0x0800F000 需要注意的是 当以32位方式读
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • 移动数组中的元素

    我需要一点帮助 我想将数组中的元素向上移动一个元素 以便新位置 1 包含位置 1 中的旧值 new 2 包含 old 1 依此类推 旧的最后一个值被丢弃 第一个位置的新值是我每秒给出的新值 我使用大小为 10 的数组 uint32 t TE
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能

随机推荐

  • 【无标题】

    ZED Pro1 xff1a ZED深度相机进行点云可视化和保存 96 提示 xff1a 我在这里想得到深度相机获取的点云数据并且进行可视化 xff0c 虽然光放以及给出一部分代码 xff0c 但是并不能支撑我完成所有工作 xff0c 所以
  • linux系统下使用gcc编译C++程序出现XXX未定义的引用的处理

    在使用gcc编译程序的时候 xff0c 出现了XXX未定义的引用的错误 xff0c 如图 错误原因分析 xff1a 首先 xff0c 我创建了类System xff0c 但是在类System中只有构造函数析构函数以及其他成员函数的定义 xf
  • CMake 常用总结二:CMake 生成静态库与动态库

    引言 CMake 实践帮助我们对 CMake 有一个系统全面的了解 xff0c 并且有大量示例以供参考 xff0c 至少在实际项目中可以让我们有能力看懂并修改项目中现有的 CMake 阅读完 CMake 实践文档 xff0c 认为自己的任务
  • linux c UDP编程实现双向通信(学习记录)

    linux c 编程学习记录 程序说明 用linuxc网络编程的UDP套接字编程 实现内网中不同ip之间服务端和客户端的双向通信 Service端 xff1a span class token macro property span cla
  • python网络程序设计,TCP协议客户端服务端智能聊天设计

    计算机网络基础知识 网络体系结构 xff0c 分层设计的好处 网络协议三要素 xff1a 语法 语义 时序 常见应用层协议 xff1a ftp http smtp pop3 telnet 传输层主要概念 xff1a TCP UDP 端口号
  • 自动化测试用例设计平台(AutoTCG OnLine)

    自动化测试用例设计平台 xff08 AutoTCG OnLine xff09 一 平台介绍二 主要功能三 AutoTCG系列产品 一 平台介绍 1 AutoTCG OnLine是一款在线自动化测试用例设计平台 xff0c 通过在线创建可视化
  • AutoTCG——移动app测试用例自动生成平台

    AutoTCG简介 1 AutoTCG 是一款在线自动化测试用例设计平台 xff0c 通过在线创建可视化测试模型 xff0c 自动生成测试用例 2 AutoTCG采用先进的数学算法 xff0c 可实现全面科学的测试覆盖 3 AutoTCG适
  • AutoTCG——桌面应用软件测试用例自动生成工具

    AutoTCG简介 1 AutoTCG 是一款在线自动化测试用例设计平台 xff0c 通过在线创建可视化测试模型 xff0c 自动生成测试用例 2 AutoTCG采用先进的数学算法 xff0c 可实现全面科学的测试覆盖 3 AutoTCG适
  • 某型车载导航软件测试

    1 设备组成 ETst USB系统主要由硬件部分与软件部分组成 硬件部分包括1553B板卡 RS232 422 485板卡 CAN总线板卡 AD采集板卡 DA转换板卡 DI DO板卡等 所有硬件板卡均采用USB的接口形式 xff0c 从而灵
  • 武器装备自动测试(ATE)系统设计要点

    1 设备组成 ETest RT系统主要由硬件部分与软件部分组成 硬件部分由上位机和实时下位机组成 xff0c 上位机采用商用便携计算机 xff0c 下位机采用PXI测控计算机 上位机安装Windows操作系统 xff0c 运行设备资源管理
  • 导弹制导控制系统半实物仿真系统的设计与实现

    设备组成 Etest CPS系统主要由硬件部分与软件部分组成 硬件部分由PCI机箱 PCI控制器以及各种PCI接口板卡组成 软件部分由测试设计软件模块 测试执行服务软件模块 测试执行客户端软件模块 设备资源管理软件模块等主要软件模块以及曲线
  • 软件功能三方测试报告

    凯云软件测评中心隶属于凯云联创 xff08 北京 xff09 科技有限公司 xff08 简称 xff1a 凯云科技 xff09 测评中心于2016年成立 xff0c 2018年1月通过中国合格评定国家认可委员会CNAS和国防科技工业实验室认
  • 兵器软件通用测试开发工具

  • 兵器软件通用测试开发方法-ETest_DEV

  • 兵器软件通用测试开发环境-ETest_DEV

  • WPS添加下划线,文字尾部不显示下划线问题解决(一个So stupid问题)

    记录一个傻瓜操作 嗯 更想删WPS了 一 问题如下 首先如图 选择wps中的下划线操作 理想中他应该是这样的 选中的内容应该在下划线中间 是吧 默认正常操作就应该这样 实际上它出来的效果是这样 文字后面选中的下划线消失了 软件自身的设置就没
  • 【记录】MPU6050原理快速入门(附手册)

    目录 MPU6050 MPU6050主要参数 MPU6050通信接口 MPU6050电路 向MPU6050的一个寄存器写一个字节的数据 从MPU6050的一个寄存器读一个字节的数据 MPU6050 MPU6050是一个运动处理传感器 xff
  • 【STM32】HAL库三步实现串口重定向(代码复制可用)

    目录 第一步 xff1a 添加标准输入输出头文件 第二步 xff1a 重写fputc 函数 第三步 xff1a 重写fgetc 函数 代码汇总 xff08 直接复制使用 xff09 需要直接来复制 在PC上进行C语言程序开发时 xff0c
  • c# Post请求实例

    server span class token comment 服务器 span span class token keyword using span span class token namespace System span span
  • STM32 串口通讯及实现

    目录 一 串口通讯概述1 广义的串口2 狭义的串口3 串口数据定义4 串口通讯应用 二 STM32串口工程标准库实现1 串口的初始化2 串口数据发送 3 串口的数据接收 一 串口通讯概述 1 广义的串口 广义的串口是针对并口来说的 串口是指