国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于PICC編譯器中C語(yǔ)言與匯編語(yǔ)言混編的分析

2010-07-30 02:57:24劉金平,葉賽風(fēng)
電腦知識(shí)與技術(shù) 2010年11期
關(guān)鍵詞:匯編語(yǔ)言C語(yǔ)言

劉金平,葉賽風(fēng)

摘要:文章通過(guò)9個(gè)程序詳細(xì)介紹PIC單片機(jī)在PICC編譯器環(huán)境下,C語(yǔ)言與匯編語(yǔ)言混合編程的方法并對(duì)出現(xiàn)的情況進(jìn)行分析解決,最后對(duì)C語(yǔ)言與匯編語(yǔ)言混合編程的優(yōu)劣提出自已的看法。

關(guān)鍵詞:PIC單片機(jī);PICC編譯器;C語(yǔ)言;匯編語(yǔ)言

中圖分類號(hào):TP312文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1009-3044(2010)11-2640-05

Analysis Based on C Language and Assembler Language Mix Programming in PICC Compiler

LIU Jin-ping, YE Sai-feng

(Fujian Electric Vocational and Technical College, Quanzhou 362000, China)

Abstract: Articles detailed C language and assembly language mixed programming methodology and anslysis and settlement according to these problems of PIC singlechip in PICC compiler environment through 9 program and lastly presented their own views on the advantages and disadvantages of C language and assembly language mixed programming .

Key words: PICC singlechip; PICC compiler; C language; assembler language

目前,最常用PIC單片機(jī)C語(yǔ)言編程環(huán)境是MATLAB調(diào)試環(huán)境和HI-TECH編譯器PICC。雖然還有眾多支持PIC單片機(jī)的C語(yǔ)言編譯器,但PICC因?yàn)榉€(wěn)定、可靠、編譯生成的代碼效率高,而受到青睞。用C語(yǔ)言來(lái)開(kāi)發(fā)PIC單片機(jī)系統(tǒng)軟件最大的好處是編寫代碼效率高,軟件高度直觀、維護(hù)升級(jí)方便、代碼的重復(fù)利用率高、便于跨平臺(tái)的代碼移植等。因此用C語(yǔ)言編程,在進(jìn)行系統(tǒng)設(shè)計(jì)和開(kāi)發(fā)的工程師群體中得到廣泛認(rèn)可。既然C語(yǔ)言是一種強(qiáng)有力的程序設(shè)計(jì)語(yǔ)言,那么是不是就可以拋棄匯編語(yǔ)言?寫單片機(jī)C程序最關(guān)鍵的一點(diǎn)是單片機(jī)內(nèi)設(shè)資源非常有限,同時(shí),要求控制的實(shí)時(shí)性高,這就要求對(duì)單片機(jī)體系結(jié)構(gòu)和硬件資源有詳盡的了解,而這些恰恰是匯編語(yǔ)言的優(yōu)勢(shì),所以對(duì)于PIC愛(ài)好者,尤其初學(xué)者而言,C語(yǔ)言與匯編語(yǔ)言混編是不可避免的。實(shí)際上,C語(yǔ)言和匯編語(yǔ)言混合編程可以使單片機(jī)應(yīng)用程序的開(kāi)發(fā)效率和程序本身的運(yùn)行效率達(dá)到最佳的配合。

1 PICC對(duì)RAM的特殊要求

下面,我們通過(guò)一個(gè)引例的不同編程來(lái)看PICC對(duì)RAM的特殊要求。

例:將RAM中的BANK0的0X20~0X2F共16個(gè)單元置為55H。

1.1 采用匯編語(yǔ)言編程

程序1:

INCLUDE "P16F877.INC"

MOVLW 0X20

MOVWF FSR

MOVLW 55H

ABC MOVWFINDF

INCF FSR ,F

BTFSSFSR ,4

GOTOABC

GOTO$

END

程序1經(jīng)過(guò)調(diào)試,運(yùn)行后能實(shí)現(xiàn)引例功能。

1.2 采用C語(yǔ)言編程

程序2:

#include"pic.h"

unsigned char i;

unsigned char *tmp;

void main()

{

tmp=0x20;

for(i=1;i<17;i++)

{

(*tmp)=0x55;

tmp++;

}

}

程序2中運(yùn)用指針知識(shí),經(jīng)過(guò)調(diào)試沒(méi)有發(fā)現(xiàn)錯(cuò)誤,但運(yùn)行后根本無(wú)法滿足引例的要求。

修改程序2第2行為:“bank2 unsigned char i;”,即變量i改到RAM的BANK2。運(yùn)行的結(jié)果是將0X56~0X64共15個(gè)單元置為55H。再次將程序2第6行修改為:“tmp=0x21;”,運(yùn)行后,RAM的0X21~0X30共16個(gè)單元置為55H,離要求還有一點(diǎn)距離。

1.3 采用C語(yǔ)言絕對(duì)定位技術(shù)

程序3:

#include"pic.h"

bank2 unsigned char i;

static volatile unsigned char *tmp @ 0x30;

void main()

{

tmp=0x20;

for(i=1;i<17;i++)

{

(*tmp)=0x55;

tmp++;

}

}

程序3將定義的指針定位在BANK0的0X30單元開(kāi)始的區(qū)域,與0X20~0X2F區(qū)域沒(méi)有沖突。經(jīng)過(guò)調(diào)試運(yùn)行能實(shí)現(xiàn)引例功能。

1.4 采用C語(yǔ)言與匯編語(yǔ)言混編

程序4:

#include"pic.h"

bank2 unsigned char i;

void main()

{ #asm

MOVLW0X20

MOVWF_FSR

MOVLW0X55

MOVWF_INDF

#endasm

for(i=1;i<16;i++)

{ #asm

INCF _FSR,F

MOVLW0X55

MOVWF _INDF

#endasm

}

}

程序4中唯一變量i 定義在RAM的BANK2區(qū)域,程序經(jīng)過(guò)調(diào)試運(yùn)行能實(shí)現(xiàn)引例功能。要說(shuō)明的是,C語(yǔ)言與匯編語(yǔ)言混編時(shí),匯編語(yǔ)言部分的特殊功能寄存器名必須采用下劃線引導(dǎo)和大寫字母。

從以上不同方法的編程出現(xiàn)的結(jié)果,可以看出在C語(yǔ)言環(huán)境下,PICC對(duì)File Registers(RAM數(shù)據(jù)存儲(chǔ)器)中的20H~7FH單元具有絕對(duì)使用權(quán),這些單元位于BANK0的最后,即通用寄存器的96個(gè)字節(jié)。所以,在編程時(shí)若要應(yīng)用這部分單元,那么,則在C語(yǔ)言中定義的所有變量必須放在除BANK0外的RAM中,否則運(yùn)行結(jié)果不可預(yù)料。

2 PICC混編時(shí)對(duì)傳遞參數(shù)的要求

2.1 采用局部變量進(jìn)行主函數(shù)與自定義函數(shù)之間的數(shù)據(jù)傳遞

PICC規(guī)定,應(yīng)用局部變量傳遞數(shù)據(jù),在匯編語(yǔ)言部分引用參數(shù)時(shí),第2 個(gè)形參要寫成?_函數(shù)名,第3個(gè)形參要寫成?_函數(shù)名+1,以此類推。而第1個(gè)形參以及函數(shù)內(nèi)部自定義變量必須分別命名為?a_函數(shù)名,?a_函數(shù)名+1,……,至于?a_函數(shù)名先分配給第1個(gè)形參或是第1個(gè)自定義變量則不確定。

程序5:

#include

void Test(unsigned char inVar1, unsigned char inVar2,unsigned char inVar3,unsigned char inVar4)

{

unsigned char tmp1=0;

inVar1++;

asm("incf ?a_Test+1,f");

asm("decf ?_Test,f");//inVar2--;

#asm //inVar3+=5;

movf ?_Test+1,w

addlw 0x5

movwf ?_Test+1

#endasm

#asm //inVar4-=0x5左移一位,低位補(bǔ)1;

bsf _STATUS,0

rlf ?_Test+2,f

#endasm

#asm //tmp1=inVar1;

movf ?a_Test+1,w

movwf ?a_Test

#endasm

}

void main()

{

unsigned char t1,t2;

t1=t2=10;

Test(t1,t2,t1,t2);

}

程序5中的自定義函數(shù)名為Test,共有inVar1~inVar4等4個(gè)形參,函數(shù)內(nèi)部還有1個(gè)自定義變量tmp1。在匯編語(yǔ)言中inVar1寫成?a_Test+1、inVar2~inVar4分別寫成?_Test~?_Test+2、而tmp1寫成?a_Test。需要說(shuō)明的是:

1) 程序中C語(yǔ)言部分若不對(duì)第1個(gè)形參inVar1進(jìn)行操作,則在匯編語(yǔ)言部分中對(duì)inVar1處理是無(wú)效的!也就是不分配內(nèi)在單元給inVar1。

2) 程序中C語(yǔ)言部分若不對(duì)函數(shù)內(nèi)部的自定義tmp1進(jìn)行賦值或運(yùn)算,則在匯編部分對(duì)tmp1處理是無(wú)效的,也就是不分配RAM空間。

以上兩點(diǎn),在進(jìn)行C語(yǔ)言與匯編語(yǔ)言混編時(shí)應(yīng)特別關(guān)注。

2.2 采用全局變量進(jìn)行主函數(shù)與自定義函數(shù)之間的數(shù)據(jù)傳遞

程序6:

#include

volatile unsigned char tmp;

volatile bank1 unsigned char tmp1;

volatile bank2 unsigned char tmp2;

void Test(void)

{

#asm

clrf _STATUS

movlw 0x55

movwf _tmp

#endasm

}

void Test1(void)

{

#asm

clrf _STATUS

movlw 0x10

movwf _tmp

bcf _STATUS,6

BSF _STATUS,5

movlw 0x20

movwf _tmp1^0x80;非BANK0變量,在匯編語(yǔ)言中使用要如此

#endasm

}

void main()

{

while(1)

{

Test1();

if(tmp==0x10)

{

tmp=0xab;

}

if(tmp1==0x20)

{

tmp1=0xcd;

}

Test();

tmp2=tmp+tmp1;

}

}

程序6采用全局變量傳遞數(shù)據(jù),共定義tmp、tmp1、tmp2三個(gè)全局變量,分別定義在RAM的BANK0、BANK1、BANK2,其中tmp、tmp1用于函數(shù)之間傳遞函數(shù),在匯編語(yǔ)言部分要使用這兩個(gè)全局變量時(shí),只要在變量名前加下劃線作為引導(dǎo)就可以了。但要注意的是,若這些全局變量定義在非BANK0,如程序中的tmp,則在匯編語(yǔ)言部分使用時(shí),必須寫成_tmp1^0x80。若是定義在BANK1,就得寫成_tmp1^0x100,若是定義在BANK2,就得寫成_tmp1^0x180。

程序7:

#include

volatile unsigned char inVar1,inVar2,inVar3,inVar4;

void Test()

{

unsigned char tmp1=0;

//inVar1-=1;

asm("incf _inVar1,f");

//inVar2--;

asm("decf _inVar2,f");

//inVar3+=5;

#asm

movf _inVar3,w

addlw 0x5

movwf _inVar3

#endasm

//inVar4-=0x5左移一位,低位補(bǔ)1;

#asm

bsf _STATUS,0

rlf _inVar4,f

#endasm

//tmp1=inVar1;

#asm

movf _inVar1,w

movwf ?a_Test

#endasm

}

void main()

{

unsigned char tmp1=2;

inVar1=inVar2=inVar3=inVar4=10;

Test();

inVar1=inVar4;inVar3=tmp1;

}

程序7除定義了全局變量,還在自定義函數(shù)中定義了一個(gè)自定義變量tmp1,同樣在匯編部分要換名為?a_Test,需要說(shuō)明的是,若對(duì)tmp1不賦初值,那么在匯編時(shí)會(huì)出現(xiàn)“找不到?a_Test”錯(cuò)誤信息,而無(wú)法通過(guò)匯編。

使用全局變量最大的好處是尋址直觀,只需在 C 語(yǔ)言定義的變量名前增加一個(gè)下劃線,即可在匯編語(yǔ)句中尋址,使用全局變量進(jìn)行參數(shù)傳遞效率比形參傳遞高。

3 C語(yǔ)言主函數(shù)內(nèi)含匯編語(yǔ)言的情況

程序8:

#include

void main()

{

unsigned char tmp,i;

while(1)

{

tmp=1;

#asm

movf ?a_main+1,w

movwf ?a_main

#endasm

i++;

} }

程序8在主函數(shù)內(nèi)定義兩個(gè)變量,這兩個(gè)變量在匯編語(yǔ)言部分使用時(shí),必須換名為 ?a_main和 ?a_main+1,需要說(shuō)明的是,第1 個(gè)自定義變量tmp,在匯編語(yǔ)言部分使用?a_main前,在C語(yǔ)言部分必須先進(jìn)行賦初值或計(jì)算,否則會(huì)出現(xiàn)錯(cuò)誤。

程序9:

#include

volatileunsigned char tmp,i;

void main()

{

while(1)

{

//tmp=1;

#asm

movf _i,w

movwf _tmp

#endasm

i++;

} }

程序9在主函數(shù)外定義了兩個(gè)全局變量,它們?cè)趨R編語(yǔ)言部分使用比較簡(jiǎn)單,只要在變量前加下劃線引導(dǎo)就可以。

4 結(jié)束語(yǔ)

可以看出,C語(yǔ)言和匯編語(yǔ)言混合編程在具體實(shí)施時(shí),一定要注意許多細(xì)節(jié)問(wèn)題,否則運(yùn)算結(jié)果不可預(yù)料。

一般來(lái)說(shuō),在項(xiàng)目開(kāi)發(fā)過(guò)程中,程序量較大且PICC 進(jìn)行后道編譯優(yōu)化,采用C語(yǔ)言編寫的代碼不會(huì)比全部用匯編編寫的代碼差多少。所以,既然用了C語(yǔ)言編程,就盡量避免使用嵌入?yún)R編指令或整個(gè)地編寫匯編指令模塊文件。對(duì)于非得采用C語(yǔ)言和匯編語(yǔ)言混合編程,一定要注意:1)盡量使用嵌入?yún)R編;2)盡量使用全局變量進(jìn)行參數(shù)傳遞。

參考文獻(xiàn):

[1] 李榮正.PIC單片機(jī)原理及應(yīng)用[M].北京:北京航空航天大學(xué)出版社,2006.

[2] 周堅(jiān).PIC單片機(jī)輕松入門[M].北京:北京航空航天大學(xué)出版社,2009.

[3] 張明峰.PIC單片機(jī)入門與實(shí)戰(zhàn)[M].北京:北京航空航天大學(xué)出版社,2004.

猜你喜歡
匯編語(yǔ)言C語(yǔ)言
基于Visual Studio Code的C語(yǔ)言程序設(shè)計(jì)實(shí)踐教學(xué)探索
高等學(xué)校計(jì)算機(jī)專業(yè)課程教學(xué)改革實(shí)踐——以匯編語(yǔ)言與接口技術(shù)課程為例
匯編語(yǔ)言與C語(yǔ)言的混合程序設(shè)計(jì)技術(shù)研究
電子制作(2019年10期)2019-06-17 11:45:16
基于C語(yǔ)言的計(jì)算機(jī)軟件編程
電子制作(2018年16期)2018-09-26 03:27:08
C語(yǔ)言程序設(shè)計(jì)課程教學(xué)與學(xué)科專業(yè)相結(jié)合的探索
提高《匯編語(yǔ)言程序設(shè)計(jì)》教學(xué)效率的思考與實(shí)踐
高職高專院校C語(yǔ)言程序設(shè)計(jì)教學(xué)改革探索
試論匯編語(yǔ)言與C語(yǔ)言的混合程序設(shè)計(jì)技術(shù)
電子世界(2015年18期)2015-03-26 22:36:05
論子函數(shù)在C語(yǔ)言數(shù)據(jù)格式輸出中的應(yīng)用
非計(jì)算機(jī)專業(yè)C語(yǔ)言教學(xué)探討
河南科技(2014年23期)2014-02-27 14:19:16
龙里县| 通辽市| 海丰县| 太白县| 安岳县| 庐江县| 龙胜| 揭东县| 栾城县| 呼玛县| 阳江市| 图木舒克市| 理塘县| 景谷| 明光市| 汕尾市| 九龙坡区| 江达县| 米脂县| 嘉义县| 冀州市| 林甸县| 临西县| 鲁甸县| 高要市| 海伦市| 博乐市| 剑川县| 峡江县| 密山市| 宕昌县| 宜章县| 临洮县| 朝阳县| 独山县| 闻喜县| 鄄城县| 涟源市| 嘉黎县| 尖扎县| 五家渠市|