本文目录

  • 一.说明基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异?
  • 二.完成STM32的USART窗口通讯程序,要求如下:
    • 1.如何进行烧录
    • 2.代码执行及其运行结果
  • 三.学习C语言程序里全局变量、局部变量、堆、栈等概念,并在ubuntu系统中编程,输出信息进行验证;
    • 1.C语言在内存中有哪几个区域?
    • 2.一个由c/C++编译的程序占用的内存有哪几个部分?
    • 3.例子程序如下:
    • 4.关于C语言中关键字volatile的相关问题
  • 四.在Keil中针对stm32系统进行编程,调试变量,进行验证; 通过串口输出信息到上位机,进行验证。

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

1.寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。基于寄存器来进行流水灯的编程,它更贴近底层,对外设的工作原理和运行机理会有更深的理解。
2.STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。基于这种方式进行流水灯的编程,会比较简单,易于编程,因为目前比较多的例程是使用固件库编写的。

二.完成STM32的USART窗口通讯程序,要求如下:

1)设置波特率为115200,1位停止位,无校验位。

2)STM32系统给上位机(win10)连续发送“hello windows!”,上位机接收程序可以使用“串口调试助手“,也可自己编程。

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

1.如何进行烧录

(1)我们使用的是野火指南针开发板,配套有相应的教程,其板子连接电脑如下所示:

(2)打开mcuisp助手


(3)进行如下操作即可将文件烧录进去
1.搜索串口
2.选择要下载的HEX文件
3.校验、编程后执行
4.DTR 低电平复位,RTS 高电平进入 bootloader
5.开始进行串口执行

2.代码执行及其运行结果

(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++;
}


(3)将主函数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);}
}


(4)编译生成hex文件

(5)将上述HEX文件烧录到助手当中,进行编程后,打开串口调试助手,点击打开串口,即可以看到stm32发给电脑的信息了
烧录成功:

串口助手调试:

停止发送:

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

1.C语言在内存中有哪几个区域?

  1. 内存栈区: 存放局部变量名;
  2. 内存堆区: 存放new或者malloc出来的对象;
  3. 常数区: 存放局部变量或者全局变量的值;
  4. 静态区: 用于存放全局变量或者静态变量;
  5. 代码区:二进制代码。

2.一个由c/C++编译的程序占用的内存有哪几个部分?

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(RW), 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(ZI)。 - 程序结束后有系统释放
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 (RO)
5、程序代码区—存放函数体的二进制代码。 (RO)

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

源代码如上,其在ubantu中运行结果如下所示:

我们可以看到从低地址到高地址,如图:

4.关于C语言中关键字volatile的相关问题

Volatile这个关键字的必要性(真正意义之所在)
但其他程序(例如内核程序或一个中断)修改了内存中该变量的值,此时寄存器R中的值并不会随之改变而更新,由于优化器的作用编译器仍然去利用之前存放在寄存器R中的值,而不去寻址内存中的值(但我们必须改变这个变量的值)。为了解决这种情况C语言就引入了volatile限定词,让代码在引用该变量时多费一点劲儿,再去内存中取出该变量的值。
Volatile和register的对比
volatile 跟以前的 register 相反。 register 告诉编译器尽量将变量放到寄存器中使用, 而volatile 强制将更改后的值写回内存。如果不写回内存,对于一些全局共享的变量,可能导致不一致问题。
Volatile关键字应用的三个地方
1、 修改硬件寄存器,尤其是状态寄存器
大家都知道,在硬件级别,如果寄存器值自动改变了,编译器是不会主动发现的。经过编译器的自动优化,我们读到的都是寄存器中存储的旧的状态寄存器的值, 而非最新的状态寄存器值。
2、 多线程中被几个线程共享的变量
线程修改共享变量var是不会通知编译器的。所以线程A坚持不懈地读着var在寄存器或者cache中的副本,读出来的内容是0, 但很可惜,线程B早就把var变量给修改为1了。鉴于此,我们必须加上volatile这个关键字来解决这个问题。
3、 中断服务程序ISR当中用
ISR:中断服务程序 (interrupt service routine)

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

用第二大点的串口通信模板,我们将main.c主函数改为如下所示:

#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){ }
}


其运行结果如下所示:

我们可以看到:
前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个区域),可以大概看出栈在顶层(地址最大),然后依次是堆,静态区。
总结:
在一个STM32程序代码中,从内存高地址到内存低地址,依次分布着栈区、堆区、全局区(静态区)、常量区、代码区,其中全局区中高地址分布着.bss段,低地址分布着.data段。
总的分布如下所示:

一、栈区(stack)

临时创建的局部变量存放在栈区。

函数调用时,其入口参数存放在栈区。

函数返回时,其返回值存放在栈区。

const定义的局部变量存放在栈区。

2、堆区(heap)

堆区用于存放程序运行中被动态分布的内存段,可增可减。

可以有malloc等函数实现动态分布内存。

有malloc函数分布的内存,必须用free进行内存释放,否则会造成内存泄漏。

3、全局区(静态区)

全局区有.bss段和.data段组成,可读可写。

4、.bss段

未初始化的全局变量存放在.bss段。

初始化为0的全局变量和初始化为0的静态变量存放在.bss段。

.bss段不占用可执行文件空间,其内容有操作系统初始化。

5、.data段

已经初始化的全局变量存放在.data段。

静态变量存放在.data段。

.data段占用可执行文件空间,其内容有程序初始化。

const定义的全局变量存放在.rodata段。

6、常量区

字符串存放在常量区。

常量区的内容不可以被修改。

7、代码区

程序执行代码存放在代码区。

字符串常量也有可能存放在代码区。

STM32串口通讯初步学习相关推荐

  1. K210学习笔记(五)——MAIX BIT(K210)与STM32串口通讯

    前言 uart 模块主要用于驱动开发板上的异步串口,可以自由对 uart 进行配置.k210 一共有3个 uart,每个 uart 可以进行自由的引脚映射. 一.MAIX BIT串口使用步骤 1.引脚 ...

  2. 作业—STM32串口通讯

    STM32串口通信 一.基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异 二.STM32的USART窗口通讯程序 1.烧录代码 2.代码 3.效果图 三.c语言程序里全局变量. ...

  3. stm32串口通讯问题

    stm32串口通讯问题 在串口试验中,串口通讯不正常,则可能会出现以下问题: 1. 配置完成后,串口没有任何消息打印. 原因:1,端口配置有问题,需要重新检查I/O口的配置 2,接线有问题,检查接线是 ...

  4. 串口通讯助手学习交流

    串口通讯助手学习交流 最近花了一些时间用C#写了一个串口通讯助手,因为工作中用到了串口通信,最开始是用C++中的MFC写的,后面觉得C#更方便一些,使用的都是SerialPort类:而且我的C#也是自 ...

  5. STM32 —— 串口通讯

    STM32 -- 串口通讯 什么是串口通讯 串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,其通讯协议可分层 ...

  6. STM32—串口通讯详解

    串口通讯目录 物理层 协议层 USART简介 开发板与上位机的连接 代码讲解: 一.初始化结构体 二.NVIC配置中断优先级 三.USART配置函数讲解 四.传输数据的函数: 1.发送一个字节 2.发 ...

  7. STM32串口通讯实现——USB转串口

    一.RS232,TTL简介 RS232是个人计算机的通讯接口之一,一般会有两组RS323接口,分别为COM1和COM2,电平标准为+12V为逻辑负,-12为逻辑正. TTL电平为5V为逻辑正,0为逻辑 ...

  8. STM32串口通讯数据丢失原因分析及解决办法

    在进行串口通讯实验时,一时不仔细可能会发现通讯不正常,数据丢失的现象,包括丢失第一个字符,或只收到最后一个字符等等,本文接下来将就这类问题展开讨论. 首先是通过MCU向上位机发送数据: 若程序如下图所 ...

  9. 嵌入式作业(六):STM32串口通讯

    目录 一.基于寄存器与基于固件库的编程方式有什么差异. 二.STM32的USART窗口通讯程序 1.烧录代码的方式 2.代码及效果图 三.C语言程序里全局变量.局部变量.堆.栈等概念 四.stm32的 ...

  10. Stm32串口通讯的几种方式及其优缺点

    1.延时等待 原理:串口发送指令/数据之后,通过延时函数延时一定时间,等待从机的响应. 优点:实现简单,对于快速相应和长度不长的通讯可以使用此方法 缺点:(1)在非实时环境中,由于延时的存在会影响系统 ...

最新文章

  1. tensorflow 代码调试工具tfdbg的用法
  2. 儿童吹泡泡水简单配方_儿童吹泡泡水简单配方[组图]
  3. mysql里添加不了中文_为什么MySQL不能添加中文
  4. alias怎么每次登陆都保存_alias命令使用说明
  5. cf1553E. Permutation Shift
  6. 小米海外召回有潜在风险的电动滑板车 中国区无此风险
  7. 商业有规律,赚钱有方法,不要在盲目努力了
  8. Git教程——回到从前 (checkout 针对单个文件)
  9. 线代总结1 线性代数中的线性方程组
  10. DevExpress GridView 排序状态下新增行不参与排序
  11. 英伟达显卡老版本驱动下载网址
  12. 想定制Android系统实现改机?看完我也会了
  13. opencv手动实现运动目标检测
  14. VR系列——Oculus最佳实践:七、虚拟幻境头晕(下)
  15. 朋友圈点赞、发红包 测试用例的设计点
  16. 基于layui 2.*省市级三级联动
  17. 【职业规划】第一篇:程序员分级之初级程序员
  18. 微信小程序:2022强大的修复版趣味心理测试小程序源码,趣味测试引流裂变神器,流量主激励广告实现管道收益
  19. NVT 异常开机log
  20. online operating system 网页操作系统(web操作系统简称Webos) 小调查

热门文章

  1. 蚂蚁课堂学习笔记之springAop和Ioc
  2. android刷成苹果手机版下载地址,安卓怎么刷苹果系统 安卓变苹果系统方法教程...
  3. 北师计算机应用基础开放作业,北师大计算机应用基础开放作业答案
  4. php中没有 simhei.ttf,linux虚拟主机jpgraph找不到simhei.ttf字体
  5. Fortran入门教程(十)——结构体
  6. 21年,周杰伦越发孤独
  7. 计算机界面视频录制软件,怎么进行电脑界面上的画面录制,推荐下好用的电脑录屏软件呗...
  8. 情人节送对象什么礼物好?适合送男友的礼物
  9. 火狐firebug,firepath以及Selenium IDE插件安装方法
  10. 如何在整个数据库中查寻一条数据?