切换具有中断ATMEGA32A的led



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

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

1用主回路控制led。

1产生2Hz中断切换led ?

tnx提前

不,您需要编写一个程序。你的指导老师要求你理解中断是如何工作的。我只在C语言中做过这种程序,所以你必须在其他地方寻找关于这个主题的教程,或者等待另一个答案。

你的程序将设置寄存器来控制一些时钟,然后在进入一个循环之前使用SEI,该循环有一条指令使芯片进入睡眠状态。你必须选择正确的睡眠模式,这样时钟仍然运行,中断仍然发生。

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

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

你需要学习处理器的使用手册。它可以从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

我已经得到了代码的工作,下面的代码是一个ATmega32A的时钟为3686400Hz晶体

.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

最新更新