如果数据段有如下定义,则stm软件编译时间定义宏后变量VAR2分配的字节数为多少?

在电子工程世界为您找到如下关于“STM8S”的新闻

最近有一个项目需要用到STM8S103F3单片机。在开始之前以为会很容易,可是实际操作起来,却遇到不少问题 。其中最令我感到困惑的一个问题是:我在调试程序的时候程序可以运行正常,但当我把程序烧录进去断电重启后却运行不正常。试了很多方法,都没有找到问题所在。最后,我把Start-up file 选择默认的就可以。之前不知道在哪里看到过可以不使用系统的默认启动文件,可以直接...

);(7)在 3.5版的启动文件还调用了在 system_stm32f10x.c文件中的SystemIni()函数配置系统时钟。 二、启动文件中提到的汇编指令指令作用EQU给数字常量取一个符号名,相当于 C 语言中的 defineAREA汇编一个新的代码段或者数据段SPACE分配内存空间PRESERVE8当前文件堆栈需按照 8 字节对齐EXPORT声明一个标号具有全局属性,可被外部...

的组和引脚的数量不尽相同,具体请参考相应ST单片机芯片型号的datasheet。 根据ST单片机的GPIO特点,控制LED灯的步骤如下: 1.在众多 GPIO端口引脚中选定需要控制的特定引脚[与LED相连的控制引脚] 2.根据外设配置GPIO需要的特定功能 3.通过设置

很多刚接触STM8单片机的入门者不知到如何使用TIM1和TIM2的定时器作为定时功能。下面介绍如下:TIM1的初始化1us:系统时钟是16M。void set_TIM1_nus(u16

stm8s定时器输出比较一般用来做pwm输出。因此通过pwm输出来讲解输出比较。手册中说“脉冲宽度调制(PWM)模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRi寄存器确定占空比的信号”。由这句话得出:1、ARR的值,即定时周期=pwm周期 2、占空比=CCR/ARR。此处的x表示1,2,3,即TIM1,TIM2,TIM3。i表示通道号,具体看芯片引脚图...

STM8S的定时器分三类; 高级定时器TIM1 通用定时器TIM2,TIM3,TIM5 基本定时器TIM4,TIM6?其中除TIM4和TIM6是8位定时器外,其他的定时器都是16位计数的。 ?每个定时器都具有自动重装载功能 ?每个定时器的时钟都可以由系统时钟独立分频而来,其中高级定时器TIM1可以选择65536种分频,分频系数...

新手必备学习STM8S105手册,有大量解决方案和源码 新手必备学习STM8S105手册,有大量解决方案和源码 新手必备学习STM8S105手册,有大量解决方案和源码...

来自STM8S库函数,上传的目的为了方便没有留心关注STM8S库函数中Demo程序的孩子们看到例程。...

;      公司:深圳市永晟达电子科技有限公司 联系人:巨经理 联系电话: 联系QQ: 地址:深圳市福田区华强北华强广场C座18D STM8烧录器 STM8S003/103脱机烧录器 编程器 烧写器 量产工具

STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机台可以完全自动化烧录...

STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机台可以完全自动化烧录...

  STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机...

STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机台可以完全自动化烧录...

  STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机...

  STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机...

STM8烧录器 STM8S003/STM8S103脱机烧录器/编程器/烧写器量产现货 全网唯一一家不挑剔网络环境的远程脱机烧录器,不需要借助第三方网络辅助工具,无需懂得复杂的网络知识,即可轻松完成远程操作。 即插即用,驱动自动安装无需东奔西找乱找驱动。 智能感知芯片是否存在, 芯片取下放上自动识别,摆脱手动按键。你需要做的仅仅是芯片的放上与取下。如果配合烧录机台可以完全自动化烧录...

}

今天调试程序时,想观察一下变量的情况,突然发现平时经常移植别人程序时最容易忽略的一个致命问题,那就是忽略变量类型,这里有必要给大家一定知识啦,都是库里面的,非原创!

3.0以后的版本中使用了CMSIS数据类型,变量的定义有所不同,但是出于兼容旧版本的目的,以上的数据类型仍然兼容。CMSIS的IO类型限定词如表 5?7所示,CMSIS和STM32固件库的数据类型对比如表


固件库与CMSIS数据类型对比

易挥发只读有符号32位数据

易挥发只读有符号16位数据

易挥发只读有符号8位数据

易挥发读写访问有符号32位数据

易挥发读写访问有符号16位数据

易挥发读写访问有符号8位数据

易挥发只读有符号32位数据

易挥发只读有符号16位数据

易挥发只读有符号8位数据

易挥发读写访问无符号32位数据

易挥发读写访问无符号16位数据

易挥发读写访问无符号8位数据

易挥发只读无符号32位数据

易挥发只读无符号16位数据

易挥发只读无符号8位数据

不同版本的标准外设库的变量定义略有不同,如3.4版本中就没有之前版本的TRUE和FALSE的定义,用户也可以根据自己的需求按照上面的格式定义自己的布尔形变量。在使用标准外设库进行开发遇到相关的定义问题时应首先找到对应的头文件定义。

处理器通用寄存器(GPRs)的大小和它的字长是相同的。一般来说,对于一个的体系结构来说,它各个部件的宽度—比如说内存总线—最少要和它的字长一样大。而一般来说,地址空间的大小也等于字长,至少支持的体系结构中都是这样的此外,C语言定义的long类型总对等于机器的字长,而int类型有时会比字长小。比如说,Alpha是64位机。所以它的寄存器、指针和long类型都是64位长度的,而int类型是32位的。Alpha机每一次可以访问和操作一个64位长的数据。

1.字、双字的含义    有些和处理器不把它们的标准字长称作字,相反,出于历史原因和某种主观的命名习惯,它们用字来代表一些固定长度的。比如说,一些系统根据长度把数据划分为字节(byte,8位),字(word,16位),双字(double words 32位)和四字(quad words 64位),而实际上该机是32位的。在本书中—在Linux中一般也是这样—象我们前面所讨论的那样,一个字就是代表处理器的字长。

对于支持的每一种体系结构,Linux都要将<asm/types.h>中的BITS_PER_LONG定义为C long类型的长度,也就是系统的字长。表1是Linux支持的体系结构和它们的字长的对照表。

 C语言虽然规定了变量的最小长度,但是没有规定变量具体的标准长度,它们可以根据实现变化。C语言的标准数据类型长度随体系结构变化这一特性不断引起争议。好的一面是标准数据类型可以充分利用不同体系结构变化的字长而无需明确定义长度。C语言中long类型的长度就被确保为机器的字长。不好的一面是在编程时不能对标准的C数据类型进行大小的假定,没有什么能够保障int一定和long的长度是相同的

情况其实还会更加复杂,因为用户空间使用的数据类型和内核空间的数据类型不一定要相互关联。sparc64体系结构就提供了32位的用户空间,其中指针、int和long的长度都是32位。而在内核空间,它的int长度是32位,指针和long的长度却是64。没有什么标准来规范这些。牢记下述准则:* ANSI C标准规定,一个char的长度一定是8位。*尽管没有规定int类型的长度是32位,但在Linux当前所有支持的体系结构中,它都是32位的。* that)。*决不应该假定指针和long的长度,在Linux当前支持的体系结构中,它们就可以在32位和64位中变化。*由于不同的体系结构long的长度不同,决不应该假设sizeof( int ) == sizeof( long )。*类似地,也不要假设指针和int长度相等。

 不透明数据类型隐藏了它们内部格式或结构。在C语言中,它们就像黑盒一样。支持它们的语言不是很多。作为替代,开发者们利用typedef声明一个类型,把它叫做不透明类型,希望人别去把它重新转化回对应的那个标准C类型。通常开发者们在定义一套特别的接口时才会用到它们。比如说用来保存进程标识符的pid_t类型。该类型的实际长度被隐藏起来了—尽管任何人都可以偷偷撩开它的面纱,发现它就是一个int。如果所有代码都不显式地利用它的长度(显式利用长度这里指直接使用int类型的长度,比如说在编程时使用sizeof(int)而不是sizeof(pid_t)—译者注),那么改变时就不会引起什么争议,这种改变确实可能会出现:在老版本的Unix系统中,pid_t的定义是short类型。   另外一个不透明数据类型的例子是atomic_t,它放置的是一个可以进行原子操作的整型值。尽管这种类型就是一个int,但利用不透明类型可以帮助确保这些数据只在特殊的有关原子操作的函数中才会被使用。不透明类型还帮助我们隐藏了类型的长度,但是该类型也并不总是完整的32位,比如在32位SPARC体系下长度被限制。    内核还用到了其他一些不透明类型,包括dev_t、gid_t和uid_t等等。处理不透明类型时的原则是:*不要假设该类型的长度。*不要将该类型转化回其对应的C标准类型使用。*编程时要保证在该类型实际存储空间和格式发生变化时代码不受影响。3.   指定数据类型  内核中还有一些数据虽然无需用不透明的类型表示,但它们被定义成了指定的数据类型。jiffy数目和在中断控制时用到的flags参数就是两个例子,它们都应该被存放在unsigned long类型中。当存放和处理这些特别的数据时,一定要搞清楚它们对应的类型后再使用。把它们存放在其他如unsigned int等类型中是一种常见错误。在32位机上这没什么问题,可是64位机上就会捅娄子了。4.   长度明确的类型   作为一个程序员,你往往需要在程序中使用长度明确的数据。像操作硬件设备,进行网络通信和操作二进制文件时,通常都必须满足它们明确的内部要求。比如说,一块声卡可能用的是32位寄存器,一个网络包有一个16位字段,一个可执行文件有8位的cookie。在这些情况下,数据对应的类型应该长度明确。内核在<asm/typs.h>中定义了这些长度明确的类型,而该文件又被包含在文件<linux/types.h>中。表2有完整的清单。

其中带符号的变量用的比较少。

 上述的这些类型只能在内核内使用,不可以在用户空间出现(比如,在头文件中的某个用户可见结构中出现)。这个限制是为了保护命名空间。不过内核对应这些不可见变量同时也定义了对应的用户可见的变量类型,这些类型与上面类型所不同的是增加了两个下画线前缀。比如,无符号32位整形对应的用户空间可见类型就是__u32。该类型除了名字有区别外,与u32相同。在内核中你可以任意使用这两个名字,但是如果是用户可见的类型,那你必须使用下画线前缀的版本名,防止污染用户空间的命名空间。   C标准表示char类型可以带符号也可以不带符号,由具体的编译器、处理器或由它们两者共同决定到底char是带符号合适还是不带符号合适。大部分体系结构上,char默认是带符号的,它可以自-128到127之间取值。而也有一些例外,比如ARM体系结构上,char就是不带符号的,它的取值范围是0~255举例来说,在默认char不带符号,下面的代码实际会把255而不是-1赋予i:char i = -1;而另一种机器上,默认char带符号,就会确切地把-1赋予i。如果程序员本意是把-1保存在i中,那么前面的代码就该修改成:signed char i = -1;    另外,如果程序员确实希望存储255,那么代码应该如下:

   如果你在自己的代码中使用了char类型,那么你要保证在带符号和不带符号的情况下代码都没问题。如果你能明确要用的是哪一个,那么就直接声明它。
}

这是ST库里面的宏定义,定义如下:


显然,这三个宏定义都是用来替换成 volatile 和 const 的,所以我们先要了解 这两个关键字的作用:

1、volatile 简单的说,就是不让编译器进行优化,即每次读取或者修改值的时候,都必须重新从内存或者寄存器中读取或者修改。

    3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义; 我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到 volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。

1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。也就是说,在这个函数内部是没有权限去修改这个变量的,但是在程序的其他位置可以去修改它,而导致函数内的某种响应。


    只读变量,即变量保存在只读静态存储区。编译时,如何尝试修改只读变量,则编译器提示出错,就能防止误修改。
   两者都可以用来定义常量,但是const定义时,定义了常量的类型,所以更精确一些(其实const定义的是只读变量,而不是常量)。#define只是简单的文本替换,除了可以定义常量外,还可以用来定义一些简单的函数,有点类似内置函数。const和define定义的常量可以放在头文件里面。(小注:可以多次声明,但只能定义一次)

前面介绍了 volatile 和 const 的用法,不知道大家了解了没?了解了后,下面的讲解就更加容易了:


__I :输入口。既然是输入,那么寄存器的值就随时会外部修改,那就不能进行优化,每次都要重新从寄存器中读取。也不能写,即只读,不然就不是输入而是输出了。
__O :输出口,也不能进行优化,不然你连续两次输出相同值,编译器认为没改变,就忽略了后面那一次输出,假如外部在两次输出中间修改了值,那就影响输出
__IO:输入输出口,同上
一般宏定义都是大写,但因为这里的字母比较少,所以再添加下划线来区分。这样一般都可以避免命名冲突问题,因为很少人这样命名,这样命名的人肯定知道这些是有什么用的。
经常写大工程时,都会发现老是命名冲突,要不是全局变量冲突,要不就是宏定义冲突,所以我们要尽量避免这些问题,不然出问题了都不知道问题在哪里。

volatile一般用在以下三个方面:1、中断标志位2、多线程共享的变量3、状态寄存器

}

我要回帖

更多关于 stm软件编译时间定义宏 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信