我有一个课程的小项目,要求我们使用PIC汇编语言生成PWM信号。为了简化操作,我将高时间设置为5ms,低时间设置为15ms,这样我就可以多次调用相同的延迟子例程。多次调用此延迟可能会导致堆栈下溢问题。
我真的不知道我可以尝试解决这个问题,因为我是非常新鲜的编程。我已经尝试在这个网站上搜索,以及一般,但还没有能够找到一个解决方案。我用MPLab 9.82以及。
代码如下所示:
list p=16F84A
#include <p16F84A.inc>
__CONFIG _CP_OFF & _XT_OSC & _PWRTE_ON & _WDT_OFF ;turn off watchdog timer
org 0x00 ; program starts at 0x00
counter equ 4Fh ; create a counter at position 4Fh in RAM
BSF STATUS, RP0 ; select bank 1
BCF TRISB, D'1' ; set port B pin 1 to output
BCF STATUS, RP0 ; select bank 0
goto main
main
BSF PORTB,1 ; turn port B pin 1 on
call delay_5ms ; calls sub routine for 5ms delay
BCF PORTB,1 ; turn port B pin 1 off
call delay_5ms ; calls sub routine for 5ms delay
call delay_5ms ; calls sub routine for 5ms delay
call delay_5ms ; calls sub routine for 5ms delay
delay_5ms
movlw D'200' ; put decimal number 200 into working register
movwf counter ; move 200 from working register into counter
lp nop ; no operation. just take 1 instruction
nop ; 1 instruction
decfsz counter ; 1 instruction and decreases counter by 1
goto lp ; 2 instructions (goto takes 2 instructions)
return
end
2条答案
按热度按时间0lvr5msh1#
每个嵌入式系统都需要一个无限循环。无限循环是必要的,因为嵌入式软件的工作永远不会完成。它的目的是运行,直到世界末日或板被重置,无论哪个先发生。此外,大多数嵌入式系统只有一个软件运行在他们身上。在非嵌入式系统中,当
main()
完成时,它返回到操作系统,程序从内存中删除。在嵌入式系统中,没有操作系统可以返回,程序不能从内存中删除。在汇编程序中,该结构可能如下所示:
或C语言
ig9co6j12#
正如Hans Passant所指出的,main需要一些方法来防止失败,为了更详细地解释这里发生的事情,让我们看一个C函数:
虽然不是最好的例子,但是我需要一个没有
return
语句的函数,至少在C语言中没有return
语句,但是在汇编语言中,这个函数(假设它没有内联)看起来像这样:用C编写的函数总是编译为带有 *return指令 * 的汇编函数(除非编译器内联该函数),即使您的函数没有C
return
语句。为什么需要这样做?因为ASM标签不存在。
程序集源文件中的一行带标签的代码只是对特定内存地址的引用。当我有下面的代码时:
goto main
只是一个硬件抽象,意思是“后藤main碰巧在的任何内存地址。分支是相对的还是绝对的,这无关紧要--汇编程序为您做数学运算,并用所需的偏移量替换goto main
中的main
,使分支带您到您想要的地方。然而,当创建可执行文件时,main:
(注意后面的冒号,我说的是标签本身)没有了,这导致了汇编语言的一些怪癖,而这些怪癖在其他语言中不会发生:第二,也是最重要的,没有什么可以阻止执行从标签中掉出来。
完全一样
也就是说,如果你想执行某个函数固定的次数,而没有循环的开销,那么你可以使用fallthrough。