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

Posted nsnsnbabsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于串口助手的STM32与计算机进行串口通信相关的知识,希望对你有一定的参考价值。

基于串口助手的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;t<len&&USART_RX_BUF[t]==stop[t];hcr++,t++)
				if (hcr>=10) hcr=0;break;
				
				
			for(t=0;t<len;t++)
			 
				USART_SendData(USART1, USART_RX_BUF[t]);//Ïò´®¿Ú1·¢ËÍÊý¾Ý
				
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//µÈ´ý·¢ËͽáÊø
			
			printf("\\r\\n\\r\\n");//²åÈë»»ÐÐ
			USART_RX_STA=0;
		
		
		else
		
			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 <stdlib.h>
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;t<len&&USART_RX_BUF[t]==stop[t];hcr++,t++)
				if (hcr>=10) hcr=0;break;
				
				
			for(t=0;t<len;t++)
			 
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
			
			printf("\\r\\n\\r\\n");//插入换行
			USART_RX_STA=0;
		
		
		else
		
			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生活剪影很期待您的关注,我们一起进步。

以上是关于基于串口助手的STM32与计算机进行串口通信的主要内容,如果未能解决你的问题,请参考以下文章

基于STM32F103入门4——串口通信

基于STM32F103入门4——串口通信

基于STM32F103入门4——串口通信

基于stm32的温湿度检测案例串口通信屏显示

基于stm32的温湿度检测案例串口通信屏显示

基于stm32的温湿度检测案例串口通信屏显示