STM32串口通信

一、基于寄存器与基于固件库编写的差异

固件库编写方式,特点是简单易于理解,资料多。新手适合用这种方式入门。
寄存器的可移植性强,更贴近底层,要求对外设的工作原理和运行机理有更深的理解。

二、stm32串口通信实战

1.烧录方式

我使用的是stm32f103指南者,从电脑中下载程序到stm32有两种方式:
1.使用仿真线下载程序;(需要仿真线)
2.使用串口下载程序;(已经快被淘汰了,由于只需要一根USB线,所以在没有仿真线的情况下,还是实用)

接下来我使用的是第二种方法。
先下载图中圈出的三个压缩包
在这里插入图片描述

链接: 野火STM32F103指南者开发板.
提取码:pmf1
失效了就去这里找到stm32f013指南者点进去下:
链接: 野火所有产品资料下载链接.

然后用usb线把stm32开发板和电脑相连接,stm32端连接的 ‘usb转串口’这个接口,再打开stm32开关,可以看到红色的小灯亮起。
在这里插入图片描述
开发板上有黄色的跳帽,是相当于导线的作用,此处要求BOOT0和BOOT1接地,RXD接A9,TXD接A10,开发板买来默认就是这样接的,所以不需要改动。
在这里插入图片描述

连接过后打开CH341SER.EXE,点击安装,显示安装成功即可。
在这里插入图片描述
然后打开串口下载助手mcuisp
在这里插入图片描述
按如下方式配置:①搜索串口,设置波特率 115200(尽量不要设置的太高) ,②选择要下载的 HEX 文件、③校验、编程后执行、④DTR 低电平复位,RTS 高电平进入 bootloader、⑤开始编程。(前4步一定要调试正确,否则可能连接不上)
在这里插入图片描述

2.代码及效果图

该处串口通信实现以下功能:
1)设置波特率为115200,1位停止位,无校验位。

2)STM32系统给上位机(win10)连续发送“hello windows!”,

3)当上位机给stm32发送“Stop stm32!”后,stm32停止发送。

此处的代码在野火的代码模板上改动。
先在前面的百度云链接中下载模板
在这里插入图片描述
解压后打开第21个串口通信文件中的USART1接发中的工程文件
在这里插入图片描述
在这里插入图片描述然后把其中stm32f10x_it.c文件的串口中断服务函数部分改为如下:

int i=0;
uint8_t ucTemp[50];
void DEBUG_USART_IRQHandler(void)
{
	if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
	{
		ucTemp[i] = USART_ReceiveData(USART1);	
	}
  if(ucTemp[i] == '!')
	{
		if(ucTemp[i-1] == '2'&&ucTemp[i-2] == '3'&&ucTemp[i-3] == 'm'&&ucTemp[i-4] == 't'&&ucTemp[i-5] == 's'&&ucTemp[i-6] == ' ')
			if(ucTemp[i-7] == 'p'&&ucTemp[i-8] == 'o'&&ucTemp[i-9] == 't'&&ucTemp[i-10] == 's')
			{
				printf("ÊÕµ½£¡");
        while(1);
			}
	}
	i++;
}

在这里插入图片描述
然后把main.c函数改为

#include "stm32f10x.h"
#include "bsp_usart.h"


void delay(uint32_t count)
{
	while(count--);
}
int main(void)
{	
  USART_Config();
  while(1)
	{	
		printf("hello windows 10!\n");
		delay(5000000);
	}	
}

在这里插入图片描述
然后就可以编译生成hex文件了,按照上面的方式把hex文件烧录到stm32中,然后打开最开始下载的串口调试助手,点击打开串口,即可以看到stm32发给电脑的信息
在这里插入图片描述
最终效果如下(停止命令中的感叹号是英文状态下的):
在这里插入图片描述

三、C语言程序里全局变量、局部变量、堆、栈等概念

看以下代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char g_buf[16];
char g_buf2[16];
char g_buf3[16];
char g_buf4[16];

int main()
{

        printf("g_buf: 0x%x\n", g_buf);
        printf("g_buf2: 0x%x\n", g_buf2);
        printf("g_buf3: 0x%x\n", g_buf3);
        printf("g_buf4: 0x%x\n", g_buf4);
        return 0;
 
 
}

该代码定义了4个全局变量并输出它们的地址,
在这里插入图片描述
它们储存到了全局区里,地址依次递增。

再看以下代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main()
{

        char l_buf[16];
        char l_buf2[16];
        char l_buf3[16];
        printf("l_buf: 0x%x\n", l_buf);
        printf("l_buf2: 0x%x\n", l_buf2);
        printf("l_buf3: 0x%x\n", l_buf3);
 
}

定义了4个局部变量,并输出它们的地址
在这里插入图片描述
它们的地址也是递增的,暂时不知道储存到了哪里。(我在ubuntu定义的所有变量地址都是递增,可能是cpu的关系)

四、stm32的堆、栈、全局变量的分配地址

仍然使用之前野火的串口通信模板,把main.c(分别在stm32中定义了全局变量和局部变量,并把它们的地址返回给windows)改为如下:

#include "stm32f10x.h"
#include "bsp_usart.h"

char global1[16];
char global2[16];
char global3[16];
	
int main(void)
{	
	char part1[16];
  char part2[16];
  char part3[16];

  USART_Config();

  printf("part1: 0x%p\n", part1);
  printf("part2: 0x%p\n", part2);
  printf("part3: 0x%p\n", part3);
	 
  printf("global1: 0x%p\n", global1);
  printf("global2: 0x%p\n", global2);
  printf("global3: 0x%p\n", global3);
  while(1)
	{	
		
	}	
}

生成hex文件后,烧录到stm32中,打开串口调试助手,点击打开串口,然后点击stm32上的reset按钮,就可以看到如下结果。
在这里插入图片描述
前3个part变量为局部变量,它们储存到了栈中,地址依次减小。
后三个global为全局变量,它们储存到了静态区,地址依次增加。

再试试以下函数(定义了静态变量和指针),

#include "stm32f10x.h"
#include "bsp_usart.h"
#include <stdlib.h>

int main(void)
{	
  static char st1[16];
  static char st2[16];
  static char st3[16];
  char *p1;
  char *p2;
  char *p3;

 
  USART_Config();

  printf("st1: 0x%p\n", st1);
  printf("st2: 0x%p\n", st2);
  printf("st3: 0x%p\n", st3);
	 
  p1 = (char *)malloc(sizeof(char) * 16);
  p2 = (char *)malloc(sizeof(char) * 16);
  p3 = (char *)malloc(sizeof(char) * 16);
	
  printf("p1: 0x%p\n", p1);
  printf("p2: 0x%p\n", p2);
  printf("p3: 0x%p\n", p3);
  while(1)
	{	
		
	}	
}

在这里插入图片描述
前三个静态变量储存到了静态区,地址依次增加。
后三个指针储存到了堆中,地址依次增加。(堆栈具体知识请看参考博客)

结合两次结果看(针对于测试的3个区域),可以大概看出栈在顶层(地址最大),然后依次是堆,静态区。对比以下地址分配图,大致符合。
在这里插入图片描述

参考博客:
C语言中,局部变量、全局变量、静态变量、堆、栈的内存地址.
C/C++程序内存的各种变量存储区域和各个区域详解.

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
STM32串口通信是MCU最基本的通信方式之一。串口通信是一种串行通信方式,与并行通信相对应。在STM32串口通信主要通过USART模块实现。USART是一种通用的同步/异步收发器,它包含了用于串口通信的相关寄存器和功能。通过配置USART的寄存器,可以实现不同的串口通信参数设置,如波特率、数据位数、停止位数等。在STM32,常用的串口通信引脚是USART1、USART2等。为了实现串口通信,可以使用USB转串口模块,其常用的电平转换芯片有CH340、PL2303、CP2102、FT232等。这些芯片可以将USB接口转换为串口接口,实现设备与电脑之间的通信。 #### 引用[.reference_title] - *1* *2* [STM32-串口通信详解](https://blog.csdn.net/qq_44016222/article/details/123280806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [【stm32串口通信](https://blog.csdn.net/weixin_51914919/article/details/123320229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值