色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

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

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

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

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

          本文引用地址:http://cafeforensic.com/article/201612/325273.htm

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

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

          ret子程序返回指令

          reti中斷返回指令

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

          有了這個(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"); //返回并開中斷,開始運(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()的地址,開始運(yùn)行fun1().

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



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

          評(píng)論


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

          關(guān)閉