完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
9.2 数据类型
9.2.2 ARM架构(含Cortex-M系列)数据类型 ARM架构(含Cortex-M系列)的数据类型定义如下: 9.2.3 头文件stdint.h对数据类型的定义 stdint.h是C99中引进的一个标准C库的头文件。目前大部分单片机C编译器均支持,IAR和MDK都支持。下面是部分内容(来自MDK)。 /* exact-width signed integer types */ typedef signed char int8_t; typedef signed short int int16_t; typedef signed int int32_t; typedef signed __INT64 int64_t; /* exact-width unsigned integer types */ typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned __INT64 uint64_t; /* 7.18.1.2 */ /* smallest type of at least n bits */ /* minimum-width signed integer types */ typedef signed char int_least8_t; typedef signed short int int_least16_t; typedef signed int int_least32_t; typedef signed __INT64 int_least64_t; /* minimum-width unsigned integer types */ typedef unsigned char uint_least8_t; typedef unsigned short int uint_least16_t; typedef unsigned int uint_least32_t; typedef unsigned __INT64 uint_least64_t; /* 7.18.1.3 */ /* fastest minimum-width signed integer types */ typedef signed int int_fast8_t; typedef signed int int_fast16_t; typedef signed int int_fast32_t; typedef signed __INT64 int_fast64_t; /* fastest minimum-width unsigned integer types */ typedef unsigned int uint_fast8_t; typedef unsigned int uint_fast16_t; typedef unsigned int uint_fast32_t; typedef unsigned __INT64 uint_fast64_t; 以MDK5.26为例,stdint.h位于如下路径: Keil_v526ARMARMCCinclude 以IAR8.X为,stdint.h位于如下路径: IAR SystemsEmbedded Workbench 8.1armincc 9.2.4 程序中推荐的变量命名方式 看程序的时候,经常会看到各种各样的变量命名方式,例如声明一个8位无符号整数,常见的有如下几种写法: u8 err; U8 err; INT8U err; UINT8 err; uint8 err; uint8_t err; 当大家阅读别人写的程序时,往往会看到风格各异的定义方式,移植部分程序时也不知道采用哪种方式更合适。 我们推荐大家采用最后一种定义方式,这种方法符合C99规范,ST的固件库都是采用的这种类型定义方式。像我们开发板配套的STM32例程,从2009年最初的版本开始就一直沿用C99的标准写法来定义整数。 9.3 局部变量和全局变量 9.3.1 局部变量 在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数以外是不能使用这些变量的,这称为局部变量。 使用局部变量注意以下问题: 不同函数中可以使用相同名字的变量,它们代表不同的对象,互不干扰。 形式参数也是局部变量。 局部变量的作用域在函数内部。 9.3.2 全局变量 在函数内部定义的变量是局部变量,而在函数之外定义的变量称为外部变量,也就是全局变量。使用全局变量的注意事项: 全局变量可以为本文件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。 设置全局变量的作用是增加了函数间数据联系的渠道。 如果在同一个源文件中,外部变量和局部变量同名,则在局部变量的作用范围内,外部变量被“屏蔽”,即外部变量将不起作用。 9.3.3 使用全局变量的缺点 程序设计中,建议不要创建太多的全局变量,主要是出于以下三点考虑: 全局变量在程序的执行过程中都占用存储单元,而不是仅在需要时才占用存储单元。 函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移植到另一个文件中,还要将有关的外部变量及其值一起移植过去。 使用全局变量过多,会降低程序的清晰性,特别是多个函数都调用此变量时。 9.3.4 变量的存储类别 从变量的作用域来分,可以分为全局变量和局部变量,而从变量值存在的时间来看,可以分为静态存储方式和动态存储方式。 静态存储方式:指在程序运行期间由系统分配固定的存储空间方式。 动态存储方式:在程序运行期间根据需要进行动态的分配存储空间方式。 全局变量存储在静态存储区中,动态存储区可以存放以下数据: 函数形式参数,在调用函数时给形参分配存储空间。 局部变量(未加static声明的局部变量)。 函数调用时的现场保护和返回地址等。 9.3.5 用static声明局部或者全局变量 有时候希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时可以使用关键字static进行声明。 用static声明一个变量的作用: 对局部变量用static声明,则使用该变量在整个程序执行期间不释放,为其分配的的空间始终存在。 全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)。 9.4 堆栈 9.4.1 堆栈作用 栈(stack)空间,用于局部变量,函数调时现场保护和返回地址,函数的形参等。 堆(heap)空间,主要用于动态内存分配,也就是说用 malloc,calloc, realloc等函数分配的变量空间是在堆上。以STM32F429为例,堆栈是在startup_stm32f429xx.s文件里面设置: 9.4.2 寄存器组(堆栈指针寄存器) Cortex – M7/M4/M3 处理器拥有R0-R15的通用寄存器组。其中R13作为堆栈指针SP。SP有两个,但在同一时刻只能有一个可以用。 主堆栈指针(MSP):这是缺省的堆栈指针,它由OS内核、异常服务例程以及所有需要特权访问的应用程序代码来使用。 进程堆栈指针(PSP):用于常规的应用程序代码(不处于异常服务例程中时)。 另外以下两点要注意: 大多数情况下的应用,只需使用指针MSP,而PSP多用于 RTOS 中。 R13 的最低两位被硬线连接到0,并且总是读出0,这意味着堆栈总是4字节对齐的。 9.4.3 Cortex-M7/M4/M3向下生长的满栈 这个知识点在以后用F4移植RTOS时,非常有用。 9.4.4 堆栈的基本操作 这里对入栈和出栈做个简单的介绍。PUSH入栈操作:SP先自减 4,再存入新的数值: POP出栈操作:先从SP指针处读出上一次被压入的值,再把SP指针自增 4: 9.5 局部变量,全局变量和堆栈实例 通过下面的实例可以对局部变量,全局变量和堆栈有个感性的认识: uint32_t a = 0; //全局初始化区, 可以被其他c文件 extern 引用 static uint32_t ss = 0; //静态变量,只允许在本文件使用 uint8_t *p1; //全局未初始化区 int main(void) { uint32_t b; //栈 uint8_t s[] = “abc”; //栈 uint8_t *p2; //栈 uint8_t *p3 = “123456”; //123456 在常量区,p3在栈上。 static uint32_t c =0; //全局(静态)初始化区 p1 = (uint8_t *)malloc(10); //在堆区申请了10个字节空间 p2 = (uint8_t *)malloc(20); //在堆区申请了20个字节空间 strcpy(p1, “123456”); /* 123456字符串(结束符号是0( ),总长度7)放在常量区, 编译器可能会将它与p3所指向的“123456”优化成一个地方 */ } 通过查看MAP文件,可以看全局变量在RAM中的位置: Symbol Name Value Ov Type Size Object(Section) a 0x20000000 Data 4 main.o(.data) p1 0x2000000c Data 4 main.o(.data) ss 0x20000004 Data 4 main.o(.data) 而局部变量要调整状态进入main函数里面查看: 9.6 总结 C语言的基础知识点要掌握牢靠,对于后面学习HAL库源码大有裨益。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 22:33 , Processed in 0.689734 second(s), Total 77, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号