隔壁老王看了都会的文章: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

相关文章

微信公众号脚本-获取热搜自动新建草稿并发布文章

《微信公众号脚本-获取热搜自动新建草稿并发布文章》本来想写一个自动化发布微信公众号的小绿书的脚本,但是微信公众号官网没有小绿书的接口,那就写一个获取热搜微信普通文章的脚本吧,:本文主要介绍微信公众... 目录介绍思路前期准备环境要求获取接口token获取热搜获取热搜数据下载热搜图片给图片加上标题文字上传图片

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

一文详解SQL Server如何跟踪自动统计信息更新

《一文详解SQLServer如何跟踪自动统计信息更新》SQLServer数据库中,我们都清楚统计信息对于优化器来说非常重要,所以本文就来和大家简单聊一聊SQLServer如何跟踪自动统计信息更新吧... SQL Server数据库中,我们都清楚统计信息对于优化器来说非常重要。一般情况下,我们会开启"自动更新

Python如何获取域名的SSL证书信息和到期时间

《Python如何获取域名的SSL证书信息和到期时间》在当今互联网时代,SSL证书的重要性不言而喻,它不仅为用户提供了安全的连接,还能提高网站的搜索引擎排名,那我们怎么才能通过Python获取域名的S... 目录了解SSL证书的基本概念使用python库来抓取SSL证书信息安装必要的库编写获取SSL证书信息

如何使用C#串口通讯实现数据的发送和接收

《如何使用C#串口通讯实现数据的发送和接收》本文详细介绍了如何使用C#实现基于串口通讯的数据发送和接收,通过SerialPort类,我们可以轻松实现串口通讯,并结合事件机制实现数据的传递和处理,感兴趣... 目录1. 概述2. 关键技术点2.1 SerialPort类2.2 异步接收数据2.3 数据解析2.

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

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

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

SpringBoot使用Apache Tika检测敏感信息

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