使用中断 ATMEGA32A 切换 LED

Toggle leds with interrupts ATMEGA32A

我有一个学校任务,但连老师都不知道怎么做... 我们必须创建一个程序,让 LED 以 1Hz 的频率闪烁。我们使用的芯片是 ATmega32A,频率为 3,6864 MHz。 程序必须包含中断,这样主程序才能进入休眠状态。

现在我的问题是我找到了 SEI 和 RETI 函数,但是我是否正确理解我必须编写 2 个汇编程序?

1 用主循环来控制 LED。

1 生成 2Hz 中断来切换 LED?

提前tnx

不行,你需要写一个程序。你的导师要求你了解中断是如何工作的。我只用 C 编写过此类程序,因此您将不得不在别处寻找有关该主题的教程或等待其他答案。

您的程序将设置控制某些时钟的寄存器,然后在进入一个循环之前使用 SEI,该循环具有一条使芯片休眠的指令。您必须选择正确的睡眠模式,以便时钟仍然 运行 并且中断仍然发生。

您还将编写一个您永远不会调用的子例程中断处理程序。相反,您巧妙地设置了时钟,以便在时钟达到某个值时发生比较中断时调用您的处理程序。

由于芯片 运行ning 如此之快,处理程序将在 1 秒之前被调用,因此您的例程将不得不执行一些操作,例如递增计数器变量,直到达到某个值。如果达到该值,重置计数器并切换 LED。处理程序以 RETI 指令结束,让处理器知道 return 它被中断的主循环。

您需要阅读处理器的手册。它可以从 Atmel 网站获得。特别是,为您的中断处理程序选择一个时钟(16 位将在中断之间持续更长的时间),并查看本章末尾的寄存器描述。你会想要设置一个预分频器来减慢时钟计数器,并选择一个合适的比较值,这样很容易得到一个倍数达到1秒。

中断处理程序的伪代码类似于

add a number to the compare register to set up the next interrupt

if counter < limit then increment counter (this is not the clock counter. It is a variable in memory you have declared)
else reset the counter variable to 0 and toggle the LEDs
rti

我已经让代码正常工作以下代码适用于时钟为 3686400Hz 的 ATmega32A crystal

.org 0x000
    rjmp    reset
.org 0x00E
    rjmp    tc0_ocm_isr

.equ    dirleds     =DDRB
.equ    leds        =PORTB
.equ    allout      =0b1111_1111
.equ    allin       =0b0000_0000

.def    temp = r16
.def    allon = r17
.def    ledtemp = r18
.def    bitlow = r20
.def    bithigh= r21

    ldi     ledtemp,0x00
    ldi     allon,0xff
reset:


    ldi     bithigh, 0x07       
    ldi     bitlow, 0x07
    out     OCR1AH,bithigh
    out     OCR1AL,bitlow

    ldi     temp,0b00010000
    out     TIMSK,temp

    ldi     temp,0x0d
    out     TCCR1B,temp

    sei



loop:   
    rjmp    loop


tc0_ocm_isr:    
    eor     ledtemp,allon
    out     DDRB,ledtemp
    reti