历史上的今天
返回首页

历史上的今天

今天是:2024年10月18日(星期五)

正在发生

2019年10月18日 | 用PIC12C509单片机控制LED

2019-10-18 来源:eefocus

PIC12C509 - Getting Around the Stack Limitation


The 12C5 series PIC has only a two level stack which limits the number of nested subroutine calls to two. This may be a very serious limitation.


(The 16C84 has an eight level stack which permits nested subroutines to eight deep. I can't imagine a program where this will not be sufficient).


In the following programs an alternative user stack is presented which provides the programmer with alternative "call" and "return" capability.


Note that a user stack is implemented using the highest data address. The idea is that the user stack grows down from 1FH, while user variables are assigned from 07H and up. Thus, the degree of nesting permitted using this approach is the full variable space (25) less the number of bytes which are used as variables in the program.


There are two other limitations to this approach;


1. Only the low byte of the program counter is saved on the user stack. Thus, this limits the calling of all functions and the implementation of the functions to the same page.


However, this does not preclude one from splitting a program over several pages and implementing each called function on each page. Of course, the same implementation of functions on different pages must have different names. That is, one must be careful and think. But with the price of the 12C5XX declining to a mere $1.00 it pays to think!


This approach of splitting a program is shown in another discussion dealing with the I2C bus.


2. The FSR is used as the user defined stack pointer. Thus, if the FSR register is used elsewhere, one must be careful to save the user stack pointer in a temporary variable when using the FSR for other applications and of course, restoring it to the FSR when calls and returns are made using this approach.


Please refer to program STACK_1.ASM which continually flashes an LED on and off. Note that the main calls routines SUB1, DELAY, SUB2 and DELAY and then loops back to repeat the process.


The FSR register is intialized to the highest data location, 01FH.


Each "call" consists of the following instructions.



MOVF PCL, W ; fetch PCL to W

ADDWF OFFSET, W ; add 4

MOVWF INDF ; save to location pointed to by FSR

DECF FSR, F ; for next subroutine

GOTO SUB1 ; turn LED on


RET_POINT1:

;... continuation of program


In the above, note that the current content of the low byte of the program counter is fetched. The address to return to (RET_POINT1) is calculated by adding 4 and this is saved to the location pointed to by the user stack pointer. The stack pointer is then decremented to accommodate the next return address. Finally, a jump to the function is executed.


In the subroutine, the task is first performed. The "return" is then implemented using the following code.



; task performed

INCF FSR, F ; return

MOVF INDF, W

MOVWF PCL


In the above, the user stack pointer is incremented so as to point to the location containing the value of the program counter which was stored in the calling routine. This is fetched and placed in the low byte of the program counter. Thus, execution continues at the return point in the calling routine.



; STACK_1.ASM (12C509)

;

; Illustrates how to use user stack to implement "calls" and "returns".

; This is particularly important on the 12C509 as to stack is limited to

; two levels.

;

; Flashes LED on GPIO0, 250 ms on and 250 ms off.



LIST p=12c509

#include

__CONFIG 1AH


LOOP1 EQU 07H ; for timing loops

LOOP2 EQU 08H

OFFSET EQU 09H


ORG 000H


MOVLW 1FH ; intitialize FSR to point to top of "stack"

MOVWF FSR


MOVLW .4

MOVWF OFFSET ; offset initialized to 4


MOVLW 1EH ; least sign bit is an output

TRIS GPIO


TOP:

; save return address on stack

MOVF PCL, W ; fetch PCL, add 4 and save at location

ADDWF OFFSET, W ; pointed to by FSR

MOVWF INDF

DECF FSR, F ; dec stack pointer for next subroutine

GOTO SUB1 ; turn LED on


MOVF PCL, W

ADDWF OFFSET, W

MOVWF INDF

DECF FSR, F

GOTO DELAY ; 250 ms delay


MOVF PCL, W

ADDWF OFFSET, W

MOVWF INDF

DECF FSR, F

GOTO SUB2 ; turn LED off


MOVF PCL, W

ADDWF OFFSET, W

MOVWF INDF

DECF FSR, F

GOTO DELAY ; 250 ms delay


GOTO TOP


SUB1:

BCF GPIO, 0 ; logic zero turns LED on


; these three lines are the equiv of a return

INCF FSR, F ; increment FSR

MOVF INDF, W ; get return address

MOVWF PCL ; and put in program counter


SUB2:

BSF GPIO, 0 ; logic one turns LED off


INCF FSR, F ; return

MOVF INDF, W

MOVWF PCL


DELAY: ; when running set LOOP1 to .250 and LOOP2 to .110.

; this will result in 250 ms delay.

MOVLW .250

MOVWF LOOP1

OUTTER:

MOVLW .110 ; close to 1.0 msec delay when set to .110

MOVWF LOOP2

INNER:

NOP

NOP

DECFSZ LOOP2, F ; decrement and leave result in LOOP2

; skip next statement if zero

GOTO INNER

DECFSZ LOOP1, F

GOTO OUTTER


INCF FSR, F ; return

MOVF INDF, W

MOVWF PCL


END


In program STACK_2.ASM, the "calls" and "returns" are implemented using macros which have been labelled as GOSUB and RET. Note that macros make the program considerably more understandable.



; STACK_2.ASM.

;

; Same as STACK_1.ASM except implemented using macros.

;

; coyright, Peter H. Anderson, MSU, June 1, '97


LIST p=12c509

#include

__CONFIG 1AH


; Macros defined

GOSUB MACRO arg1 ; uses user defined stack to save return address

MOVF PCL, W ; and jumps to specified routine.

ADDWF OFFSET, W

MOVWF INDF

DECF FSR, F

GOTO arg1


ENDM


RET MACRO ; fetches return address from stack

INCF FSR, F

MOVF INDF, W

MOVWF PCL


ENDM


LOOP1 EQU 0CH ; for timing loops

LOOP2 EQU 0DH

OFFSET EQU 0EH


ORG 000H


MOVLW 1FH ; intitialize FSR to point to top of "stack"

MOVWF FSR


MOVLW .4

MOVWF OFFSET ; intialize OFFSET to 4


MOVLW 1EH

TRIS GPIO ; least sign bit is defined as output


TOP:

GOSUB SUB1

GOSUB DELAY

GOSUB SUB2

GOSUB DELAY


GOTO TOP


SUB1:

BCF GPIO, 0

RET

SUB2:

BSF GPIO, 0

RET


DELAY: ; when running set LOOP1 to .250 and LOOP2 to .110.

; this will result in 250 ms delay.

MOVLW .250

MOVWF LOOP1

OUTTER:

MOVLW .110 ; close to 1.0 msec delay when set to .110

MOVWF LOOP2

INNER:

NOP

NOP

DECFSZ LOOP2, F ; decrement and leave result in LOOP2

; skip next statement if zero

GOTO INNER

DECFSZ LOOP1, F

GOTO OUTTER


RET


END

推荐阅读

史海拾趣

D1 International Inc公司的发展小趣事

在快速扩张的过程中,D1 International Inc公司始终坚守品质管理的原则。公司严格把控产品的每一个环节,从原材料采购到生产流程,再到最终的产品检验,都力求做到精益求精。这种对品质的执着追求,使得D1 International Inc公司的产品在市场上赢得了良好的口碑,也为公司的长期发展提供了有力保障。

Diconex公司的发展小趣事

随着环保意识的不断提高,电子行业的环保要求也越来越高。Diconex公司积极响应环保号召,将环保理念融入生产全过程。公司采用环保材料和工艺进行生产,降低生产过程中的污染排放。同时,公司还建立了完善的废弃物处理机制,确保废弃物得到合理处理和资源化利用。这种环保理念的实施不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实基础。

Broadband公司的发展小趣事

在电子行业的激烈竞争中,Diconex公司凭借其卓越的技术创新能力脱颖而出。公司成立之初,便专注于研发高性能、低能耗的半导体芯片。通过不断的研发投入和团队努力,Diconex成功推出了一系列具有行业领先水平的产品,赢得了客户的广泛认可。随着技术的不断升级和市场需求的不断增长,Diconex逐渐在电子行业占据了一席之地。

ARRA Inc公司的发展小趣事

在电子行业中,Diconex公司始终坚持以客户需求为导向的市场定位策略。公司深入调研市场需求,针对不同客户群体推出定制化解决方案。这种精准的市场定位使得Diconex的产品能够更好地满足客户需求,赢得了客户的信任和忠诚。同时,公司还积极拓展国际市场,与全球知名企业建立了长期稳定的合作关系。

佰鸿(BrtLed)公司的发展小趣事

佰鸿公司一直非常重视技术创新和研发投入。通过不断的技术创新,公司成功开发出多款具有竞争力的LED产品,如高散热性发光二极管、贴片型发光二极管等。这些产品的推出,不仅提升了佰鸿在市场上的竞争力,也为其赢得了客户的广泛认可。此外,公司还积极申请专利保护,以确保其技术成果得到充分的保护。

DYMO公司的发展小趣事

在XX世纪XX年代,DYMO公司推出了一款具有划时代意义的标签打印机。这款打印机采用了全新的打印技术,能够打印出清晰、耐用的标签,并且支持多种字体和图案。这一创新技术让DYMO公司在标签打印领域取得了领先地位,并为其后续的产品线奠定了坚实的基础。

问答坊 | AI 解惑

理想、激情、生存—— 一位技术管理人员的20年工作经历和感悟

我是一个有10年电子产品研发经验的工程师和10年IT知名公司研发中心管理经验的技术管理者。世上好的管理理念可能归纳起来就那么1~2百条,也都好理解,难的是怎么适当地运用在特定的环境中。下面的文章共18篇,是我20年工作中的片段,也是我在研发及 ...…

查看全部问答>

96-24的大屏幕仿真

96*24的大屏幕仿真系统,非常实用。…

查看全部问答>

麻烦大家帮一下

一、编写程序,比较40H和50H中两个无符号数的大小,大的存放在61H中 ,小的存放在62H中。 二、试编写程序计算求和2i,其中,0〈i〈127.i的大小存放在40H 单元中,计算结果放在R3R2中。 三、假设R2R3中分别存放的是0~9之中的一个数,试编程, ...…

查看全部问答>

U-Boot简介

U-Boot  1 U-Boot简介   U-Boot,全称 Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化 ...…

查看全部问答>

中国科学院光电技术研究所2010年招聘

中国科学院光电技术研究所2010年招聘 根据目前光电所学科领域与科研项目发展的需要,现将2010年招聘岗位公布如下(详情请查看中科院光电所网站http://www.ioe.ac.cn,各类岗位将根据招聘进展情况随时进行调整):一、 招聘岗位招聘对象:国家重点 ...…

查看全部问答>

大家来晒晒自己的开发工具~~~

如题 要图哦 说说使用起来顺手不? 另外说说使用它的有趣经历~~~…

查看全部问答>

献给初学者:15个最基本报警知识

1、 报警系统由哪几部分组成?   简单的报警系统由前端探测器、中间传输部分和报警主机组成。大一些的系统也可将探测器和报警主机看做是前端部分,从报警主机到接警机之间是传输部分,中心接警部分看做是后端部分。 2、 报警系统按信息传输方式 ...…

查看全部问答>

16*16的led显示屏的实物怎么做?

外面的驱动电路怎么接,还有怎么把代码写进芯片里面啊?大概多少钱,at89c51,74ch154 74ch595 点阵,还要什么啊??…

查看全部问答>

好消息无线手表开发工具(售价仅24.50 美元)

好消息无线手表开发工具(售价仅24.50 美元),   介绍TI Deals !购买 TI折扣优惠工具及套件的全新方式!8 月 16 日,德州仪器推出 TI Deals 网站,设计人员有机会购买大额折扣的易用型开发工具及套件。现正5 折优惠销售 eZ430-Chronos 无线手 ...…

查看全部问答>