STM8使用----STVD(COSMIC)定义变量指定其类型和位定义_stm8定义数组_robot_ding的博客-程序员宅基地

STM8使用----STVD(COSMIC)定义变量指定其类型和位定义
http://www.51hei.com/bbs/dpj-31009-1.html
(出处: 单片机论坛)

stm8 stvd下

near等于51的xdata

tiny等于51的idata


如何分配变量到指定的地址
举例:
unsigned char temp_A@0x00; //定义无符号变量temp_A,强制其地址为0x00
        unsigned char temp_B@0x100; //定义无符号变量temp_B,强制其地址为0x100
        @tiny unsigned char temp_C; //定义无符号变量temp_C,由编译器自动在地址小于0x100的RAM中为其分配一个地址
@near unsigned char temp_D; //定义无符号变量temp_D,由编译器自动在地址大于0xFF的RAM中为其分配一个地址
        另外也可以采用伪指令"pragma"将函数或者变量定义到指定的section中,例如:
#pragma section [name] // 将下面定义的未初始化变量定义到.name section中
Unsigned char data1;
        Unsigned int data2;
……(任何需要定义在.name section中的变量)
……
#pragma section [] // 返回到正常的section.
注意:pragma伪指令可以用来定位函数,初始化变量或者未初始化变量。这三者用不同的括号区分。
(name):代码
[name] :未初始化变量
{name}:初始化变量                  
如何在COSMIC C文件中使用汇编语言
        在COSMIC C文件中使用汇编语言常见的方法有如下两种:使用#asm …#endasm组合格式
        或_asm("…"); 单行格式。
        举例1:
unsigned char temp_A;
        Void func1(void)
        {
        ...
        #asm
        PUSH A
        LD A,(X)
        LD _temp_A,A
        POP A
        #endasm
        ...
        }
注:在C嵌汇编环境下使用全局变量,要在该全局变量名称前加下划线"_"。
        举例2:
Void func1(void)
        {
        ...
        _asm("rim");
        _asm("nop");
        ...
        }      
如何观察RAM/FLASH/EEPROM的最终分配情况
在Project->settings->linker选项页中,将Category选为Output,再勾选Generate Map File。                 
点击OK按键后,再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:\STM8_NewProject1\debug 目录下)生成 .map 文件。该文件详细地列出RAM/FLASH/EEPROM的分配使用情况。 
如何生成hex格式的输出文件
            在Project->settings->PostBuild选项页中,在commands栏内加入下行命令:
chex –fi -o $(OutputPath)$(TargetSName).hex $(OutputPath)$(TargetSName).sm8
再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:\STM8_NewProject1\debug 目录下)生成 .hex 文件。
什么是MEMORY MODEL
              STM8的C编译器支持多种存储器模式。用户可以根据应用的需要选择最适合的配置。可以根据需要选择采用2个字节的寻址方式(仅适用于64k以内的程序)或者3字节的寻址方式。也可以规定将变量默认为定义在存储器的哪一区域:zero page内,还是zero page 外。下面对几种供选择的MEMORY MODEL做简单说明。
              在Project->settings->C Complier选项页中,将Category选为General,里面有一个Memory Models选项栏如下:

            在下拉菜单中共有4种MEMORY MODEL可供选择:        
  • 程序地址空间在64K以内(即程序容量小于32K)
                    mods0,
                    modsl0
  • 程序地址哦那个键在64K以上(即程序容量大于32K)
    mods
                    modsl
MODS0
MODSL0
MODS
MODSL
名称
Stack Short
短堆栈模式
Stack Long
长堆栈模式
Stack Short
短堆栈模式
Stack Long
长堆栈模式
程序地址空间
程序所用到的地址空间在64K范围内
程序所用到的地址空间超出64K范围
指针默认类型
函数指针和数据指针默认为@near (2 bytes)
函数指针默认为@far(地址为3字节);
      数据指针默认为@near
全局变量默认类型
所有全局变量的地址默认为1个字节。对于地址超出1个字节的变量,必须用@near定义
所有全局变量默认为Long型。若要将变量地址定义为1个字节,必须用@tiny定义
所有全局变量的地址默认为1个字节。对于地址超出1个字节的变量,必须用@near定义
所有全局变量默认为Long型。若要将变量地址定义为1个字节,必须用@tiny定义
.lkf 文件的作用
.lkf文件在程序链接时决定如何具体分配RAM/ROM的空间。在Project Settings – Linker – Category(Input)选项页中,当"Auto"选择框被选中时,由系统自动生成.LKF文件,否则由用户指定。

          当"Auto"选择框被勾选时,.lkf文件会自动生成在项目主目录下的 debug/ 和 release/ 目录中。下面以上图所示 at45DBXX Project的 lkf 文件为例,来进一步理解.lkf 。
          在.lkf中,以"#"开头的行是注释行,为方便用户理解,将原注释删除,代之以中文注释如下:
# 定义(+seg)一个常量段(.const),开始(b)于0x8080,最大分配(m)0x1ff80个字节(即不超过
# 0x27FFF),为该段起名(n)为.const(和常量段的保留字同名),需要初始化的变量的初始值存
# 放于此段(-it)
          +seg .const -b 0x8080 -m 0x1ff80 -n .const -it
          # 定义(+seg)一个程序段(.text),紧跟(-a)在.const段后面(和.const 共同位于0x8080 –
# 0x27FFF),为该段起名(n)为. text (和程序段的保留字同名)。
+seg .text -a .const -n .text
          # 定义(+seg)一个EEPROM段(.eeprom),开始(b)于0x4000,最大分配(m)0x800个字节(即不超
#过0x47FF),为该段起名(n)为. eeprom (和EEPROM段的保留字同名)。
+seg .eeprom -b 0x4000 -m 0x800 -n .eeprom
          # .bsct段服务于定义在0页(地址小于0x100)以内需要初始化的全局变量(如@tiny char a = 9;)
          +seg .bsct -b 0x0 -m 0x100 -n .bsct
          # .ubsct段服务于定义在0页(地址小于0x100)以内不需要初始化的全局变量(如@tiny char b;)
        +seg .ubsct -a .bsct -n .ubsct        
        # .bit表示位域段,定义后即可在程序中使用_Bool变量(如_Bool c = 1;),-id表示该段需要初始化。
+seg .bit -a .ubsct -n .bit -id
        # 这是ST7时代(STM8是基于ST7发展而来的)由于物理堆栈小,速度慢,使用内存来模拟堆栈的变通手段。
+seg .share -a .bit -n .share -is
        # .data段服务于定义在0页(地址大于0xFF)以外需要初始化的全局变量(如@near char d = 8;)
        +seg .data -b 0x100 -m 0x1300 -n .data
        # .bss段服务于定义在0页(地址大于0xFF)以内不需要初始化的全局变量(如@ near char e;)
        +seg .bss -a .data -n .bss
        # 段定义结束,下面放置的库及Obj文件中的变量、常量、程序就按照上面的规定进行分配。
#初始化程序
crtsi0.sm8
        #用户程序
Debug\main.o

# 一些必要的cosmic库
libis0.sm8
        libm0.sm8
        # 重定义常量段,开始于0x8000,用于放置中断向量表(STM8硬件决定此位置)
        # –k 用于程序冗余代码优化,详情可参考cosmic用户手册。
+seg .const -b 0x8000 –k
        # 中断向量
Debug\stm8_interrupt_vector.o
        #定义了三个变量,用于系统初始化
+def [email protected] # end of uninitialized zpage
        +def [email protected] # end of bss segment
        +def __stack=0x17ff # 不同的芯片__stack内容不同,由系统自动生成         
如何实现位操作
Cosmic C 编译器支持位变量的操作,可以将其定义成 _Bool类型。_Bool类型的变量只包含两种值true(1)或者false(0)。若将一个表达式赋值给_Bool变量,则编译器会将表达式与0做比较,然后将布尔值赋给_Bool变量。因此,任何整型或者表达式的值都可以赋给_Bool变量。但是,布尔变量不能定义位数组,只能定义成结构体或者联合。而且,_Bool变量会被打包成字节的形式。
        编译器会将所有的全局_Bool变量打包成字节形式,存放在.bit section中。局部_Bool变量也会被打包成字节形式。但是_Bool类型的参数会被扩展成一个单字节。        
具体的关于位变量的定义和使用可参考如下例子:
          定义位变量:
_Bool in_range;
          _Bool p_valid;
          char *ptr;
使用位变量:
in_range = (value >= 10) && (value <= 20);
          p_valid = ptr; /* p_valid is true if ptr not 0 */
        if (p_valid && in_                                        
在使用位变量时,若程序编译时提示如下错误:
#error clnk Debug\example.lkf:1 no default placement for segment .bit
          The command: "clnk -l"C:\Program Files\COSMIC\CXSTM8_16K_4.2.10\Lib" -o Debug\example.sm8 -mDebug\example.map -sa Debug\example.lkf " has failed, the returned value is: 1
        exit code=1.
实际上是由于,在项目中没有定义.bit section。可按照如下步骤,手工添加.bit section:
打开项目链接配置窗口:Project - Settings - Linker,选择 Input 目录项

在Zero page 或者 Ram 里面定义一个.bit section.                

然后重新编译一下就可以了。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dingding0403/article/details/45336013

智能推荐

hdu3790 最短路径问题<最短路>_lingo起点到终点最短路径-程序员宅基地

最短路径问题Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 19990 Accepted Submission(s): 5947Problem Description给你n个点,m条无向边,每条_lingo起点到终点最短路径

利尔达与紫光展锐、中国电信等行业伙伴共筑NB-IoT安全生态_利尔达科技的博客-程序员宅基地

国内物联网的发展阶段已经由蓄力期进入增长期,中国电信在今年成为全球首个5G NB-IoT用户数破亿的运营商,随着用户规模的增长,潜在的安全风险也愈加得到重视。在2021天翼智能生态博览会期间,利尔达携手展锐、中国电信等物联网产业合作伙伴共同举办了“共筑NB-IoT安全生态”启动仪式,开启NB-IoT安全生态的全新篇章。利尔达总裁陈凯(右三)出席启动仪式实现了端、网、云协同的端到端安全解决方案,为物联网产业发展保驾护航。展锐 V8811展锐V8811是基于3GPP R16标准设计的5G NB-Io

C和C++内存分配-程序员宅基地

一、预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。3、全局区(

C语言变量常量,基本数据类型及数据类型转换详讲_const unsigned short 格式化类型_是谢添啊的博客-程序员宅基地

详解:为什么需要数据类型,整型,浮点型,字符型,变量与常量,自动类型转换,强制类型转换_const unsigned short 格式化类型

安装tensorflow-gpu问题及解决方案-程序员宅基地

安装tensoflow-gpu花了一天的时间终于把程序安装完成了 服了 下面稍微总结一下遇到的问题 也不知道后面会不会换电脑 到时候还得重装一下 所以现在记录一下安装基本步骤「WIN10安装TENSORFLOW(GPU版本)详解(超详细,从零开始)」:https://zhuanlan.zhihu.com/p/37086409常见安装问题:1.遇到安装超时问题:可以-i 一下镜像源例如:pip install **** -i http://mirrors.aliyun.com/pypi/

正则-程序员宅基地

www.cnblogs.com/yansheng/archive/2010/05/07/1730188.html$  匹配行结束符。例如正则表达式weasel$ 能够匹配字符串"He's a weasel"的末尾,但是不能匹配字符串"They are a bunch of weasels."。  ^  匹配一行的开始。例如正则表达式^When in能够...

随便推点

浅尝辄止_数学建模(笔记_线性回归)-程序员宅基地

文章目录线性回归分析一、一元线性回归1.一元线性回归模型2.对线性的理解对回顾系数的理解线性回归分析一、一元线性回归1.一元线性回归模型假设xxx是自变量,yyy是因变量,且满足如下线性关系:yi=β0+β1xi+μiy_i=β_0+β_1x_i+μ_iyi​=β0​+β1​xi​+μi​,其中β0和β1β_0和β_1β0​和β1​为回归系数,μiμ_iμi​为无法观测的且满足一定条件的扰动项。2.对线性的理解 线性假定并不要求初始模型呈现如yi=β0+β1xi+μiy_i=β_0+β

Oracle数据库_oracle功能_@一只菜鸟¥的博客-程序员宅基地

OracleOracle是什么?Oracle是一种适用于大型、中型和微型计算机的关系数据库管理系统,它使用SQL作为它的数据库语言。1、Oracle主要包括数据定义、数据操纵和数据控制等三方面功能。2、Oracle数据库由三种类型的文件组成:数据库文件、日志文件和控制文件。3、Oracle本身也要利用数据库字典来管理和控制整个数据库。4、Oracle产品覆盖了大、中、小型机等几十种机型,Oracle数据库成为世界上使用最广泛的关系数据系统之一。三范式第一范式(1NF)数据库表中的每一列都是不_oracle功能

QT运行时找不到链接库-程序员宅基地

QT链接动态库利用QtCreator开发Qt应用时碰到过这样的一个错误: 1. 引用了第三方的动态库,在pro文件中指明了头文件目录和链接库文件  INCLUDE_PATHS += ../inc  LIBS += ../lib/libtest.so 2. 编译通过 3. 运行时提示 error while loading shared libraries  无法找到链接的动态库库目录

python对数据去重处理-程序员宅基地

我们在数据处理时,经常需要用到对重复数据进行过滤处理。 对数据去重有两种处理方式,如下:1、对重复数据去重,并且会自动排序使用函数 set# 列表去重list_a = [6, 6, 5, 1, 2, 2, 3, 4, 4, 4, 6, 7, 8, 8, 8, 10]# 仅去重list_aa = set(list_a)print(list_aa)..._python对数据去重用

c语言不同类型指针间的强转,C语言中不同的结构体类型的指针间的强制转换详解..._所遇非人覃的博客-程序员宅基地

C语言中不同类型的结构体的指针间可以强制转换,很自由,也很危险。只要理解了其内部机制,你会发现C是非常灵活的。一.结构体声明如何内存的分布,结构体指针声明结构体的首地址,结构体成员声明该成员在结构体中的偏移地址。变量的值是以二进制形式存储在内存中的,每个内存字节对应一个内存地址,而内存存储的值本身是没有整型,指针,字符等的区别的,区别的存在是因为我们对它们有不同的解读,param的值就是一个32位..._不同类型的结构体指针之间通过强转赋值

用python实现一个简单的学生管理系统_python设计一个简单的学生管理系统。-程序员宅基地

"""本程序实现老师登录板块和学生修改信息板块简单来说就是函数疯狂调函数对想练习函数的同学可以拿来练一下逻辑其实很简单"""gl={}#老师登录def Total(): print("——————学生管理系统————————\n登录账号\n注册账号\n退出账号") while True: k = input("请选择的服务(1~3)") if k=="1": root=input("请输入账号") _python设计一个简单的学生管理系统。