如何分配变量到指定的地址
举例:
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_newproject1debug 目录下)生成 .map 文件。该文件详细地列出ram/flash/eeprom的分配使用情况。
如何生成hex格式的输出文件
在project-》settings-》postbuild选项页中,在commands栏内加入下行命令:
chex –fi -o $(outputpath)$(targetsname).hex $(outputpath)$(targetsname).sm8
再次编译链接该项目,如果成功则会在项目输出目录中(本例是在c:stm8_newproject1debug 目录下)生成 .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
mods0modsl0modsmodsl
名称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
#用户程序
debugmain.o
…
# 一些必要的cosmic库
libis0.sm8
libm0.sm8
# 重定义常量段,开始于0x8000,用于放置中断向量表(stm8硬件决定此位置)
# –k 用于程序冗余代码优化,详情可参考cosmic用户手册。
+seg .const -b 0x8000 –k
# 中断向量
debugstm8_interrupt_vector.o
#定义了三个变量,用于系统初始化
+def __endzp=@.ubsct # end of uninitialized zpage
+def __memory=@.bss # 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 debugexample.lkf:1 no default placement for segment .bit
the command: “clnk -l”c:program filescosmiccxstm8_16k_4.2.10lib“ -o debugexample.sm8 -mdebugexample.map -sa debugexample.lkf ” has failed, the returned value is: 1
exit code=1.
实际上是由于,在项目中没有定义.bit section。可按照如下步骤,手工添加.bit section:
打开项目链接配置窗口:project - settings - linker,选择 input 目录项
在zero page 或者 ram 里面定义一个.bit section.
然后重新编译一下就可以了。
OLED面板制造水平不足,LG公司将向京东方采购OLED面板
9月液晶电视面板价格持续较大涨幅趋势
2021工业互联网创新发展促经济数字化转型大会成功举办
光伏变频器公司有哪些
长安逸动R怎么样?极为激进的外观设计,2.0T+6AT的动力组合!
浅析STVD(COSMIC)定义变量及其位定义
OPPO Reno2 Z内置MediaTek Helio P90,拍摄更美
基于RFID应用的通用型控制器的设计方案
电视面板全线涨价 显示器和笔记本维持原状
Atheros推出ROCm单芯片11n AR6003
自信过头华为P10比华为Mate9还贵!国人的钱太好赚?
手机屏幕测试有多重要,它的测试方案是怎样的
什么是VMOS(垂直沟道绝缘栅型场效应管)
LED灯具质量快速检测
三星布局无线充电 引领行业新风向
新技术帮助多核满足安全关键标准
什么叫焊接?什么是焊接?
AP5191 DC-DC降压恒流芯片 车灯 日行灯线路图
Intersil新款模拟开关开态电阻低于0.5Ω
AI趋势报告 中美专利申请和科学出版数遥遥领先