《无刷直流电机》第2章STM8微处理器开发环境 (3) - 技术资料 - 电子技术论坛 - 最好最受欢迎电子论坛!

《无刷直流电机》第2章STM8微处理器开发环境 (3)

本帖最后由 优易特电子 于 2015-1-27 17:39 编辑

续(2)

。。。

2.3.3         COSMIC C语言相关说明
更多更详细COSMIC C语言相关说明请参考光盘中“第二章”中“COSMIC C Cross Compiler User’s Guide for Stm8.pdf”文件。
1COSMIC段的定义(Section
编译器使用默认预定义的段输出不同部分的机器码。默认段如表2-7所示。
2-7 COSMIC默认段
描述
.text
可执行代码
.const
文本字符和常数
.fconst
大常量(@far)
.data
初始化变量(@near)
.bss
未初始化变量(@near)
.bsct
零页内的初始化变量(@tiny, 默认)
.ubsct
零页内的未初始化变量(@tiny,默认)
.fdata
大变量(@far)
.eeprom
EEPROM内任何变量(@eeprom
.bit
位变量

通过pragma定义用户自己的段,格式如下:
#pragma section
可以是空白,或者使用下面语句:
const
_Bool
@tiny
@near
@far
@eeprom
是一个段的名字:
(name) - 圆括号表示代码段
[name] – 方括号表示未初始化的数据
{name} – 大括号表示初始化的数据
段的名字开头不能用点开始。段的名字不能超过13个字符。使用可以切回到默认段。
2COSMIC C语言中嵌入汇编指令
COSMIC C编译器提供两种方法嵌入汇编指令。第一种方法是#asm#endasm嵌入汇编指令块。第二种方法是嵌入行汇编。单独一行汇编指令。
第一种方法语法:
#asm     //开始汇编指令块
#endasm  //结束汇编指令块
第二种方法语法:
_asm(“嵌入的汇编代码”, 符合C语言规则的参数...);
例如,执行单条指令        
_asm("ld _mya,a");
若在一行内执行多条指令,可如:
_asm("push an ld a,88n ld _mya,an inc an pop an call _subroutinen");
2-8是一个嵌入汇编的例子。
2-8 COSMIC C语言嵌入汇编的例子
#include "stm8s207c_s.h"
unsigned char i,mya;
void subroutine(void){}
main()
{
mya=0x22;
#asm        //#asm 要顶格书写
    push a        
        ld a,_mya
        inc a
        ld _mya,a
        call _subroutine
        pop a        
#endasm

_asm("push an ld a,88n ld _mya,an pop an call _subroutinen");
        while (1)        {i = mya;}


3COSMIC C编译器的启动程序
COSMIC 有一个启动程序,就是在单片机复位之后,在程序跳转至main函数之前,插入一段汇编代码做一些初始化的动作。其包括:
段的初始化(如bss)、拷贝ROMRAM(如果程序中需要的话)和堆栈指针初始化。
2-9crtsi0.sm8反汇编之后的代码。
2-9 crtsi0.sm8反汇编代码
0x8084 <__stext+1>          0x0FFF          CLR   (0xff,SP)           CLR   (0xff,SP)
0x8086 <__stext+3>          0x94            LDW   SP,X                  LDW   SP,X
0x8087 <__stext+4>          0x90CE8080      LDW   Y,0x8080            LDW   Y,__idesc__
0x808b <__stext+8>          0xAE8082        LDW   X,#0x8082           LDW   X,#0x8082
0x808e <__stext+11>         0xF6            LD    A,(X)               LD    A,(X)
0x808f <__stext+12>         0x2720          JREQ  0x80b1              JREQ  0x80b1
0x8091 <__stext+14>         0xA560          BCP   A,#0x60             BCP   A,#0x60
0x8093 <__stext+16>         0x2717          JREQ  0x80ac              JREQ  0x80ac
0x8095 <__stext+18>         0xBF03          LDW   0x03,X              LDW   c_x,X
0x8097 <__stext+20>         0xEE03          LDW   X,(0x03,X)          LDW   X,(0x03,X)
0x8099 <__stext+22>         0xBF06          LDW   0x06,X              LDW   c_y,X
0x809b <__stext+24>         0xBE03          LDW   X,0x03              LDW   X,c_x
0x809d <__stext+26>         0xEE01          LDW   X,(0x01,X)          LDW   X,(0x01,X)
0x809f <__stext+28>         0x90F6          LD    A,(Y)               LD    A,(Y)
0x80a1 <__stext+30>         0xF7            LD    (X),A               LD    (X),A
0x80a2 <__stext+31>         0x5C            INCW  X                   INCW  X
0x80a3 <__stext+32>         0x905C          INCW  Y                   INCW  Y
0x80a5 <__stext+34>         0x90B306        CPW   Y,0x06              CPW   Y,c_y
0x80a8 <__stext+37>         0x26F5          JRNE  0x809f              JRNE  0x809f
0x80aa <__stext+39>         0xBE03          LDW   X,0x03              LDW   X,c_x
0x80ac <__stext+41>         0x1C0005        ADDW  X,#0x0005           ADDW  X,#0x0005
0x80af <__stext+44>         0x20DD          JRT   0x808e              JRT   0x808e
0x80b1 <__stext+46>         0xAE0000        LDW   X,#0x0000           LDW   X,#0x0000
0x80b4 <__stext+49>         0x2002          JRT   0x80b8              JRT   0x80b8
0x80b6 <__stext+51>         0xF7            LD    (X),A               LD    (X),A
0x80b7 <__stext+52>         0x5C            INCW  X                   INCW  X
0x80b8 <__stext+53>         0xA30009        CPW   X,#0x0009           CPW   X,#0x0009
0x80bb <__stext+56>         0x26F9          JRNE  0x80b6              JRNE  0x80b6
0x80bd <__stext+58>         0xAE0100        LDW   X,#0x0100           LDW   X,#0x0100
0x80c0 <__stext+61>         0x2002          JRT   0x80c4              JRT   0x80c4
0x80c2 <__stext+63>         0xF7            LD    (X),A               LD    (X),A
0x80c3 <__stext+64>         0x5C            INCW  X                   INCW  X
0x80c4 <__stext+65>         0xA30100        CPW   X,#0x0100           CPW   X,#0x0100
0x80c7 <__stext+68>         0x26F9          JRNE  0x80c2              JRNE  0x80c2
0x80c9 <__stext+70>         0xCD80CF        CALL  0x80cf              CALL  main
0x80cc <_exit>               0x20FE          JRT   0x80cc              JRT   _exit

STVD开发环境中,选择“project->Setttings...”,可对启动文件进行设置,如图2-34所示。
2-34 STVD启动设置
建议:
在软件设计时,建议用户不使用C编译器的启动文件。也就是说,在单片机复位后,直接跳转至main处执行。在main开始处,按照自己的设计,做一些变量和外设等的初始化动作。
跳转至main需要做如下修改
将图2-34Start-up 修改为None
修改复位函数:
{0x82, (interrupt_handler_t)_stext}, /* reset */  
修改为:
{0x82, (interrupt_handler_t)main}, /* reset */
并修改外部函数声明:
extern void _stext(); /* startup routine */  
修改为:
extern void main();  /* startup routine */
4COSMIC的存储器模式
STM8 编译器支持两种存储器模式。
代码小于64K:函数指针和数据指针默认是@near指针(2个字节)
stack short (mods0) 全局变量默认short range类型。任何在long range范围的全局变量必须明确地用@near来访问,除非通过指针访问。
stack Long (modsl0) 全局变量默认为long range类型。任何在short range类型中的变量必须明确地用@tiny 来访问。
代码大于64K:函数指针默认是@far指针(3个字节),数据指针默认为@near类型(2个字节),除非用@far明确地声明。
stack Short (mods)全局变量默认short range类型。 任何在long range范围的全局变量必须明确地用@near 来访问,除非通过指针来访问。
stack Long (modsl0) 全局变量默认为long range类型。任何在short range类型中的变量必须明确地用@tiny 来访问。
其中:short int int 默认为2个字节。long int 默认为4个字节。@tiny 指针(short range)默认为1个字节。@near 指针(long range)默认为2个字节。@far 指针默认为3个字节。
5COSMIC的位变量设置
STM8 C编译器位变量在STVD中的设置,如图2-35所示:
2-35 STVD位变量设置
C编译器使用_Bool类型定义位变量(新的ANSI/ISO标准C99)。布尔变量可用做结构或联合类型,连续的布尔变量放在一个字节中。
布尔变量定义,例子如图2-36

2-36 布尔变量定义
6)常量定义
常量定义例子如图2-37

2-37 常量定义
定义一个常量表如下:
const unsigned char constring[]
={0x2C,0x27,0x23,0x1F,0x1D,0x1A,0x17,0x16,0x13,0x11,0x0F,0x0E,0x00, 0x0D, 0x09, 0x15 };
unsigned char i;
i = constring[3];  // i = 0x 1F
7)在RAM中运行程序
可使用COSMIC中的函数_fctcpy将FLASH中的代码代码拷贝RAM中,并运行。_fctcpy从FALSH中拷贝一段可移动代码段到RAM中。_fctcpy寻找linker定义的描述符(此描述符是在RAM中定义段的第一个字符)。本例子在RAM 中定义了一个段.CODE_IN_RAM。所以地一个字符是’C’。
需要在程序中应用int _fctcpy(char name;
Ram 中创建一个’.CODE_IN_RAM’ 段,并在Option 中输入’-ic’ 。
’.CODE_IN_RAM’ 表示在RAM中定义一个CODE_IN_RAM的段。程序可从此起始地址运行。_fctcpy函数使用此段的名字的第一个描述符’C’。
’-ic’ 表示标记这个段为可移动的段。可将FLASH中的代码移动到此。
在程序代码中完成函数:
#pragma section (CODE_IN_RAM)
functions()
{
        var1 = 0x99;
        var2 = 0x88;
        var3 = 0x77;
}
routine()
{
        var1++;
        var2++;
        var3++;
}
#pragma section ()
打开“project->settings…->Linker”,如图2-38所示配置。
2-38 程序RAM运行配置
例子如下:
unsigned char var1,var2,var3;
int _fctcpy(char name);

#pragma section (CODE_IN_RAM)
functions()
{
        var1 = 0x99;
        var2 = 0x88;
        var3 = 0x77;
}
routine()
{
        var1++;
        var2++;
        var3++;
}
#pragma section ()

main()
{
_fctcpy('C');   //拷贝pragma section(CODE_IN_RAM)中的函数到RAM
        functions();       // 调用RAM中的functions 函数
        routine();         // 调用RAM 中的 routine 函数

while (1)
        {
                _asm("nop");
                _asm("nop");
                _asm("nop");
                _asm("nop");
        }
}
8)如何生成HEX文件
设置“Project-> Settings…->Post-Build”,如图2-39所示。
2-39 HEX文件生成设置
原来设置:
chex -o  $(OutputPath)$(TargetSName).s19  $(OutputPath)$(TargetSName).sm8
设置为:
chex –fi –o  $(OutputPath)$(TargetSName).hex  $(OutputPath)$(TargetSName).sm8
        如图2-40为编译连接生成结果。
2-40编译连接生成结果


024.jpg (14.24 KB, 下载次数: 3)

024.jpg

025.jpg (10.01 KB, 下载次数: 3)

025.jpg

0个回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则


关闭

站长推荐上一条 /7 下一条

小黑屋|手机版|Archiver|电子发烧友 ( 湘ICP备2023018690号 )

GMT+8, 2024-11-20 07:16 , Processed in 0.655631 second(s), Total 57, Slave 40 queries .

Powered by 电子发烧友网

© 2015 bbs.elecfans.com

微信扫描
快速回复 返回顶部 返回列表