news 2026/4/18 6:36:55

STM32F03C8T6通过AT指令获取天气API-下篇

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F03C8T6通过AT指令获取天气API-下篇

这里写目录标题

  • 堆栈大小换算与修改说明
    • 一、十六进制到十进制的换算
      • 1.1 换算公式
      • 1.2 换算结果
    • 二、修改前后的对比
      • 修改前(原始配置):
      • 修改后(新配置):
    • 三、STM32F103C8T6的内存限制
    • 四、为什么需要调整堆栈大小?
      • 4.1 原始设置(1KB栈+0.5KB堆)的问题:
      • 4.2 建议设置(4KB栈+8KB堆)的好处:
    • 五、完整的startup文件修改示例
    • 六、不同内存需求对应的推荐配置
    • 七、验证堆栈是否足够的方法
      • 7.1 在代码中添加堆栈使用检查
      • 7.2 在Keil/IDE中查看内存使用
    • 八、针对您之前报错的解决方案
    • 九、修改建议总结

堆栈大小换算与修改说明

一、十六进制到十进制的换算

1.1 换算公式

十六进制到十进制换算: 0x400 = 4 × 16² = 4 × 256 = 1024 0x1000 = 1 × 16³ = 1 × 4096 = 4096 0x200 = 2 × 16² = 2 × 256 = 512 0x2000 = 2 × 16³ = 2 × 4096 = 8192

1.2 换算结果

十六进制十进制字节KB
0x40010241024字节1KB
0x100040964096字节4KB
0x200512512字节0.5KB
0x200081928192字节8KB

二、修改前后的对比

修改前(原始配置):

  • Stack_Size = 0x400 = 1KB(栈大小)
  • Heap_Size = 0x200 = 0.5KB(堆大小)
  • 总计:1.5KB RAM

修改后(新配置):

  • Stack_Size = 0x1000 = 4KB(栈大小)
  • Heap_Size = 0x2000 = 8KB(堆大小)
  • 总计:12KB RAM

三、STM32F103C8T6的内存限制

STM32F103C8T6的RAM大小为20KB(0x5000字节)

内存区域地址范围大小
总RAM0x20000000-0x20004FFF20KB
栈(Stack)向下生长4KB(修改后)
堆(Heap)向上生长8KB(修改后)
全局/静态变量中间区域8KB(剩余)
内存布局示意图(修改后): 0x20005000 ↑ │ 栈(Stack) - 4KB (向下生长) │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 0x20004000 ├─────────┤ │ 全局变量 │ │ 静态变量 │ │ 已分配内存 │ ├─────────┤ 0x20002000 ↑ │ 堆(Heap) - 8KB (向上生长) │ 0x20000000

四、为什么需要调整堆栈大小?

4.1 原始设置(1KB栈+0.5KB堆)的问题:

  1. 栈太小

    • 函数调用层次有限
    • 局部变量不能太大
    • 中断嵌套可能溢出
    • cJSON递归解析可能溢出
  2. 堆太小

    • cJSON动态分配内存不够
    • 网络数据缓冲区不足
    • 字符串操作受限
    • 无法使用标准库的malloc

4.2 建议设置(4KB栈+8KB堆)的好处:

  1. 栈(4KB)

    • 支持较深的函数调用
    • 可定义较大的局部数组
    • 中断处理更安全
    • 支持cJSON的递归解析
  2. 堆(8KB)

    • cJSON有足够内存解析完整JSON
    • 可创建较大的动态缓冲区
    • 支持标准库函数
    • 网络数据处理更灵活

五、完整的startup文件修改示例

; startup_stm32f103xe.s ; 堆栈配置部分 IF :DEF:__MICROLIB EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + Stack_Size) LDR R2, =(Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR ALIGN ENDIF ; ========================================================================== ; 修改前:Stack_Size EQU 0x00000400 ; 修改后:Stack_Size EQU 0x00001000 Stack_Size EQU 0x00001000 ; ← 修改这里,改为4KB AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp ; ========================================================================== ; 修改前:Heap_Size EQU 0x00000200 ; 修改后:Heap_Size EQU 0x00002000 Heap_Size EQU 0x00002000 ; ← 修改这里,改为8KB AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base Heap_Mem SPACE Heap_Size __heap_limit PRESERVE8 THUMB

六、不同内存需求对应的推荐配置

应用场景栈大小堆大小总RAM需求说明
裸机简单应用1KB0.5KB1.5KB无动态分配,简单控制
中等复杂度2KB4KB6KB有动态分配,简单网络
JSON解析+网络4KB8KB12KB推荐配置
FreeRTOS简单4KB8KB12KB+多任务需要更多栈
FreeRTOS复杂6KB12KB18KB+接近芯片极限

七、验证堆栈是否足够的方法

7.1 在代码中添加堆栈使用检查

// 在main.c中添加堆栈使用检查externuint32_t__heap_base;externuint32_t__heap_limit;externuint32_t__initial_sp;externuint32_t__StackTop;externuint32_t__StackLimit;voidcheck_stack_heap_usage(void){// 获取当前栈指针registeruint32_t*stack_ptrasm("sp");// 计算栈使用量uint32_tstack_top=(uint32_t)&__StackTop;// 栈顶uint32_tstack_usage=stack_top-(uint32_t)stack_ptr;uint32_tstack_free=(uint32_t)stack_ptr-(uint32_t)&__StackLimit;// 计算堆使用量uint32_theap_base=(uint32_t)&__heap_base;uint32_theap_limit=(uint32_t)&__heap_limit;printf("=== 内存使用情况 ===\r\n");printf("栈大小: %lu bytes (%.1fKB)\r\n",Stack_Size,Stack_Size/1024.0);printf("栈已用: %lu bytes\r\n",stack_usage);printf("栈剩余: %lu bytes\r\n",stack_free);printf("堆大小: %lu bytes (%.1fKB)\r\n",Heap_Size,Heap_Size/1024.0);printf("堆起始: 0x%08lX\r\n",heap_base);printf("堆结束: 0x%08lX\r\n",heap_limit);printf("===================\r\n");}// 在main函数中定期调用intmain(void){// 初始化...while(1){check_stack_heap_usage();HAL_Delay(10000);// 每10秒检查一次}}

7.2 在Keil/IDE中查看内存使用

1. 编译后查看.map文件 2. 查找以下信息: Total RO Size (Code + RO Data) xxxx Total RW Size (RW Data + ZI Data) xxxx Total ROM Size (Code + RO Data + RW Data) xxxx 3. RW + ZI ≈ RAM使用量

八、针对您之前报错的解决方案

您之前的编译错误确实与startup文件有关,但不是堆栈设置的问题,而是:

  1. 中文字符编码问题:字符串中的中文字符导致编译器无法识别
  2. 解决方案:使用纯ASCII字符的JSON字符串进行测试
// 错误的(有中文字符):char*json_data="{\"name\":\"合肥\",\"weather\":\"阴\"}";// 正确的(纯ASCII):char*json_data="{\"name\":\"Beijing\",\"weather\":\"Cloudy\"}";

九、修改建议总结

  1. 必须修改

    • Stack_Size: 0x400 → 0x1000 (1KB → 4KB)
    • Heap_Size: 0x200 → 0x2000 (0.5KB → 8KB)
  2. 原因

    • cJSON需要动态内存分配
    • 网络数据需要缓冲区
    • 函数调用需要栈空间
  3. 注意事项

    • STM32F103C8T6只有20KB RAM
    • 修改后总共使用12KB,还有8KB给全局变量
    • 实际使用中监控堆栈使用情况
  4. 如果还不够用

    • 优化代码,减少栈使用
    • 使用静态分配代替动态分配
    • 减少递归深度
    • 优化网络缓冲区大小

这样修改后,您的JSON解析和网络通信应该就能正常工作了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 22:09:15

(1-1)人形机器人的发展历史、趋势与应用场景:人形机器人的发展历程

本章首先系统介绍了人形机器人的发展脉络,从早期仿人研究到ASIMO等里程碑事件,再到特斯拉、Figure、宇树等企业推动的商业化进程,勾勒出人形机器人产业的演进全景。然后进一步分析了具身智能、大模型融合背景下的人形机器人发展趋势及其在劳动…

作者头像 李华
网站建设 2026/4/18 6:35:38

day143—递归—对称二叉树(LeetCode-101)

题目描述给你一个二叉树的根节点 root , 检查它是否轴对称。示例 1:输入:root [1,2,2,3,4,4,3] 输出:true示例 2:输入:root [1,2,2,null,3,null,3] 输出:false提示:树中节点数目在…

作者头像 李华
网站建设 2026/4/17 17:57:36

STM32-S184-车位感应+停车引导+闸道控制+车道防夹+计时计费+结算+OLED屏+声光报警+按键+(无线方式选择)(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫

STM32-S184-车位感应停车引导闸道控制车道防夹计时计费结算OLED屏声光报警按键(无线方式选择)STM32-S184N无无线-无APP板(硬件操作详细): STM32-S184B蓝牙无线-APP版: STM32-S184W-WIFI无线-APP版: STM32-S184CAN-视频监控WIFI无线-APP版: STM32-S184I-云平台-APP版: 产品功能描…

作者头像 李华
网站建设 2026/4/18 2:00:01

特价股票与公司社会资本积累的长期关系

特价股票与公司社会资本积累的长期关系 关键词:特价股票、公司社会资本积累、长期关系、市场机制、企业价值 摘要:本文旨在深入探讨特价股票与公司社会资本积累之间的长期关系。通过对相关核心概念的解析,阐述了特价股票和公司社会资本的原理及架构。运用算法原理和数学模型…

作者头像 李华
网站建设 2026/4/18 2:02:27

Python+django的生鲜海鲜商城交易系统设计与实现没论文

目录摘要开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!摘要 随着电子商务的快速发展,生鲜海鲜产品的线上交易需求日益增长。传统的线下交易模式存在地域限制、价格不透明、物流…

作者头像 李华