如何分配變量到指定的地址
舉例:
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”將函數(shù)或者變量定義到指定的section中,例如:
#pragma section [name] // 將下面定義的未初始化變量定義到.name section中
Unsigned char data1;
Unsigned int data2;
……(任何需要定義在.name section中的變量)
……
#pragma section [] // 返回到正常的section.
注意:pragma偽指令可以用來定位函數(shù),初始化變量或者未初始化變量。這三者用不同的括號區(qū)分。
(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嵌匯編環(huán)境下使用全局變量,要在該全局變量名稱前加下劃線“_”。
舉例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編譯器支持多種存儲器模式。用戶可以根據(jù)應用的需要選擇最適合的配置。可以根據(jù)需要選擇采用2個字節(jié)的尋址方式(僅適用于64k以內的程序)或者3字節(jié)的尋址方式。也可以規(guī)定將變量默認為定義在存儲器的哪一區(qū)域: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范圍
指針默認類型函數(shù)指針和數(shù)據(jù)指針默認為@near (2 bytes)函數(shù)指針默認為@far(地址為3字節(jié));
數(shù)據(jù)指針默認為@near
全局變量默認類型所有全局變量的地址默認為1個字節(jié)。對于地址超出1個字節(jié)的變量,必須用@near定義所有全局變量默認為Long型。若要將變量地址定義為1個字節(jié),必須用@tiny定義所有全局變量的地址默認為1個字節(jié)。對于地址超出1個字節(jié)的變量,必須用@near定義所有全局變量默認為Long型。若要將變量地址定義為1個字節(jié),必須用@tiny定義
.lkf 文件的作用
.lkf文件在程序鏈接時決定如何具體分配RAM/ROM的空間。在Project Settings – Linker – Category(Input)選項頁中,當“Auto”選擇框被選中時,由系統(tǒng)自動生成.LKF文件,否則由用戶指定。
當“Auto”選擇框被勾選時,.lkf文件會自動生成在項目主目錄下的 debug/ 和 release/ 目錄中。下面以上圖所示 at45DBXX Project的 lkf 文件為例,來進一步理解.lkf 。
在.lkf中,以“#”開頭的行是注釋行,為方便用戶理解,將原注釋刪除,代之以中文注釋如下:
# 定義(+seg)一個常量段(.const),開始(b)于0x8080,最大分配(m)0x1ff80個字節(jié)(即不超過
# 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個字節(jié)(即不超
#過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發(fā)展而來的)由于物理堆棧小,速度慢,使用內存來模擬堆棧的變通手段。
+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文件中的變量、常量、程序就按照上面的規(guī)定進行分配。
#初始化程序
crtsi0.sm8
#用戶程序
Debugmain.o
…
# 一些必要的cosmic庫
libis0.sm8
libm0.sm8
# 重定義常量段,開始于0x8000,用于放置中斷向量表(STM8硬件決定此位置)
# –k 用于程序冗余代碼優(yōu)化,詳情可參考cosmic用戶手冊。
+seg .const -b 0x8000 –k
# 中斷向量
Debugstm8_interrupt_vector.o
#定義了三個變量,用于系統(tǒng)初始化
+def __endzp=@.ubsct # end of uninitialized zpage
+def __memory=@.bss # end of bss segment
+def __stack=0x17ff # 不同的芯片__stack內容不同,由系統(tǒng)自動生成
如何實現(xiàn)位操作
Cosmic C 編譯器支持位變量的操作,可以將其定義成 _Bool類型。_Bool類型的變量只包含兩種值true(1)或者false(0)。若將一個表達式賦值給_Bool變量,則編譯器會將表達式與0做比較,然后將布爾值賦給_Bool變量。因此,任何整型或者表達式的值都可以賦給_Bool變量。但是,布爾變量不能定義位數(shù)組,只能定義成結構體或者聯(lián)合。而且,_Bool變量會被打包成字節(jié)的形式。
編譯器會將所有的全局_Bool變量打包成字節(jié)形式,存放在.bit section中。局部_Bool變量也會被打包成字節(jié)形式。但是_Bool類型的參數(shù)會被擴展成一個單字節(jié)。
具體的關于位變量的定義和使用可參考如下例子:
定義位變量:
_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.
然后重新編譯一下就可以了。
評論
查看更多