<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 建立一個(gè)AVR的RTOS(2)—人工堆棧

          建立一個(gè)AVR的RTOS(2)—人工堆棧

          作者: 時(shí)間:2016-12-03 來(lái)源:網(wǎng)絡(luò) 收藏
          第二篇:人工堆棧

          單片機(jī)的指令集中,一類指令是專門(mén)與堆棧和PC指針打道的,它們是

          本文引用地址:http://www.ex-cimer.com/article/201612/325273.htm

          rcall相對(duì)調(diào)用子程序指令

          icall間接調(diào)用子程序指令

          ret子程序返回指令

          reti中斷返回指令

          對(duì)于ret和reti,它們都可以將堆棧棧頂?shù)膬蓚€(gè)字節(jié)被彈出來(lái)送入程序計(jì)數(shù)器PC中,一般用來(lái)從子程序或中斷中退出。其中reti還可以在退出中斷時(shí),重開(kāi)全局中斷使能。

          有了這個(gè)基礎(chǔ),就可以建立我們的人工堆棧了。

          例:

          #include <avr/io.h>

          void fun1(void)

          {

          unsigned char i=0;

          while(1)

          {

          PORTB=i++;

          PORTC=0x01<<(i%8);

          }

          }

          unsigned char Stack[100]; //建立一個(gè)100字節(jié)的人工堆棧

          void RunFunInNewStack(void (*pfun)(),unsigned char *pStack)

          {

          *pStack--=(unsigned int)pfun>>8; //將函數(shù)的地址高位壓入堆棧,

          *pStack--=(unsigned int)pfun; //將函數(shù)的地址低位壓入堆棧,

          SP=pStack; //將堆棧指針指向人工堆棧的棧頂

          __asm__ __volatile__("RET nt"); //返回并開(kāi)中斷,開(kāi)始運(yùn)行fun1()

          }

          int main(void)

          {

          RunFunInNewStack(fun1,&Stack[99]);

          }

          RunFunInNewStack(),將指向函數(shù)的指針的值保存到一個(gè)unsigned char的數(shù)組Stack中,作為人工堆棧。并且將棧頂?shù)臄?shù)值傳遞組堆棧指針SP,因此當(dāng)用"ret"返回時(shí),從SP中恢復(fù)到PC中的值,就變?yōu)榱酥赶騠un1()的地址,開(kāi)始運(yùn)行fun1().

          上面例子中在RunFunInNewStack()的最后一句嵌入了匯編代碼"ret",實(shí)際上是可以去除的。因?yàn)樵赗unFunInNewStack()返回時(shí),編譯器已經(jīng)會(huì)加上"ret"。我特意寫(xiě)出來(lái),是為了讓大家看到用"ret"作為返回后運(yùn)行fun1()的過(guò)程。



          關(guān)鍵詞: AVRRTOS人工堆

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();