新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 建立一個AVR的RTOS(2)—人工堆棧

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

        作者: 時間:2016-12-03 來源:網絡 收藏
        第二篇:人工堆棧

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

        本文引用地址:http://www.104case.com/article/201612/325273.htm

        rcall相對調用子程序指令

        icall間接調用子程序指令

        ret子程序返回指令

        reti中斷返回指令

        對于ret和reti,它們都可以將堆棧棧頂的兩個字節被彈出來送入程序計數器PC中,一般用來從子程序或中斷中退出。其中reti還可以在退出中斷時,重開全局中斷使能。

        有了這個基礎,就可以建立我們的人工堆棧了。

        例:

        #include <avr/io.h>

        void fun1(void)

        {

        unsigned char i=0;

        while(1)

        {

        PORTB=i++;

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

        }

        }

        unsigned char Stack[100]; //建立一個100字節的人工堆棧

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

        {

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

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

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

        __asm__ __volatile__("RET nt"); //返回并開中斷,開始運行fun1()

        }

        int main(void)

        {

        RunFunInNewStack(fun1,&Stack[99]);

        }

        RunFunInNewStack(),將指向函數的指針的值保存到一個unsigned char的數組Stack中,作為人工堆棧。并且將棧頂的數值傳遞組堆棧指針SP,因此當用"ret"返回時,從SP中恢復到PC中的值,就變為了指向fun1()的地址,開始運行fun1().

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



        關鍵詞: AVRRTOS人工堆

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 永春县| 安新县| 报价| 苍山县| 肥城市| 太仆寺旗| 绥芬河市| 鹤庆县| 桦川县| 陇西县| 阜南县| 吉木萨尔县| 云浮市| 喀什市| 安陆市| 崇州市| 鹿泉市| 海盐县| 江永县| 江西省| 通榆县| 松阳县| 大安市| 集安市| 任丘市| 彝良县| 德安县| 宣威市| 长泰县| 临沂市| 西乡县| 鄱阳县| 保山市| 曲周县| 惠州市| 法库县| 商城县| 四会市| 和硕县| 乌鲁木齐市| 宿松县|