基于串口助手的STM32与计算机进行串口通信

您所在的位置:网站首页 ttl串口通信 基于串口助手的STM32与计算机进行串口通信

基于串口助手的STM32与计算机进行串口通信

2024-01-05 16:30| 来源: 网络整理| 查看: 265

基于串口助手的STM32与计算机进行串口通信 序 言 一. 串口通信概述二.项目说明三.实战过程 1)实现stm32向上位机发送字符 2)实现stm32发和收3)Keil中针对stm32系统进行编程,调试变量,进行验证; 通过串口输出信息到上位机,进行验证。 四. 结语

序 言

博主在这里会为大家介绍stm32串口通信的实战经历,我们会一起学习以下内容: (1)串口通信的概念 (2)串口通信的双向通信实战= 我们用到的工具有: 串口助手: stm32最小系统板: usb转TTL J-LINk下载器 在这里插入图片描述

一. 串口通信概述

(一)串口 串口是串行接口 (Serial Interface)的简称,它是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信(可以直接利用电话线作为传输线),从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。串行通讯的特点是:数据位的传送,按位顺序进行,最少只需一根传输线即可完成;成本低但传送速度慢。串行通讯的距离可以从几米到几千米;根据信息的传送方向,串行通讯可以进一步分为单工、半双工和全双工三种。

(二)协议 所谓协议,就是通信双方约定好的规定,通信双方只有遵守这个规定才能够完成任务。举个栗子就是周幽王烽火戏诸侯,双方约定好以烽火为信号进行通信,但是愚蠢的周幽王为博美人褒姒一笑破坏了这个规定,最后付出的代价是惨重的。可见,通信双方只有遵守协议才能够完成通信。

(三)时序 时序就是协议的实际化,它实质上是一些列的脉冲信号,通信双方将信息按照预先定好的规定(协议)转换成一系列的脉冲信号,通过总线发送给接收方,接收方再将接收到的数据按照规定进行解析,从而得到发送方发送过来的数据。

(四)上位机 上位机和下位机其实是一个相对的概念,上位机指的是可以直接发出操控命令的计算机,一般指PC机,能够显示各种信号变化(液压,水位,温度等),能够将信息直接传递给人。下位机是直接控制设备获取设备状况的计算机,一般是PLC/单片机single chip microcomputer/slave computer/lower computer之类的,下位机需要PC机来对其进行控制。

关于USART stm32有丰富的通讯外设,USART(Universal Synchronous Asynchronous Receiver Transmitter)、SPI(Serial Peripheral interface)、I2c(Inter-Integrated Circuit)、CAN(Controller Area Network),因为stm32有完整的且强大的固件库,这使得配置串口的难度大大降低了,和用软件IO口模拟通信时序相比,硬件的支持可以大大提高通信的速率、大大降低出错的概率,从而提高了通信的质量和效率。用IO口模拟USART难度较大,它对延时要求比较苛刻,且出错的概率较大,所以一般很少用IO口模拟USART。IO口模拟I2c比较常见,由于I2c的最高通信速度只有3.4M/s,单片机的IO口速度可以完美驾驭。由于SPI多用于一些较高速的通信,例如LCD、OLED、TFT显示器的写入,EEPROM (Electrically Erasable Programmable read only memory)的写入和读取,用IO口模拟效果不是很理想,所以建议使用硬件自带接口。

接下来看一下我们实战的原理图 在这里插入图片描述

二.项目说明

目标: 1)STM32系统给上位机(win10)连续发送“hello windows!”,上位机接收程序可以使用“串口调试助手“, 2)当上位机给stm32发送“Stop,stm32”后,stm32停止发送。 我们的难点是第2部分,我们该如何给我们的STM32发送信息,让其停止发送

三.实战过程 1)实现stm32向上位机发送字符

博主思考,假如我们要实现我们要的那个效果,我们可以分几步来实现。首先,博主想到的是如何实现,stm32通过串口发送信息给我们的上位机,假如我们实现了这个过程,那后面的就不会那么难。 所以下面就是博主做的stm32的发送 博主遇到几个坑,一个是我们在连接串口的时候可能会显示串口不可用或者被占用,我们可以看一下后台有哪些程序也在占用我们的串口,关掉即可,但是博主比较倒霉,找了半天没有发现,所以博主只能重启电脑,果然有效。 在这里插入图片描述 这是主函数部分

#include "NVIC.h" #include "User_USART.h" #include "stm32f10x.h" int main(void) { User_USART_GPIO_Config(); User_NVIC_Config(); User_USART_Config(); while(1) { User_UART_Send_String(USART1, "HCR\n"); } }

具体代码可以看到文末 接下我们可以看一下我们的串口助手链接: 串口助手. 这是我一直在用的,我觉得他比较好用 在这里插入图片描述 这个我们直接打开就好了,我们的USB转TTL要插到电脑上,然后RX,TX’分别与stm32的P9和P10连接,注意我们的stm32要用USB上电能运行,然后按下面配置 对了如果我们插进去没有反应的话,大概率是没有安装驱动,我们不同类型的USB转TTL的驱动是不一样的,我们可以如下操作

在这里插入图片描述 找到然后安装驱动即可 在这里插入图片描述

然后就是我们的串口助手,如果有了驱动,会自动弹出串口,然后我们设波特率为115200 在这里插入图片描述 把程序烧进我们的stm32(比较简单,不详细讲) 在这里插入图片描述!

2)实现stm32发和收

现在我们已经实现了定时发送hello windows!,这个程序在打其他输入时,会原样输出,如下

在这里插入图片描述 这是我们的主函数,我们利用一个数组与我们的输入进行比较,假如是对的,我们会返回hcr=0,循环结束

#include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "usart.h" int hcr=1; int main(void) { char stop[]={'S','t','o','p',',','s','t','m','3','2'}; u16 t; u16 len; u16 times=0; delay_init(); //ÑÓʱº¯Êý³õʼ»¯ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶ uart_init(115200); //´®¿Ú³õʼ»¯Îª115200 LED_Init(); //LED¶Ë¿Ú³õʼ»¯ KEY_Init(); //³õʼ»¯Óë°´¼üÁ¬½ÓµÄÓ²¼þ½Ó¿Ú while(hcr) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//µÃµ½´Ë´Î½ÓÊÕµ½µÄÊý¾Ý³¤¶È printf("\r\nhello windows!:\r\n\r\n"); for(t=0;thcr=0;break;}} for(t=0;t times++; if(times%500==0) { printf("\r\ǶÈëʽ´®¿ÚʵÑé\r\n"); printf("hcr@2219491180qqcom\r\n\r\n"); } if(times%200==0){printf("hello windows!%d\n",hcr);hcr=1;} if(times%30==0)LED0=!LED0;//ÉÁ˸LED,ÌáʾϵͳÕýÔÚÔËÐÐ. delay_ms(10); } } }

在这里插入图片描述 ,最终,我们实现了全部的功能我们尝试输入Stop,stm32,我们可以看到我们的stm32停止发送 在这里插入图片描述

3)Keil中针对stm32系统进行编程,调试变量,进行验证; 通过串口输出信息到上位机,进行验证。

我还是用上面的代码魔改;了一下 在这里插入图片描述

#include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "usart.h" #include int hcr=1; int k1 = 1; int k2; static int k3 = 2; static int k4; int main(void) { static int m1=2, m2; int i = 1; char *p; char str[10] = "hello"; char *var1 = "123456"; char *var2 = "abcdef"; int *p1=malloc(4); int *p2=malloc(4); char stop[]={'S','t','o','p',',','s','t','m','3','2'}; u16 t; u16 len; u16 times=0; free(p1); free(p2); delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 KEY_Init(); //初始化与按键连接的硬件接口 while(hcr) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 printf("\r\nhello windows!:\r\n\r\n"); for(t=0;thcr=0;break;}} for(t=0;t times++; if(times%500==0) { printf("\r\n嵌入式串口实验\r\n"); printf("hcr@2219491180qqcom\r\n\r\n"); printf("栈区-变量地址\r\n"); printf(" i:%p\r\n", &i); printf(" p:%p\r\n", &p); printf(" str:%p\r\n", str); printf("\n堆区-动态申请地址\r\n"); printf(" %p\r\n", p1); printf(" %p\r\n", p2); printf("\r\n.bss段\r\n"); printf("\n全局外部无初值 k2:%p\r\n", &k2); printf("静态外部无初值 k4:%p\r\n", &k4); printf("静态内部无初值 m2:%p\r\n", &m2); printf("\r\n.data段\r\n"); printf("\n全局外部有初值 k1:%p\r\n", &k1); printf("静态外部有初值 k3:%p\r\n", &k3); printf("静态内部有初值 m1:%p\r\n", &m1); printf("\r\n常量区\n"); printf("文字常量地址 :%p\r\n",var1); printf("文字常量地址 :%p\r\n",var2); printf("\r\n代码区\n"); printf("程序区地址 :%p\n",&main); printf("\r\n end \r\n\r\n\r\n"); } if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行. delay_ms(10); } } }

这是串口助手上的输出 在这里插入图片描述 在这里插入图片描述 我们可以发现 栈:向低地址扩展 堆:向高地址扩展 bss 段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域; 数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域; 数据段属于静态内存分配

嵌入式串口实验 hcr@2219491180qqcom 栈区-变量地址 i:2000075c p:20000758 str:2000074c 堆区-动态申请地址 20000198 200001a0 .bss段 全局外部无初值 k2:20000008 静态外部无初值 k4:20000010 静态内部无初值 m2:20000018 .data段 全局外部有初值 k1:20000004 静态外部有初值 k3:2000000c 静态内部有初值 m1:20000014 常量区 文字常量地址 :080003ac 文字常量地址 :080003b4 代码区 程序区地址 :080001dd end hello windows!: Stop,stm32 四. 结语

这个实战对于我们了解串口通信有着重要的意义,所以博主在这里希望各位也要好好学习,争取掌握这个知识点。博主在这次的实践中发现了几个坑,一是,我们的串口助手可能对于我们的实验结果有影响,博主今天试了三个串口工具,其中有两个似乎有些小问题,但是上面那个串口工具对我们没影响,这博主也有点疑问。二是,博主在使用串口助手的时候还遇到过串口被占用的问题,搜了很多博主,但是还是没有解决,只能重启电脑,很麻烦。还有就是希望各位有问题可以联系博主,博主很乐意和各位一起学习。请您关注我个人的微信公众号,微信搜索h生活剪影很期待您的关注,我们一起进步。在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3