STM32串口通讯USART

本文对比了STM32 USART窗口通讯中基于寄存器和固件库的编程差异,并深入剖析了C语言中全局变量、局部变量、堆和栈的内存分布。通过实例展示了STM32程序中堆栈、全局区与静态区的内存分配,揭示了嵌入式开发中关键内存区域的工作原理。

一、STM32的USART窗口通讯程序

(一)基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异?
答:固件库就是函数的集合,固件库函数的作用就是:向下负责与寄存器直接打交道,向上提供用户函数调用的接口(API)。对于STM32这种级别的MCU,数百个寄存器记起来何谈容易,于是推出了官方固件库,固件库将这些寄存器底层操作都封装起来,提供一套API供开发者使用。大多数情况下,你不需要知道操作的是哪个寄存器,你只需要知道调用哪些函数即可。
(二)STM32的USART窗口通讯程序
1、打开keil5创建一个工程,新建NVIC.h、NVIC.c、User_USART.h、User_USART.c、main.c 5个文件
在这里插入图片描述
2、从STM32官方库的例子中将stm32f10x_it.c、stm32f10x_it.h、stm32f10x_conf.h拷贝到自己的工程目录下
在这里插入图片描述
3、敲入代码
NVIC.h
在这里插入图片描述
NVIC.c
在这里插入图片描述
User_USART.h
在这里插入图片描述
User_USART.c
在这里插入图片描述
main.c
在这里插入图片描述
4、运行main.c函数
在这里插入图片描述
5、把程序烧录到stm32f103核心板
通过ST-link连接stm32核心板,下载官方STM32 STLink驱动

点击如图图标(keil5)
在这里插入图片描述
烧录完成
在这里插入图片描述
运行仿真
点击如图图标
在这里插入图片描述
运行仿真
在这里插入图片描述
6、下载官方野火串口调试助手
在这里插入图片描述
7、或者用烧录软件烧录.hex文件
(BOOT0接高电平,BOOT1接低电平)
在这里插入图片描述
8、通过串口转接线连接stm32核心板和电脑
在这里插入图片描述
(引脚A9 TX和A10 RX接出来,另外两根接地GND和3.3V电压)
在这里插入图片描述
9、打开野火调试助手
打开串口,开始发送数据
在这里插入图片描述
发送Stop,stm32停止发送。
在这里插入图片描述

二、C语言程序里全局变量、局部变量、堆、栈

1、打开ubuntu里的vscode编译器
2、下载Code Runner插件(多一个运行三角标)
在这里插入图片描述
可以直接运行编译好的程序。

3、敲入如下代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void before()
{

}

char g_buf[16];
char g_buf2[16];
char g_buf3[16];
char g_buf4[16];
char g_i_buf[]=“123”;
char g_i_buf2[]=“123”;
char g_i_buf3[]=“123”;

void after()
{

}

int main(int argc, char **argv)
{
char l_buf[16];
char l_buf2[16];
char l_buf3[16];
static char s_buf[16];
static char s_buf2[16];
static char s_buf3[16];
char *p_buf;
char *p_buf2;
char *p_buf3;

    p_buf = (char *)malloc(sizeof(char) * 16);
    p_buf2 = (char *)malloc(sizeof(char) * 16);
    p_buf3 = (char *)malloc(sizeof(char) * 16);

    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);

    printf("g_i_buf: 0x%x\n", g_i_buf);
    printf("g_i_buf2: 0x%x\n", g_i_buf2);
    printf("g_i_buf3: 0x%x\n", g_i_buf3);

    printf("l_buf: 0x%x\n", l_buf);
    printf("l_buf2: 0x%x\n", l_buf2);
    printf("l_buf3: 0x%x\n", l_buf3);

    printf("s_buf: 0x%x\n", s_buf);
    printf("s_buf2: 0x%x\n", s_buf2);
    printf("s_buf3: 0x%x\n", s_buf3);

    printf("p_buf: 0x%x\n", p_buf);
    printf("p_buf2: 0x%x\n", p_buf2);
    printf("p_buf3: 0x%x\n", p_buf3);

    printf("before: 0x%x\n", before);
    printf("after: 0x%x\n", after);
    printf("main: 0x%x\n", main);

    if (argc > 1)
    {
            strcpy(l_buf, argv[1]);
    }
    return 0;

}
3、运行代码
在这里插入图片描述
结果如下:
g_buf: 0x11c6f030
g_buf2: 0x11c6f040
g_buf3: 0x11c6f050
g_buf4: 0x11c6f060
g_i_buf: 0x11c6f010
g_i_buf2: 0x11c6f014
g_i_buf3: 0x11c6f018
l_buf: 0xf4a33e90
l_buf2: 0xf4a33ea0
l_buf3: 0xf4a33eb0
s_buf: 0x11c6f070
s_buf2: 0x11c6f080
s_buf3: 0x11c6f090
p_buf: 0x121d1260
p_buf2: 0x121d1280
p_buf3: 0x121d12a0
before: 0x11a6e74a
after: 0x11a6e751
main: 0x11a6e758
4、结论:
栈:地址向下递增
堆:地址向上递增
全局变量
静态变量,地址向下递增
全局变量,地址向上递增
函数,地址向上递增

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

1、继续使用一中的串口通讯代码
2、在main.c函数中stm32中定义了全局变量和局部变量
在这里插入图片描述
3、烧录.hex文件到stm32芯片中
4、打开调试助手,打开串口
在这里插入图片描述
可以看出:前3个局部变量储存到了栈中,它们地址依次减小,后三个全局变量储存到了静态区,它们地址依次增加。
5、再次修改main.c函数,定义了静态变量和指针
在这里插入图片描述
6、打开串口
在这里插入图片描述
可以看出:前三个静态变量储存到了静态区,地址依次增加。
后三个指针储存到了堆中,地址依次增加。
7、结论
在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区、堆区、全局区(静态区)、常量区、代码区,其中全局区中高地址分布着.bss段,低地址分布着.data段。
在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等风来1249

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值