我是靠谱客的博主 丰富方盒,最近开发中收集的这篇文章主要介绍新手小白尝试STM32串口通讯一、差异说明二、STM32的USART窗口通讯程序三、C语言程序各种变量存储区域和各个区域四、STM32系统下编程的变量地址空间验证,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 一、差异说明
  • 二、STM32的USART窗口通讯程序
    • 1.安装驱动
    • 2.安装调试助手
    • 3.串口通信的验证
  • 三、C语言程序各种变量存储区域和各个区域
    • 1.简介
    • 2.演示
  • 四、STM32系统下编程的变量地址空间验证

新手小白入门,课程作业要求,慎重参考

作业要求

1.说明基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异。

2.完成STM32的USART窗口通讯程序,要求:
1)设置波特率为115200,1位停止位,无校验位。
2)STM32系统给上位机(win10)连续发送“hello windows!”,上位机接收程序可以使用“串口调试助手“,也可自己编程。
3)当上位机给stm32发送“Stop,stm32”后,stm32停止发送。

3.重温C语言程序里全局变量、局部变量、堆、栈等概念,并在ubuntu系统中编程,输出信息进行验证;

4.重温C语言程序里全局变量、局部变量、堆、栈等概念,在Keil中针对stm32系统进行编程,调试变量,进行验证; 通过串口输出信息到上位机,进行验证。

一、差异说明

···外设库函数的调用与直接配置寄存器相比,从执行效率上看会有额外的消耗:初始化变量赋值的过程、库函数在被调用的时候要耗费调用时间;在函数内部,对输入参数转换所需要的额外运算也消耗一些时间。
···基于寄存器方式的开发有具体参数更直观、程序运行占用资源少的优点,但是这种方式开发速度慢、程序可读性差、维护复杂,带来了比较高的维和和交流成本,所以一般只有在频繁调用的中断服务函数时利用直接配置寄存器的方式。
···基于固态库方式开发,也就是直接调用库函数具有外设交流方便、查错简单、对主控制器STM32上手简单的特点

二、STM32的USART窗口通讯程序

工具准备:
开发板:野火指南者(STM32F103VE)带3.2寸屏
软件:5.0版本以上的Keil
USBQ驱动:CH340
串口调试助手版本:v1.0.1.5

1.安装驱动

在野火资料包里找USB转串口驱动_CH340安装
链接:https://pan.baidu.com/s/1BbiJWIyq-ff7LT5c6319tw
提取码:i7tp
复制这段内容后打开百度网盘手机App,操作更方便哦
解压双击安装即可(安装前需要确保板子和电脑连接正常)
在这里插入图片描述

2.安装调试助手

同样的,还是在资料包里下载串口_网络_电机多功能调试助
链接:https://pan.baidu.com/s/1ypO2vPWOSxGrIw3nq4h3TA
提取码:vkbw
复制这段内容后打开百度网盘手机App,操作更方便哦
解压好后打开fireTools即可(建议添加快捷方式到桌面)
在这里插入图片描述
打开后是这个样子
在这里插入图片描述

3.串口通信的验证

(1)依旧是野火家的资料包,在配套例程里面找到串口通信的文件夹打开工程文件即可
在这里插入图片描述
(2)改代码
①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);
	}	
}


(3)编译生成hex文件
在这里插入图片描述
(4)将电脑与板子通过ST-LINK线连接起来,打开设备管理器查看是否连接成功
在这里插入图片描述
(5)烧录程序
点击魔法棒设置Debug
在这里插入图片描述
再点击Settings设置port为SW
在这里插入图片描述
点工具栏编译旁边的在这里插入图片描述下载烧录
(6)观察
打开串口调试助手
点击“打开串口”即为显示stm32正在向上机位发送消息
在这里插入图片描述
当我们输入“stop stm32!”时,显示“收到”,stm32停止发送消息
在这里插入图片描述

三、C语言程序各种变量存储区域和各个区域

1.简介

在CC++中,通常可以把内存理解为4个分区:栈、堆、全局/静态存储区和常量存储区:
1 内存栈区stack: 存放局部变量名;
2. 内存堆区heap: 存放new或者malloc出来的对象;
3. Text & Data & Bss:代码段与静态分配
4. BSS区(未初始化数据段):并不给该段的数据分配空间,仅仅是记录了数据所需空间的大小。
5.DATA(初始化的数据段):为数据分配空间,数据保存在目标文件中。

2.演示

.c程序的执行也就是静态的文件加载到内存下的过程,
内存属性有两种:(1)静态分配内存:是在程序编译和链接时就确定好的内存;(2)动态分配内存:是在程序加载、调入、执行的时候分配/回收的内存。
由.c文件的执行也可以验证得到:
(1)栈的地址是向下增长
(2)堆的地址是向上增长
(3)静态变量是地址向下增长
(4)全局常量是地址向上增长
(5)函数的地址向上增长
(6)而由函数,一直到栈区,地址总体是从低地址到高地址,逐步递增的。

接下来在虚拟机演示一下
在Ubuntu写.c文件

#include <stdio.h>
#include <stdlib.h>
int k1 = 1;
int k2;
static int k3 = 2;
static int k4;
int main( )
{   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);
    free(p1);
    free(p2);
    printf("栈区-变量地址n");
    printf("                i:%pn", &i);
    printf("                p:%pn", &p);
    printf("              str:%pn", str);
    printf("n堆区-动态申请地址n");
    printf("                   %pn", p1);
    printf("                   %pn", p2);
    printf("n.bss段n");
    printf("全局外部无初值 k2:%pn", &k2);
    printf("静态外部无初值 k4:%pn", &k4);
    printf("静态内部无初值 m2:%pn", &m2);
    printf("n.data段n");
    printf("全局外部有初值 k1:%pn", &k1);
    printf("静态外部有初值 k3:%pn", &k3);
    printf("静态内部有初值 m1:%pn", &m1);
    printf("n常量区n");
    printf("文字常量地址     :%pn",var1);
    printf("文字常量地址     :%pn",var2);
    printf("n代码区n");
    printf("程序区地址       :%pn",&main);
    return 0;
}

编译运行
在这里插入图片描述

四、STM32系统下编程的变量地址空间验证

(1)将前面串口用过的工程打开(以防万一可以复制一个副本)
修改main.c代码,分别在stm32中定义全局变量和局部变量,并把它们的地址返回给上位机

#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%pn", part1);
  printf("part2: 0x%pn", part2);
  printf("part3: 0x%pn", part3);
	 
  printf("global1: 0x%pn", global1);
  printf("global2: 0x%pn", global2);
  printf("global3: 0x%pn", global3);
  while(1)
	{	
		
	}	
}

跟目录前面二3.串口通信验证一样烧录程序
在这里插入图片描述
part1、part2、part3为栈中的局部变量,地址逐渐减小。
global1、global2、global3为静态区中的全局变量,地址逐渐增加。
(2)再改main.c,定义静态变量和指针,并返回它们的地址给上位机。

#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%pn", st1);
  printf("st2: 0x%pn", st2);
  printf("st3: 0x%pn", st3);
	 
  p1 = (char *)malloc(sizeof(char) * 16);
  p2 = (char *)malloc(sizeof(char) * 16);
  p3 = (char *)malloc(sizeof(char) * 16);
	
  printf("p1: 0x%pn", p1);
  printf("p2: 0x%pn", p2);
  printf("p3: 0x%pn", p3);
  while(1)
	{	
		
	}	
}

再烧
在这里插入图片描述
st1、st2、st3都是静态变量,他们的地址依次增加。
p1、p2、p3是堆中的指针,他们的地址也是依次增加。

最后

以上就是丰富方盒为你收集整理的新手小白尝试STM32串口通讯一、差异说明二、STM32的USART窗口通讯程序三、C语言程序各种变量存储区域和各个区域四、STM32系统下编程的变量地址空间验证的全部内容,希望文章能够帮你解决新手小白尝试STM32串口通讯一、差异说明二、STM32的USART窗口通讯程序三、C语言程序各种变量存储区域和各个区域四、STM32系统下编程的变量地址空间验证所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部