新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 一種基于avr的多任務(wù)機(jī)制

        一種基于avr的多任務(wù)機(jī)制

        作者: 時(shí)間:2016-11-18 來源:網(wǎng)絡(luò) 收藏
        首先要獲得函數(shù)的pc地址,并通過獲得的函數(shù)地址,輕松切換函數(shù)數(shù)。其目的是減少墜余的代碼。比如說對(duì)按鍵掃描的掃描,以達(dá)到精簡函數(shù)代碼,提高函數(shù)執(zhí)行效率。

        其主要的思想就是利用中斷返回的時(shí)候改變函數(shù)的返回地址,來實(shí)現(xiàn)的,當(dāng)然用指針也可以過得函數(shù)地址,以下是用iccavr仿真編譯軟件和hex文件反匯編軟件以及proteus仿真實(shí)驗(yàn),單片機(jī)atmega16調(diào)試的內(nèi)容。
        首先,我們用C語言編譯以一段函數(shù),自定義4個(gè)不同的函數(shù),舉例:3個(gè)發(fā)光二極管發(fā)光來指示。
        如:
        #include
        #include
        unsigned int sp_ZHI=0,SP_init=0;

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


        void LED_1(void)
        { while(1){PORTB=(1<

        void LED_2(void)
        {while(1){PORTB=(1<

        void LED_3(void)
        { while(1){PORTB=(1<

        然后再設(shè)計(jì)一個(gè)關(guān)函數(shù),
        void LED_OFF(void)
        { while(1){PORTB=0;}}

        接著是中斷初始化及其端口配置,
        void INTER_init_0()
        {

        PORTA = 0xFF;
        DDRA = 0xff;
        PORTB = 0xff;
        DDRB = 0xff;
        PORTC = 0xFF;
        DDRC = 0x00;
        PORTD = 0xFF;
        DDRD = 0x00;

        MCUCR|=1<GICR|=(1<GIFR&=~(1<

        }
        中斷請(qǐng)求函數(shù)

        unsigned char k=4;
        //外部中斷0向量端口
        #pragma interrupt_handler int0_isr:iv_INT0
        void int0_isr(void)
        {

        k++;
        if(k>=4)
        k=0;
        SP=sp_ZHI-2;//這個(gè)sp_ZHI-2是通過反匯編看出來的,查看一下匯編。
        }

        //重置堆棧指針,防止堆棧溢出
        void SP_INIT(unsigned int a)
        {
        SP=a;

        }


        然后我們定義主函數(shù)
        其主函數(shù)的功能:

        開機(jī)顯示為3個(gè)發(fā)光二極管都發(fā)光

        通過按鍵中斷切換發(fā)光二極管。





        void main(void)
        { INTER_init_0();
        sp_ZHI=SP;
        SP_INIT(sp_ZHI);
        SREG|=0x80;//使能全局中斷
        PORTB = 0;
        while(1)
        {
        switch(k)
        {
        case 1:LED_1();break;
        case 2:LED_2();break;
        case 3:LED_3();break;
        default :LED_OFF();break;
        }
        }
        }

        以下以本C語言函數(shù)通過反匯編軟件編譯出來的匯編程序,
        ; reassembly of "實(shí)驗(yàn).hex"
        ; created by ReAVR V3.2.0
        ; at 2010/02/02 - 22:04:10
        ; for ICCAVR assembler
        ;---------------------------------------
        ; AVR_TYPE=
        ; FLASH_SIZE=8KB
        ; SRAM_START=0x60
        ;---------------------------------------
        .area text
        ;; older iccavr need different setup:
        ;; .area text (abs,ovr)
        ;; .org 0x0000
        ;---------------------------------------
        ; byte constants:
        ;
        k00 = 0x00 ;
        k01 = 0x01 ;
        k02 = 0x02 ;
        k03 = 0x03 ;
        k04 = 0x04 ;
        k10 = 0x10 ;
        k40 = 0x40 ;@
        k5F = 0x5F ; _
        k60 = 0x60 ; `
        k65 = 0x65 ; e
        kAA = 0xAA ; ?
        kBF = 0xBF ; ?
        kFF = 0xFF ;
        ;
        ; io register addresses:
        ;
        p11 = 0x11
        p12 = 0x12
        p14 = 0x14
        p15 = 0x15
        p17 = 0x17
        p18 = 0x18
        p1A = 0x1A
        p1B = 0x1B
        p35 = 0x35
        p3A = 0x3A
        p3B = 0x3B
        p3D = 0x3D
        p3E = 0x3E
        p3F = 0x3F
        ;
        ; bit numbers:
        ;
        b0 = 0x00
        b1 = 0x01
        b2 = 0x02
        b3 = 0x03
        b4 = 0x04
        b5 = 0x05
        b6 = 0x06
        b7 = 0x07
        ;---------------------------------------
        ;
        L0000:
        jmp __start ; L0033
        ; ----------- jump on last line
        jmp L0085
        ; ----------- jump on last line
        .word 0xFFFF ; pc=0x0004(0x0008)
        .word 0xFFFF ; pc=0x0005(0x000A)
        .word 0xFFFF ; pc=0x0006(0x000C)
        .word 0xFFFF ; pc=0x0007(0x000E)
        .word 0xFFFF ; pc=0x0008(0x0010)
        .word 0xFFFF ; pc=0x0009(0x0012)
        .word 0xFFFF ; pc=0x000A(0x0014)
        .word 0xFFFF ; pc=0x000B(0x0016)
        .word 0xFFFF ; pc=0x000C(0x0018)
        .word 0xFFFF ; pc=0x000D(0x001A)
        .word 0xFFFF ; pc=0x000E(0x001C)
        .word 0xFFFF ; pc=0x000F(0x001E)
        .word 0xFFFF ; pc=0x0010(0x0020)
        .word 0xFFFF ; pc=0x0011(0x0022)
        .word 0xFFFF ; pc=0x0012(0x0024)
        .word 0xFFFF ; pc=0x0013(0x0026)
        .word 0xFFFF ; pc=0x0014(0x0028)
        .word 0xFFFF ; pc=0x0015(0x002A)
        .word 0xFFFF ; pc=0x0016(0x002C)
        .word 0xFFFF ; pc=0x0017(0x002E)
        .word 0xFFFF ; pc=0x0018(0x0030)
        .word 0xFFFF ; pc=0x0019(0x0032)
        .word 0xFFFF ; pc=0x001A(0x0034)
        .word 0xFFFF ; pc=0x001B(0x0036)
        .word 0xFFFF ; pc=0x001C(0x0038)
        .word 0xFFFF ; pc=0x001D(0x003A)
        .word 0xFFFF ; pc=0x001E(0x003C)
        .word 0xFFFF ; pc=0x001F(0x003E)
        .word 0xFFFF ; pc=0x0020(0x0040)
        .word 0xFFFF ; pc=0x0021(0x0042)
        .word 0xFFFF ; pc=0x0022(0x0044)
        .word 0xFFFF ; pc=0x0023(0x0046)
        .word 0xFFFF ; pc=0x0024(0x0048)
        .word 0xFFFF ; pc=0x0025(0x004A)
        .word 0xFFFF ; pc=0x0026(0x004C)
        .word 0xFFFF ; pc=0x0027(0x004E)
        .word 0xFFFF ; pc=0x0028(0x0050)
        .word 0xFFFF ; pc=0x0029(0x0052)
        .word 0xFFFF ; pc=0x002A(0x0054)
        .word 0xFFFF ; pc=0x002B(0x0056)
        .word 0xFFFF ; pc=0x002C(0x0058)
        .word 0xFFFF ; pc=0x002D(0x005A)
        .word 0xFFFF ; pc=0x002E(0x005C)
        .word 0xFFFF ; pc=0x002F(0x005E)
        nop
        nop
        ; --------- this is skippy
        sbrs r16,b4
        ;
        __start::
        ; L0033:
        ldi r28,k5F
        ; --------- last may be skipped
        ; pc=0x34(0x68)
        ;
        ldi r29,k04
        out p3D,r28
        out p3E,r29
        subi r28,k10
        sbci r29,k00
        ldi r16,kAA
        std Y+o00,r16
        clr r0
        ldi r30,k65
        ldi r31,k00
        ldi r17,k00
        L003F:
        cpi r30,k65
        cpc r31,r17
        breq L0044
        ; ----- branch on last line
        st Z+,r0
        rjmp L003F
        ; ----------- jump on last line
        L0044:
        st Z,r16
        ldi r30,k60
        ldi r31,k00
        ldi r26,k60
        ldi r27,k00
        ldi r17,k00
        L004A:
        cpi r30,k65
        cpc r31,r17
        breq L0051
        ; ----- branch on last line
        lpm
        adiw r30,k01
        st X+,r0
        rjmp L004A
        ; ----------- jump on last line
        L0051:
        call L00A3
        L0053:
        rjmp L0053
        ; ----------- jump on last line
        ; pc=0x54(0xA8)
        ;
        L0054:
        rjmp L0057
        ; ----------- jump on last line
        L0055:
        ldi r24,k01
        out p18,r24
        L0057:
        rjmp L0055
        ; ----------- jump on last line
        ret
        ;----------------------*
        ; pc=0x59(0xB2)
        ;
        L0059:
        rjmp L005C
        ; ----------- jump on last line
        L005A:
        ldi r24,k02
        out p18,r24
        L005C:
        rjmp L005A
        ; ----------- jump on last line
        ret
        ;----------------------*
        ; pc=0x5E(0xBC)
        ;
        L005E:
        rjmp L0061
        ; ----------- jump on last line
        L005F:
        ldi r24,k04
        out p18,r24
        L0061:
        rjmp L005F
        ; ----------- jump on last line
        ret
        ;----------------------*
        ; pc=0x63(0xC6)
        ;
        L0063:
        rjmp L0066
        ; ----------- jump on last line
        L0064:
        clr r2
        out p18,r2
        L0066:
        rjmp L0064
        ; ----------- jump on last line
        ret
        ;----------------------*
        ; pc=0x68(0xD0)
        ;
        L0068:
        sts (p3E+0x20),r17 ; io register
        sts (p3D+0x20),r16 ; io register
        ret
        ;----------------------*
        ; pc=0x6D(0xDA)
        ;
        L006D:
        ldi r24,kFF
        out p1B,r24
        out p1A,r24
        out p18,r24
        out p17,r24
        out p15,r24
        clr r2
        out p14,r2
        out p12,r24
        out p11,r2
        in r24,p35
        ori r24,k02
        out p35,r24
        in r24,p35
        ori r24,k01
        out p35,r24
        in r24,p3B
        ori r24,k40
        out p3B,r24
        in r24,p3A
        andi r24,kBF
        out p3A,r24
        sei
        ret
        ;----------------------*
        ; pc=0x85(0x10A)
        ;
        L0085:
        st -Y,r2
        st -Y,r24
        st -Y,r25
        in r2,p3F
        st -Y,r2
        lds r24,D0064
        subi r24,kFF
        sts D0064,r24
        cpi r24,k04
        brcs L0094
        ; ----- branch on last line
        clr r2
        sts D0064,r2
        L0094:
        lds r24,D0060
        lds r25,D0061
        sbiw r24,k02
        sts (p3E+0x20),r25 ; io register
        sts (p3D+0x20),r24 ; io register
        ld r2,Y+
        out p3F,r2
        ld r25,Y+
        ld r24,Y+
        ld r2,Y+
        reti
        ;----------------------*
        ; pc=0xA3(0x146)
        ;
        L00A3:
        rcall L006D
        in r2,p3D
        in r3,p3E
        sts D0061,r3
        sts D0060,r2
        movw r16,r2
        rcall L0068
        sei
        clr r2
        out p18,r2
        rjmp L00C7
        ; ----------- jump on last line
        L00B0:
        lds r20,D0064
        clr r21
        cpi r20,k01
        ldi r30,k00
        cpc r21,r30
        breq L00C0
        ; ----- branch on last line
        cpi r20,k02
        ldi r30,k00
        cpc r21,r30
        breq L00C2
        ; ----- branch on last line
        cpi r20,k03
        ldi r30,k00
        cpc r21,r30
        breq L00C4
        ; ----- branch on last line
        rjmp L00C6
        ; ----------- jump on last line
        L00C0:
        rcall L0054
        rjmp L00C7
        ; ----------- jump on last line
        L00C2:
        rcall L0059
        rjmp L00C7
        ; ----------- jump on last line
        L00C4:
        rcall L005E
        rjmp L00C7
        ; ----------- jump on last line
        L00C6:
        rcall L0063
        L00C7:
        rjmp L00B0
        ; ----------- jump on last line
        ret
        ;----------------------*
        ; pc=0xC9(0x192)
        ;
        __text_end::
        ;
        ; last flash byte address = 0x0191
        ; last flash word address = 0x00C8
        ;---------------------------------------
        .area bss (abs)
        .org 0x0060
        ;
        __first_bss::
        ;
        D0060:
        .blkb 1
        D0061:
        .blkb 3
        D0064:
        ;
        __last_bss::
        ;
        ; last lds/sts data byte at 0x0064
        ;---------------------------------------
        ;



        關(guān)鍵詞: avr多任務(wù)機(jī)

        評(píng)論


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

        關(guān)閉
        主站蜘蛛池模板: 灌阳县| 南充市| 岑溪市| 基隆市| 榆社县| 香港 | 青浦区| 鱼台县| 确山县| 台中县| 淮滨县| 榕江县| 静海县| 盘锦市| 同仁县| 九龙城区| 鹰潭市| 资源县| 宜城市| 襄城县| 太白县| 沾益县| 竹山县| 义马市| 电白县| 松滋市| 鹤岗市| 桐庐县| 平定县| 黔西县| 同德县| 漯河市| 黔南| 增城市| 杭锦旗| 巫溪县| 定襄县| 西安市| 盐山县| 东山县| 澄迈县|