AVR 定时器中断

AVR Timer interrupts

我不明白如何使用中断和定时器。你能解释一下怎么做吗? 我读了人的,但什么也不懂。这是代码:

    .include "C:\Users\user\Downloads/m328Pdef.inc"  
.MACRO  INVBM
    .if @0 < 0x40
    PUSH    R16
    PUSH    R17
    IN      R16,@0
    LDI     R17,1<<@1
    EOR     R17,R16
    OUT     @0,R17
    POP     R17
    POP     R16
    .else
    PUSH    R16
    PUSH    R17
    LDS     R16,@0
    LDI     R17,1<<@1
    EOR     R17,R16
    STS     @0,R17
    POP     R17
    POP     R16
    .endif
    .ENDM
      .ORG 0
     ON_RESET:
      ldi R16, 0b1000_0001
      OUT       DDRB,       R16
      LDI       R16,        0b0100_0010 ; CTC mode Timer1
      STS       TCCR1A,     R16 ;SET FLAG ON COMPARE MATCH
      LDI       R16,        0x0D ; maybe change to 0x05 0b0000_0101 
      STS       TCCR1B,     R16 ;SET PRESCALER TO /1024
      LDI       R16,        0 ; value to compare 0*16+255
      STS       OCR1AH, R16
      LDI       R16,        255
      STS       OCR1AL,     R16
      
      MAIN_LOOP:
      INVBM     PINB,       0
      RCALL     PAUSE
      RJMP  MAIN_LOOP
      
      PAUSE:
      
      PLUPE:
      IN        R16,        TIFR0
      CPI       R16,        0b0000_0010
      BRNE      PLUPE
      LDI       R16,        0b0000_0010
      OUT       TIFR0,      R16
      RET

我的 LED 没有闪烁。 [连接][1] [1]: https://i.stack.imgur.com/0EUSG.png

  ;====================================================================
; Main.asm file generated by New Project wizard
;
; Created:   Ср апр 7 2021
; Processor: ATmega328P
; Compiler:  AVRASM (Proteus)
;====================================================================
.include "C:\Users\user\Downloads\m328Pdef.inc"
;====================================================================
; DEFINITIONS
.list
.def temp=r16
.MACRO  INVBM
    .if @0 < 0x40
    PUSH    R16
    PUSH    R17
    IN      R16,@0
    LDI     R17,1<<@1
    EOR     R17,R16
    OUT     @0,R17
    POP     R17
    POP     R16
    .else
    PUSH    R16
    PUSH    R17
    LDS     R16,@0
    LDI     R17,1<<@1
    EOR     R17,R16
    STS     @0,R17
    POP     R17
    POP     R16
    .endif
    .ENDM
    
    .MACRO PUSHF
    PUSH    R16
    IN  R16,SREG
    PUSH    R16
    .ENDM


    .MACRO POPF
    POP R16
    OUT SREG,R16
    POP R16
    .ENDM
    
    
    .MACRO  SETB
        .if @0 < 0x20       ; Low IO
        SBI     @0,@1
        .else
            .if @0<0x40     ; High IO
        IN      @2,@0
        ORI     @2,1<<@1
        OUT     @0,@2
            .else           ; Memory
        LDS     @2,@0
        ORI     @2,1<<@1
        STS     @0,@2
            .endif
        .endif
    .ENDM
    
.dseg
.cseg
.ORG [=10=]0        ; (RESET) 
         RJMP   RESET
         .ORG [=10=]2
         RETI             ; (INT0) External Interrupt Request 0
         .ORG [=10=]4
         RETI             ; (INT1) External Interrupt Request 1
         .ORG [=10=]6
         RETI             ; (TIMER2 COMP) Timer/Counter2 Compare Match
         .ORG [=10=]8
         RETI             ; (TIMER2 OVF) Timer/Counter2 Overflow
         .ORG [=10=]A
         RETI             ; (TIMER1 CAPT) Timer/Counter1 Capture Event
         .ORG [=10=]C 
         RETI             ; (TIMER1 COMPA) Timer/Counter1 Compare Match A
         .ORG [=10=]E
         RETI             ; (TIMER1 COMPB) Timer/Counter1 Compare Match B
         .ORG 0
         RETI             ; (TIMER1 OVF) Timer/Counter1 Overflow
         .ORG 2
         RETI ; (TIMER0 OVF) Timer/Counter0 Overflow
         .ORG 4
         RETI           ; Timer1 Capture
         .ORG 6
         RJMP   Timer1_IRQ           ; Timer1 compare A
         .ORG 8
         RETI            ;Compare B
         .ORG A
         RETI           ; Timer1 overflow
         .ORG C
         RETI             ; (ADC) ADC Conversion Complete
         .ORG E
         RETI             ; (EE_RDY) EEPROM Ready
         .ORG 0
         RETI            ; (ANA_COMP) Analog Comparator
         .ORG 2
         RETI             ; (TWI) 2-wire Serial Interface
         .ORG 4
         RETI             ; (INT2) External Interrupt Request 2
         .ORG 6
         RETI             ; (TIMER0 COMP) Timer/Counter0 Compare Match
         .ORG 8
         RETI             ; (SPM_RDY) Store Program Memory Ready
        .ORG A
         RETI 
         .ORG C
         RETI 
         .ORG E
         RETI 
         .ORG 0
         RETI 
         
         .ORG 2
         RETI 
         
         
        .ORG   INT_VECTORS_SIZE
        
    Timer1_IRQ:
        CLI
        INVBM   PORTB, 0
        
        SEI
        RETI

    
      

;====================================================================
; CODE SEGMENT
;====================================================================
Reset:      LDI     R16,Low(RAMEND) ; Инициализация стека
            OUT     SPL,R16         ; Обязательно!!!

            LDI     R16,High(RAMEND)
            OUT     SPH,R16




Start:
ldi temp, 0b1111_1111 ; Устанавливает биты в 1 на выход
out DDRB, temp; OUTPUT PORTB0 
clr temp

LDI temp,0x0C
STS TCCR1B, temp
LDI temp,0x00
STS TCCR1A, temp
;LDI    temp,   0b1000_0000
;OUT    SREG,   temp
;SETB   TIMSK1,TOIE1,R16
SETB    TIMSK1,OCIE1A,R16
;LDI    temp,   0b0000_0001 ; TOIE in TISK1 OVERFLOW INTERRUPT ENABLE TIMER1 INT ENABLE
;STS    TIMSK1, temp
LDI     temp,   0x1E
STS     OCR1AH, temp
LDI     temp,   0x84
STS     OCR1AL, temp
SEI


Loop:
;ldi temp, 1 ;Загрузить константу в регистр 
;out PortB, temp
;clr temp
;out PortB, temp
;LDI temp,0x0F
;STS OCR1AH, temp
;LDI temp,0xFF
;STS OCR1AL, temp
      rjmp  Loop

使其工作的主要步骤: 1)处理我们需要的所有中断寄存器。给其他人写RETI。

2)堆栈寄存器中断必须初始化。 (RJMP 重置)

3)写入处理程序定时器。

4)使用DDR(A/B/C/D)将使用过的位转换为使用过的端口。 1 - 输出,0 - 输入。

5) 配置定时器 TCCR1B(对于 1 个定时器)0000_0101 - 1024 预分频器工作一次因为时间溢出。 Table 可以在net中找到。 0000_1101 - 相同,但在第一个中断之后,下一个将由清除溢出定时器自动启动。

6)TCCR1A 0000_0000 如果您不想使用特殊引脚查看定时器状态。

7) 如果您将中断与比较 A (B) 一起使用,您应该在寄存器 TIMSK1 中启用它中断(对于 1 个定时器)。它的 table 可以在 net 中找到。 F.e。 OCIE1A 使比较 A 中断使能。

8)写一个常量到OCR1A(for 1 timer)寄存器

9)启动全局中断

10)制作循环。

这听起来很可怕,但也许这可以帮助像我这样的人。