STM8之STVD的使用

发布者:muhaoying2017最新更新时间:2021-10-19 来源: eefocus关键字:STM8  STVD 手机看文章 扫描二维码
随时随地手机看文章

如何分配变量到指定的地址


举例:
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;
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.


关键字:STM8  STVD 引用地址:STM8之STVD的使用

上一篇:stm8s单片机内部定时器2使用
下一篇:STM8的中断向量

推荐阅读最新更新时间:2024-11-10 20:34

STM8输出PWM变频时波形断开解决方法
  在使用STM8单片机的PWM功能时,一直没出现过问题。但是在一个项目中需要在PWM波输出的过程中变频,这时候问题来了。在PWM输出过程中,输出的波形是不是的就会有一大段空白的地方,好像波形输出被关闭了一样。 输出波形如下图所示:   放大后查看   可以看到波形输出的过程中突然就消失了,而且还不是偶尔的出现一次。是频繁的出现。这就奇怪了?难道是单片机坏了?换了几个单片机测试都是这样的,那么肯定就是软件代码出问题了。那么到底是什么地方有问题了,于是开启找BUG模式,一行一行代码分析。   代码分析了半天也没找不到哪行代码有问题,输出单一频率的PWM波一直很稳定,只是改变频率的时候就会出现波形断开情况,频率改变的越多,
[单片机]
<font color='red'>STM8</font>输出PWM变频时波形断开解决方法
stm8 eeprom
void EEPROOM_Configuration(void) { FLASH_DeInit(); /* Define flash programming Time*/ FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD); /* Unlock Data memory */ FLASH_Unlock(FLASH_MEMTYPE_DATA); } 写一位数据 FLASH_ProgramByte(0x4000,0xaa);//写0xaa数据到0x4000地址 读一位数据 read_data=FLASH_ReadByte(0x4000);//读取0x4000地址上的数据
[单片机]
STM8定时器1计数说明
定时器计数说白了就是把内部时钟信号(fmaster)变成外部时钟信号(TIx、ETR),计数需要有时钟/触发控制器和时基单元,定时器1拥有这两个,定时器2和3虽然没有,但可以在捕获模式下进入捕获中断里计数。 使用外部信号计数有两种方式,见下图: 一种输入方式是使用定时器1通道输入,第二种使用定时器1触发输入,各输入口见下图,其中PC1到PC4为定时器1输入通道,PB3为定时器1触发输入口: 如何使用这两种方式来计数外部信号呢,看手册说明: 第一种方式:外部时钟源模式1(使用定时器通道): 第二种方式:外部时钟源模式2(使用触发方式): 这里使用定时器4作为定时1s电平翻转输出到PE4作为计数器外部计数信号
[单片机]
<font color='red'>STM8</font>定时器1计数说明
STVD 编译代码提示stm8_interrupt_vector.o: section 0 expected (.text:0000)
今天编译前同事留下的代码,发现代码报错: #error clnk Debugcsc_code.lkf:93 Debugstm8_interrupt_vector.o: section 0 expected (.text:0000) The command: clnk -l D:Program Files (x86)COSMICCXSTM8Lib -l D:Program Files (x86)COSMICCXSTM8Lib -o Debugcsc_code.sm8 -mDebugcsc_code.map Debugcsc_code.lkf has failed, the returned value is: 1 exit
[单片机]
<font color='red'>STVD</font> 编译代码提示stm8_interrupt_vector.o: section 0 expected (.text:0000)
STM8读写EEPROM
RWW特性允许用户在执行程序和读程序存储器时对DATA区域进行写操作,因此执行的时间被优化了。相反的操作是不允许的:即你不可以在写程序存储器时对DATA EEPROM进行读操作。 RWW特性是一直有效的而且可以在任意时刻使用。注意:并不是所有STM8都拥有RWW特性,请参考相应的数据手册来了解更多信息。 字节编程 可以对主程序存储器和DATA区域逐字节地编程。要对一个字节编程,应用程序可直接向目标地址写入数据。 在主程序存储器中 当字节编程操作执行时,应用程序停止运行。 在DATA区域中 有RWW功能的器件:在IAP模式下,应用程序不停止运行,字节编程利用RWW功能进行操作。 无RWW功能的器件:当字节编程操作执行时,应
[单片机]
STM8 ADC转换使用经验
STM8单片机ADC转换启动开关ADON使用:须通过写此开关位来把ADC从低功耗模式唤醒并触发一次AD转换。如果此位是0时,并且写1到些位,那么将把ADC从低功耗模式下唤醒。如果在此位是1,并且写1到此位,那么将启动AD转换。一旦ADC上电,所选转换通道的I/O输出功能就被禁用了。
[单片机]
IAR for stm8使用标准固件库的方法以及注意事项
阅读数:11304 标准库其实挺方便的。有了一个模板之后,如果改参数,根本就不需要再去查手册,重新定义寄存器值了。 第一部分,stm8标准库介绍。 stm8的标准库名称代码是stsw-stm8069,根据这个代码就可以到st的官网上下载到最新的固件库。 解压固件库后,有几个文件夹,我这里只是简单的说明各文件夹和文件的作用,具体的说明参考文件包中的chm帮助文档。 Libraries是驱动文件夹,里面的inc文件夹是h文件,src文件夹是c文件,这是最关键的东西。 Utilities是stm自己提供的EVAL开发板程序,如果没用这个EVAL开发板可以无视,有也可以无视,反正就很简单的一个led程序 Project文件夹是工程
[单片机]
STM8S 生成纯eeprom文件
环境:stvd+ST Assembler Linker /////////////////////////////////////////////////--main.asm文件--1////////////////////////////////////////////////////////////////////////////////////// stm8/ #include cfg.inc ;segment 'eeprom' segment byte at:EADD_INIT_FLAG1 'eeprom' dc.b INIT_FLAG1 segment byte at:EA
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved