天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術熱線: 4007-888-234

技術支持

用PIC12F509單片機控制LED

更新時間: 2019-01-05

PIC12F509 - 繞過堆棧限制

12C5系列PIC只有一個兩級堆棧,它將嵌套子程序調用的數量限制為兩個。這可能是一個非常嚴重的限制。

(16C84有一個八級堆棧,它允許嵌套的子程序達到八個深度。我無法想象一個程序,這是不夠的)。

在以下程序中,提供了另一個用戶堆棧,它為程序員提供了替代的“調用”和“返回”功能。

請注意,使用最高數據地址實現用戶堆棧。這個想法是用戶堆棧從1FH開始增長,而用戶變量從07H及以上分配。因此,使用這種方法允許的嵌套程度是完全變量空間(25)減去在程序中用作變量的字節數。

這種方法還有兩個局限性;

1.只有程序計數器的低字節保存在用戶堆棧中。因此,這限制了所有函數的調用以及函數的實現到同一頁面。

但是,這并不妨礙人們將程序分成幾頁并在每頁上實現每個被調用的函數。當然,不同頁面上相同的函數實現必須具有不同的名稱。也就是說,一定要小心并思考。但是,隨著12C5XX的價格下降到僅僅1.00美元,我們需要思考!

這種分離程序的方法在另一個涉及I2C總線的討論中顯示。

  1. FSR用作用戶定義的堆棧指針。因此,如果在其他地方使用FSR寄存器,則在將FSR用于其他應用程序時必須小心將用戶堆棧指針保存在臨時變量中,當然,當使用此方法進行調用和返回時,將其還原到FSR。

請參考程序STACK_1.ASM,它會持續閃爍LED指示燈。請注意,主調用例程SUB1,DELAY,SUB2和DELAY然后循環返回以重復該過程。

FSR寄存器初始化為最高數據位置01FH。

每個“呼叫”包含以下說明。

MOVF PCL,W; 將PCL提取到W ADDWF OFFSET,W; 加4 MOVWF INDF; 保存到FSR DECF FSR 指向的位置,F; 用于下一個子程序GOTO SUB1; 打開LED

RET_POINT1:; …程序的繼續

在上文中,請注意,獲取程序計數器的低字節的當前內容。要返回的地址(RET_POINT1)通過添加4來計算,并將其保存到用戶堆棧指針指向的位置。然后遞減堆棧指針以容納下一個返回地址。最后,執行跳轉到該函數。

在子例程中,首先執行任務。然后使用以下代碼實現“返回”。

; 任務執行INCF FSR,F; 返回MOVF INDF,W MOVWF PCL

在上文中,用戶堆棧指針遞增以便指向包含存儲在調用例程中的程序計數器的值的位置。這被取出并放在程序計數器的低字節中。因此,執行在調用例程的返回點繼續。

; STACK_1.ASM(12F509); ; 說明如何使用用戶堆棧來實現“調用”和“返回”。; 這在12F509上尤為重要,因為疊加限于; 兩個級別。; ; 閃爍GPIO0上的LED,250 ms開啟和250 ms關閉。

列表p = 12F509

include __CONFIG 1AH

LOOP1 EQU 07H; 用于定時環路LOOP2 EQU 08H OFFSET EQU 09H

ORG 000H

MOVLW 1FH; 初始化FSR以指向“堆疊” MOVWF FSR的頂部

MOVLW .4 MOVWF OFFSET; 偏移初始化為4

MOVLW 1EH; 最小符號位是輸出TRIS GPIO TOP : ; 保存堆棧上的返回地址MOVF PCL,W; 獲取PCL,添加4并保存在ADDWF OFFSET,W 位置; FSR MOVWF INDF DECF FSR 指出,F; dec堆棧指針用于下一個子程序GOTO SUB1; 打開LED

MOVF PCL,W ADDWF OFFSET,W MOVWF INDF DECF FSR,F GOTO DELAY; 250毫秒延遲

MOVF PCL,W ADDWF OFFSET,W MOVWF INDF DECF FSR,F GOTO SUB2; 關閉LED

MOVF PCL,W ADDWF OFFSET,W MOVWF INDF DECF FSR,F GOTO DELAY; 250毫秒延遲

GOTO TOP

SUB1:BCF GPIO,0; 邏輯零點亮LED

; 這三行是返回INCF FSR,F的等價物; 增量FSR MOVF INDF,W; 獲得返回地址MOVWF PCL; 并放入程序計數器

SUB2:BSF GPIO,0; 邏輯1關閉LED INCF FSR,F; 返回MOVF INDF,W MOVWF PCL

延遲:; 運行時將LOOP1設置為.250,將LOOP2設置為.110。; 這將導致250毫秒的延遲。MOVLW .250 MOVWF LOOP1 OUTTER:MOVLW .110; 當設置為.110 MOVWF LOOP2 INNER:NOP NOP DECFSZ LOOP2,F 時接近1.0毫秒延遲; 減量和離開結果為LOOP2 ; 如果為零則跳過下一個語句

GOTO INNER DECFSZ LOOP1,F GOTO OUTTER

INCF FSR,F; 返回MOVF INDF,W MOVWF PCL

結束

在程序STACK_2.ASM中,“調用”和“返回”是使用已標記為GOSUB和RET的宏實現的。請注意,宏使程序更容易理解。

; STACK_2.ASM。; ; 與STACK_1.ASM相同,但使用宏實現。; ; 版權所有,Peter H. Anderson,MSU,1997年6月1日

列表p = 12F509 #include __CONFIG 1AH

; 宏定義了GOSUB MACRO arg1; 使用用戶定義的堆棧保存返回地址MOVF PCL,W; 并跳轉到指定的例程。ADDWF OFFSET,W MOVWF INDF DECF FSR,F GOTO arg1

ENDM

RET MACRO; 從堆棧INCF FSR,F MOVF INDF,W MOVWF PCL 獲取返回地址

ENDM

LOOP1 EQU 0CH; 用于定時環路LOOP2 EQU 0DH OFFSET EQU 0EH

ORG 000H

MOVLW 1FH; 初始化FSR以指向“堆疊” MOVWF FSR的頂部

MOVLW .4 MOVWF OFFSET; 將OFFSET初始化為4

MOVLW 1EH TRIS GPIO; 最小符號位定義為輸出TOP:GOSUB SUB1 GOSUB DELAY GOSUB SUB2 GOSUB DELAY GOTO TOP

SUB1:BCF GPIO,0 RET SUB2:BSF GPIO,0 RET DELAY :; 運行時將LOOP1設置為.250,將LOOP2設置為.110。; 這將導致250毫秒的延遲。MOVLW .250 MOVWF LOOP1 OUTTER:MOVLW .110; 當設置為.110 MOVWF LOOP2 INNER:NOP NOP DECFSZ LOOP2,F 時接近1.0毫秒延遲; 減量和離開結果為LOOP2 ; 如果零GOTO INNER DECFSZ LOOP1,F GOTO OUTTER ,則跳過下一個語句

RET

結束

404
返回首頁 |  返回上一頁
联系我们: 濮阳市| 仪征市| 宁明县| 西和县| 吉首市| 铅山县| 镇安县| 湘潭市| 堆龙德庆县| 巴彦县| 乳山市| 时尚| 宣威市| 正蓝旗| 新安县| 定日县| 曲水县| 门源| 体育| 临沂市| 抚远县| 新沂市| 巩义市| 巫山县| 淮滨县| 河北区| 商都县| 木兰县| 汉中市| 平凉市| 武安市| 汉中市| 双峰县| 佛山市| 门头沟区| 尼玛县| 崇左市| 扶沟县| 佛冈县| 绥江县| 藁城市|