隔壁老王看了都会的文章:STM32串口实验——单片机与上位机交互信息

本文主要是介绍隔壁老王看了都会的文章:STM32串口实验——单片机与上位机交互信息,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天介绍USART串口通信的使用,目的在于会用串口传送和接收数据。内容包含了NVIC中断的知识,下一篇着重讲NVIC中断。ADC在下下一篇。主要还是先看懂USART的相关代码。

什么是串行通信

 我们对通信的字面意思理解就是信息的传输与交换。通信按照基本类型可以分为并行通信和串行通信。并行通信时数据的各个位同时传送,可以实现字节为单位通信,但是因为通信线多占用资源多,成本高。而串口通信传送数据是一帧一帧发送,传送距离相对较远,占用资源少,成本低,但是串行通信传输速度相对于并行通信传输速度较慢。单片机上大多使用串行通信。            

串行通信是单片机最常用的一种通信技术,通常用于单片机和电脑之间以及单片机和单片机之间的通信。单片机的串口是全双工异步串口通信方式,通过TXD引脚发送,RXD引脚接收输入。

串行通信的实现方式--数据传输方式

同步通信:接收时钟与发送进钟严格同步,通常要有同步时钟,日常应用在大批量数据传输上。例(SPI、IIC通信接口)

异步通信:接收时钟与发送进钟不需要严格同步,但是必须设置相同的波特率,否则传输数据会产生异常。例(单总线,uart)

串行通信的实现方式--数据传输方向

根据串行通信的数据传输方向,串行通信方式分为三种:单工、单双工、全双工。

单工: 信息只可以从一方传向另一方。

半双工: 任意时刻信息都可以从一方传向另一方,但不能同时发生。即A-->B或B-->A。

全双工:任意时刻信息都可以双向的传输,即A-->B且B-->A。

串口通信的基础概念

串口通讯在协议层中规定了数据包的内容,具体包括起始位、主体数据(8位或9位)、校验位以及停止位,通讯的双方必须将数据包的格式约定一致才能正常收发数据。 1、波特率:由于异步通信中没有时钟信号,所以接收双方要约定好波特率,即每秒传输的码元个数,以便对信号进行解码,常见的波特率有4800、9600、115200等。 2、起始和停止信号:数据包的首尾分别是起始位和停止位,数据包的起始信号由一个逻辑0的数据位表示,停止位信号可由0.5、1、1.5、2个逻辑1的数据位表示,双方需约定一致。 3、有效数据:有效数据规定了主题数据的长度,一般为8或9位 4、数据校验;在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、0校验(space)、1校验(mark)以及无(noparity)。

USART工作过程(usart比uart多了同步的功能)

UART传输数据依靠的是UART总线,数据总线用于通过微控制器等其他设备将数据发送到UART。数据以并行形式从数据总线传输发送到UART。UART从数据总线获得并行数据之后,它将添加起始位,奇偶校验位和停止位,从而创建数据包。接下来,数据包在Tx引脚上逐位串行输出。UART接收端则在其Rx引脚上逐位读取数据包。然后,接收UART将数据转换回并行形式,并删除起始位,奇偶校验位和停止位。最后,接收UART将数据包并行传输到接收端的数据总线。

介绍了其工作过程,我们现在看看其关键代码实现,下面是对USART串口配置的初始化代码,基本没有什么难的,请自动忽略NVIC的部分下一篇主要讲他:

1) 串口时钟使能,GPIO 时钟使能
2) 串口复位
3) GPIO 端口模式设置
4) 串口参数初始化
5) 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
6) 使能串口void uart_init(u32 bound){//定义需要用到的结构体 GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;
//使能GPIOA与USART1的时钟	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//配置GPIO PA9为输出端  PA10为输入端GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	  //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//NVIC配置    下个主要讲NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			NVIC_Init(&NVIC_InitStructure);	//USART的初始化配置,根据上面USART的基础知识来配USART_InitStructure.USART_BaudRate = bound;  //波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b; //位长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_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //开启串口1中断USART_Cmd(USART1, ENABLE);                      //串口1使能}

 

加上重定义代码段就可以直接用printf()来给上位机传数据了

int fputc(int ch, FILE *f)
{      while((USART1->SR&0X40)==0);USART1->DR = (u8) ch;      return ch;
}

那上位机如何给单片机传输数据呢?请看下面的代码:

void USART1_IRQHandler(void)                	{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断{Res =USART_ReceiveData(USART1);  //保存当前传送来的数据if((USART_RX_STA&0x8000)==0)   //如果接收未完成{if(USART_RX_STA&0x4000)//如果次高位为1{ if(Res!=0x0a)USART_RX_STA=0;//次高位已经为1,所以本次接收结果一定为0x0a,不为0x0a的话就是接收过程错误,重新接受。else USART_RX_STA|=0x8000;//此时的数据为0x0a,则将最高位改为1代表接受已经完成}else {	if(Res==0x0d)USART_RX_STA|=0x4000;       //次高位不为1,但是本次数据为0x0d,则将次高位设置为1else{USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;//次高位不为1,本次数据也不是为0x0d,缓冲区加1USART_RX_STA++;													if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//超出最大数据容量,接受错误,重新接收}		 }}   		 } } 

想信许多没有基础的同学看这这些代码很蒙,没关系下来我给大家介绍一下代码的意思。

上位机给串口发送数据时,都会给数据末尾加上0x0d,0x0a。0x0d是回车的意思,0x0a是换行的意思。由此我们就可以判断数据何时发送结束了。

USART_RX_STA是接收状态标记。是16位的数据,他的最高位可以判断接受是否完成,次高位为判断数据是否为回车,回车的ASCLL是0X0d。其他14位用来存储数据的长度。USART_RX_BUF[]是接收缓冲区,他被下面代码定义为最大可以接收200个字节(这是usart.h里的代码)。

#define USART_REC_LEN  			200
extern u8  USART_RX_BUF[USART_REC_LEN];

上面代码其实就是为了上位机给的数据被成功的接收,很难表达出来,详细注释都给了,基本没很大难度,有需要私聊。

主函数如下,目的是将上位机给单片机的数据又返回给上位机,便于观察是否传输正确:

while(1){if(USART_RX_STA&0x8000)  //最高位为1,接收完成{					   len=USART_RX_STA&0x3fff;   //取出数据长度到len//下面为函数重定义,将单片机收到的数据再返回给上位机,主要起了提示作用
for(t=0;t<len;t++){USART1->DR=USART_RX_BUF[t];while((USART1->SR&0X40)==0);}//传输完成清空标志位USART_RX_STA=0;}//此时没有数据可以输出给上位机,请再发送数据else{times++;if(times%200==0)printf("请输入数据:\r\n");  delay_ms(10);   }}	 
}

下篇和下下篇为NVIC中断管理和ADC模块。我会加急更新!!!!

 

这篇关于隔壁老王看了都会的文章:STM32串口实验——单片机与上位机交互信息的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/307026

相关文章

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

SpringBoot使用Apache Tika检测敏感信息

《SpringBoot使用ApacheTika检测敏感信息》ApacheTika是一个功能强大的内容分析工具,它能够从多种文件格式中提取文本、元数据以及其他结构化信息,下面我们来看看如何使用Ap... 目录Tika 主要特性1. 多格式支持2. 自动文件类型检测3. 文本和元数据提取4. 支持 OCR(光学

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

基于WinForm+Halcon实现图像缩放与交互功能

《基于WinForm+Halcon实现图像缩放与交互功能》本文主要讲述在WinForm中结合Halcon实现图像缩放、平移及实时显示灰度值等交互功能,包括初始化窗口的不同方式,以及通过特定事件添加相应... 目录前言初始化窗口添加图像缩放功能添加图像平移功能添加实时显示灰度值功能示例代码总结最后前言本文将

通过C#获取PDF中指定文本或所有文本的字体信息

《通过C#获取PDF中指定文本或所有文本的字体信息》在设计和出版行业中,字体的选择和使用对最终作品的质量有着重要影响,然而,有时我们可能会遇到包含未知字体的PDF文件,这使得我们无法准确地复制或修改文... 目录引言C# 获取PDF中指定文本的字体信息C# 获取PDF文档中用到的所有字体信息引言在设计和出

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

使用Python检查CPU型号并弹出警告信息

《使用Python检查CPU型号并弹出警告信息》本教程将指导你如何编写一个Python程序,该程序能够在启动时检查计算机的CPU型号,如果检测到CPU型号包含“I3”,则会弹出一个警告窗口,感兴趣的小... 目录教程目标方法一所需库步骤一:安装所需库步骤二:编写python程序步骤三:运行程序注意事项方法二

PostgreSQL如何查询表结构和索引信息

《PostgreSQL如何查询表结构和索引信息》文章介绍了在PostgreSQL中查询表结构和索引信息的几种方法,包括使用`d`元命令、系统数据字典查询以及使用可视化工具DBeaver... 目录前言使用\d元命令查看表字段信息和索引信息通过系统数据字典查询表结构通过系统数据字典查询索引信息查询所有的表名可

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti