日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]  一、混合編程  1、模塊內(nèi)接口:  使用如下標(biāo)志符:  #pragma asm  匯編語(yǔ)句  #pragma endasm  注意:如果在c51程序中使用了匯編語(yǔ)言,注意在keil編譯器中需要激活Properties中的“Generate Assemble

  一、混合編程
  1、模塊內(nèi)接口:
  使用如下標(biāo)志符:
  #pragma asm
  匯編語(yǔ)句
  #pragma endasm
  注意:如果在c51程序中使用了匯編語(yǔ)言,注意在keil編譯器中需要激活Properties中的“Generate Assembler SRC File” 和“Assembler SRC File ”兩個(gè)選項(xiàng)。來(lái)個(gè)實(shí)例吧:

#includevoidmain(void){P2=1;#pragmaasmMOVR7,#10DEL:MOVR6,#20DJNZR6,$DJNZR7,DEL#pragmaendasmP2=0;}

  另:
  1、把"xx.c"加入工程中,右擊"xx.c"選擇“options for file"xx.c" 選擇“Generate Assembler SRC File”和“Assemble SRC File”打上黑勾有效;
  2、根據(jù)選擇的編譯模式,把相應(yīng)的庫(kù)文件象加"xx.c"一樣加入工程中并放在"xx.c"下面,如smail模式下選"keilc51libc51s.lib"加入工程中。如果要進(jìn)行浮點(diǎn)運(yùn)算把"keilc51libc51fpl.lib"也加入工程中。
在 Keil 安裝目錄下的 C51LIB 目錄的LIB 文件如下:

  C51S.LIB - 沒(méi)有浮點(diǎn)運(yùn)算的 Small model
  C51C.LIB - 沒(méi)有浮點(diǎn)運(yùn)算的 Compact model
  C51L.LIB - 沒(méi)有浮點(diǎn)運(yùn)算的 Large model
  C51FPS.LIB - 帶浮點(diǎn)運(yùn)算的 Small model
  C51FPC.LIB - 帶浮點(diǎn)運(yùn)算的 Compact model
  C51FPL.LIB - 帶浮點(diǎn)運(yùn)算的 Large model

  3、在"xx.c"頭文件中加入優(yōu)化:比如#pragma OT(4,speed)
  4、在"xx.c"中加入?yún)R編代碼

#pragmaASM;AssemblerCodeHere#pragmaENDASM

  5、編譯生成xx.hex
  注意:
沒(méi)有做第一步會(huì)有如下警告:'asm/endasm' requires src-control to be active
沒(méi)有做第二步會(huì)有如下警告:UNRESOLVED EXTERNAL SYMBOL;REFERENCE MADE TO UNRESOLVED EXTERNAL等
沒(méi)有做第三步會(huì)有如下警告:UNDEFINED SYMBOL (PASS-2)

  二、中斷使用  interrupt xx using y
  跟在interrupt 后面的xx 值得是中斷號(hào),就是說(shuō)這個(gè)函數(shù)對(duì)應(yīng)第幾個(gè)中斷端口,一般在51中
0 外部中斷0
1 定時(shí)器0
2 外部中斷1
3 定時(shí)器1
4 串行中斷
  其它的根據(jù)相應(yīng)的單片機(jī)有自己的含義,實(shí)際上C在編譯的時(shí)候就是把你這個(gè)函數(shù)的入口地址放到這個(gè)對(duì)應(yīng)中斷的跳轉(zhuǎn)地址 。

  using y 這個(gè)y時(shí)說(shuō)這個(gè)中斷函數(shù)使用的那個(gè)寄存器組就是51里面一般有4個(gè) r0 -- r7寄存器,如果你的終端函數(shù)和別的程序用的不是同一個(gè)寄存器組,則進(jìn)入中斷的時(shí)候就不會(huì)將寄存器組壓入堆棧,返回時(shí)也不會(huì)彈出來(lái)節(jié)省代碼和時(shí)間。

  三、關(guān)于reentrant的使用方法及問(wèn)題原因分析
  
我在程序中出現(xiàn)了如下警告:
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_CRCDATA?PANEL_DISP
CALLER1: ?C_C51STARTUP
CALLER2: ?PR?UART_RECV?PANEL_DISP
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?ANALOGALLBECKON?PANEL_DISP
CALLER1: ?C_C51STARTUP
CALLER2: ?PR?UART_RECV?PANEL_DISP
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?SWITCHALLBECKON?PANEL_DISP
CALLER1: ?C_C51STARTUP
CALLER2: ?PR?UART_RECV?PANEL_DISP

///////////////////

  該警告表示連接器發(fā)現(xiàn)有一個(gè)函數(shù)可能會(huì)被主函數(shù)和一個(gè)中斷服務(wù)程序(或者調(diào)用中斷服務(wù)程序的函數(shù))同時(shí)調(diào)用,或者同時(shí)被多個(gè)中斷服務(wù)程序調(diào)用。出現(xiàn)這種問(wèn)題的原因之一是這個(gè)函數(shù)是不可重入性函數(shù),當(dāng)該函數(shù)運(yùn)行時(shí)它可能會(huì)被一個(gè)中斷打斷,從而使得結(jié)果發(fā)生變化,并可能會(huì)引起一些變量形式的沖突(即引起函數(shù)內(nèi)一些數(shù)據(jù)的丟失,可重入性函數(shù)在任何時(shí)候都可以被ISR打斷,一段時(shí)間后又可以運(yùn)行,但是相應(yīng)數(shù)據(jù)不會(huì)丟失)。
原因之二是用于局部變量和變量(暫且這樣翻譯,arguments,[自變量,變?cè)粩?shù)值,用于確定程序或子程序的值])的內(nèi)存區(qū)被其他函數(shù)的內(nèi)存區(qū)所覆蓋,如果該函數(shù)被中斷,則它的內(nèi)存區(qū)就會(huì)被使用,這將導(dǎo)致其他函數(shù)的內(nèi)存沖突。
例如,第一個(gè)警告中函數(shù)WRITE_GMVLX1_REG 在D_GMVLX1.C 或者D_GMVLX1.A51被定義,它被一個(gè)中斷服務(wù)程序或者一個(gè)調(diào)用了中斷服務(wù)程序的函數(shù)調(diào)用了,調(diào)用它的函數(shù)是VSYNC_INTERRUPT,在MAIN.C中。
  解決方法:如果你確定兩個(gè)函數(shù)決不會(huì)在同一時(shí)間執(zhí)行(該函數(shù)被主程序調(diào)用并且中斷被禁止),并且該函數(shù)不占用內(nèi)存(假設(shè)只使用寄存器),則你可以完全忽略這種警告。
如果該函數(shù)占用了內(nèi)存,則應(yīng)該使用連接器(linker)OVERLAY指令將函數(shù)從覆蓋分析(overlay analysis)中除去,例如:OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
上面的指令防止了該函數(shù)使用的內(nèi)存區(qū)被其他函數(shù)覆蓋。如果該函數(shù)中調(diào)用了其他函數(shù),而這些被調(diào)用在程序中其他地方也被調(diào)用,你可能會(huì)需要也將這些函數(shù)排除在覆蓋分析(overlay analysis)之外。這種OVERLAY指令能使編譯器除去上述警告信息。
如果函數(shù)可以在其執(zhí)行時(shí)被調(diào)用,則情況會(huì)變得更復(fù)雜一些。這時(shí)可以采用以下幾種方法:
1.主程序調(diào)用該函數(shù)時(shí)禁止中斷,可以在該函數(shù)被調(diào)用時(shí)用#pragma disable語(yǔ)句來(lái)實(shí)現(xiàn)禁止中斷的目的。必須使用OVERLAY指令將該函數(shù)從覆蓋分析中除去。
2.復(fù)制兩份該函數(shù)的代碼,一份到主程序中,另一份復(fù)制到中斷服務(wù)程序中。
3.將該函數(shù)設(shè)為重入型。例如:

voidmyfunc(void)reentrant{...}

///////////////////////
  我的程序編譯出來(lái)就這3個(gè)警告,但是程序可以正常下載運(yùn)行。但是我覺(jué)得有這些警告會(huì)使程序存在bug。從字面上看是它的意思是我程序中接受函數(shù)UART_RECV()多調(diào)用了analogAllBeckon()、switchAllBeckon()。
  因?yàn)?1的普通函數(shù)是不可重入的,變量放在固定的地址,兩個(gè)函數(shù)同時(shí)運(yùn)行時(shí),就會(huì)修改同一個(gè)變量,從而導(dǎo)致結(jié)果錯(cuò)誤。于是我在analogAllBeckon()、switchAllBeckon()函數(shù)后面加了void analogAllBeckon()reentrant{//All Analog data beckon使程序消除了警告。這種方法是表明函數(shù)是可被多個(gè)任務(wù)調(diào)用而不修改函數(shù)里邊的變量值,以此來(lái)實(shí)現(xiàn)函數(shù)的重入性。
  

  關(guān)于reentrant的使用keil的官方論壇上有詳細(xì)的討論.
  Andy Neil(官方工程師)建議:"Are you sure that you really need to make everything reentrant?...A reading of the Keil app notes & knowledgebase articles on this subject showed that it was not necessary. "
  由于每一次調(diào)用被reentrant聲明的函數(shù)都要把函數(shù)的參數(shù)和內(nèi)部變量壓棧,所以很容易使堆棧區(qū)溢出,S52只有256Bytes的data段,一個(gè)簡(jiǎn)單的函數(shù)如果有一個(gè)參數(shù)三個(gè)內(nèi)部變量,則需要壓棧4字節(jié)以上,這還不包括函數(shù)調(diào)用堆棧。reentrant其實(shí)并不是適合低端的單片機(jī),keil論壇上有人說(shuō)對(duì)于那些有KB以上RAM的單片機(jī)reentrant才適合。



  四、變量聲明有關(guān)
  在51系列中data,idata,xdata,pdata的區(qū)別:

data:固定指前面0x00-0x7f的128個(gè)RAM,可以用acc直接讀寫的,速度最快,生成的代碼也最小。

idata:固定指前面0x00-0xff的256個(gè)RAM,其中前128和data的128完全相同,只是因?yàn)樵L問(wèn)的方式不同。idata是用類似C中的指針?lè)绞皆L問(wèn)的。匯編中的語(yǔ)句為:moxACC,@Rx.(不重要的補(bǔ)充:c中idata做指針式的訪問(wèn)效果很好)。

xdata:外部擴(kuò)展RAM,一般指外部0x0000-0xffff空間,用DPTR訪問(wèn)。

pdata:外部擴(kuò)展RAM的低256個(gè)字節(jié),地址出現(xiàn)在A0-A7的上時(shí)讀寫,用movx ACC,@Rx讀寫。這個(gè)比較特殊,而且C51好象有對(duì)此BUG, 建議少用。但也有他的優(yōu)點(diǎn),具體用法屬于中級(jí)問(wèn)題,這里不提。

  startup.a51的作用和匯編一樣,在C中定義的那些變量和數(shù)組的初始化就在startup.a51中進(jìn)行,如果你在定義全局變量時(shí)帶有數(shù)值,如unsigned char data xxx="100";,那startup.a51中就會(huì)有相關(guān)的賦值。如果沒(méi)有=100,startup.a51就會(huì)把他清0。(startup.a51==變量的初始化)。這些初始化完畢后,還會(huì)設(shè)置SP指針。對(duì)非變量區(qū)域,如堆棧區(qū),將不會(huì)有賦值或清零動(dòng)作。有人喜歡改startup.a51,為了滿足自己一些想當(dāng)然的愛(ài)好,這是不必要的,有可能錯(cuò)誤的。比如掉電保護(hù)的時(shí)候想保存一些變量,但改startup.a51來(lái)實(shí)現(xiàn)是很笨的方法,實(shí)際只要利用非變量區(qū)域的特性,定義一個(gè)指針變量指向堆棧低部:0xff處就可實(shí)現(xiàn)。為什么還要去改? 可以這么說(shuō):任何時(shí)候都可以不需要改startup.a51,如果你明白它的特性。


  五、類型有關(guān)
用bit能夠定義一個(gè)變量,用sbit卻不行,sbit能夠定義端口。


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

嵌入式開(kāi)發(fā)作為一種專業(yè)且技術(shù)密集型的領(lǐng)域,涵蓋了從硬件底層驅(qū)動(dòng)、中間件到應(yīng)用層軟件開(kāi)發(fā)等多個(gè)層面的工作,其所需的工具種類繁多,各有針對(duì)性,旨在提升開(kāi)發(fā)效率、保證代碼質(zhì)量以及簡(jiǎn)化調(diào)試過(guò)程。

關(guān)鍵字: 嵌入式開(kāi)發(fā) keil

之后新建新的工程,添加.a文件就可以使用了,當(dāng)然也可以使用keil來(lái)添加,但是keil默認(rèn)的是用.lab,需要自己配置一下文件屬性,改為lib文件即可。一半release sdk的時(shí)候用這種方式很關(guān)鍵的,畢竟自己的核心代...

關(guān)鍵字: keil 文件屬性 lib文件

DSP28335與AD7606通過(guò)SPI的串行數(shù)據(jù)交互

關(guān)鍵字: keil C

為幫助大家更好使用單片機(jī)編程軟件,本文將對(duì)keil單片機(jī)編程軟件仿真、調(diào)劑技巧予以講解,并對(duì)該單片機(jī)編程軟件的常見(jiàn)錯(cuò)誤提示予以闡述。

關(guān)鍵字: 單片機(jī)編程軟件 指數(shù) keil

本文對(duì)于單片機(jī)編程軟件的介紹將基于如何采用keil單片機(jī)編程軟件調(diào)試stm32,如果你對(duì)單片機(jī)編程軟件抑或本文內(nèi)容具有興趣,不妨繼續(xù)往下閱讀哦。

關(guān)鍵字: 單片機(jī)編程軟件 指數(shù) keil

本文對(duì)于單片機(jī)編程軟件的介紹基于兩點(diǎn):1.keil單片機(jī)編程軟件編譯環(huán)境優(yōu)化等級(jí)說(shuō)明,2.keil單片機(jī)編程軟件中兩大概念名詞解析。

關(guān)鍵字: 單片機(jī)編程軟件 指數(shù) keil

為增加大家對(duì)單片機(jī)編程軟件的了解,本文將對(duì)keil單片機(jī)編程軟件予以介紹,主要在于介紹該單片機(jī)編程軟件的模式設(shè)置和一些編程事項(xiàng)。

關(guān)鍵字: keil 單片機(jī)編程軟件 指數(shù)

為幫助大家更快學(xué)會(huì)單片機(jī)編程軟件的使用,本文將對(duì)keil單片機(jī)編程軟件的使用方法加以介紹。如果你對(duì)本文內(nèi)容具有興趣,不妨繼續(xù)往下閱讀哦。

關(guān)鍵字: keil 單片機(jī)編程軟件 指數(shù)

本文對(duì)單片機(jī)編程軟件的介紹基于Keil,主要在于介紹keil單片機(jī)編程軟件如何將hex下載進(jìn)STM32,如何燒寫hex文件以及如何直接使用二進(jìn)制數(shù)。

關(guān)鍵字: keil 單片機(jī)編程軟件 指數(shù)
關(guān)閉