A
A
Artem Ivantsov2014-02-19 11:13:09
Arduino
Artem Ivantsov, 2014-02-19 11:13:09

How to solve interrupt problem on ATMega328P-PU?

The code is written in Atmel studio. Arduino UNO board with ATMega328P-PU. I'm uploading a hex file using XLoader v1.00. There are two problems.

First: Interrupt on PCIE0:2
.cseg
    .org	0

    rjmp	init	; Reset Handler
    reti			; IRQ0 Handler
    reti			; IRQ1 Handler
    rjmp	pci0	; PCINT0 Handler
    rjmp	pci1	; PCINT1 Handler
    rjmp	pci2	; PCINT2 Handler
    reti			; Watchdog Timer Handler
    reti			; Timer2 Compare A Handler
    reti			; Timer2 Compare B Handler
    reti			; Timer2 Overflow Handler
    reti			; Timer1 Capture Handler
    reti			; Timer1 Compare A Handler
    reti			; Timer1 Compare B Handler
    reti			; Timer1 Overflow Handler
    reti			; Timer0 Compare A Handler
    reti			; Timer0 Compare B Handler
    reti			; Timer0 Overflow Handler
    reti			; SPI Transfer Complete Handler
    reti			; USART, RX Complete Handler
    reti			; USART, UDR Empty Handler
    reti			; USART, TX Complete Handler
    reti			; ADC Conversion Complete Handler
    reti			; EEPROM Ready Handler
    reti			; Analog Comparator Handler
    reti			; 2-wire Serial Interface Handler
    reti			; Store Program Memory Ready Handler

;-------------------------- Инициализация стека

init:	ldi		r31, 0x8
    ldi		r30, 0xFF

    out		SPL, r30
    out		SPH, r31

;-------------------------- Активация прерываний

    ldi		r16, 1 << PCIE2 | 1 << PCIE1 | 1 << PCIE0
    sts		PCICR, r16

    ldi		r16, 1 << PCINT0
    sts		PCMSK0, r16

    ldi		r16, 1 << PCINT8
    sts		PCMSK1, r16

    ldi		r16, 1 << PCINT16
    sts		PCMSK2, r16

;-------------------------- Инициализация портов ВВ

    ldi		r16, 0b11111110
    out		DDRB, r16
    out		DDRC, r16
    out		DDRD, r16

    ldi		r16, 0b11111111
    out		PORTB, r16
    out		PORTC, r16
    out		PORTD, r16

    ldi		r16, 0b00000001

    sei
main:
    rjmp	main

pci0:	out		PORTB, r16
    reti

pci1:	out		PORTC, r16
    reti

pci2:	out		PORTD, r16
    reti

Регистры DDRB0, DDRC0, DDRD0 настроены на ввод, а так-же на генерацию прерывания при изменении сигнала. Все остальные на вывод.
Прерывание должно менять выходное значение на порту и зажигать диоды, но оно не происходит.
Second: Interrupt on INT0:1
;------------------------- Начало программного кода

    .cseg 	
    .org	0	

    rjmp	init	; Reset Handler
    rjmp	irq0	; IRQ0 Handler
    rjmp	irq1	; IRQ1 Handler
    reti			; PCINT0 Handler
    reti			; PCINT1 Handler
    reti			; PCINT2 Handler
    reti			; Watchdog Timer Handler
    reti			; Timer2 Compare A Handler
    reti			; Timer2 Compare B Handler
    reti			; Timer2 Overflow Handler
    reti			; Timer1 Capture Handler
    reti			; Timer1 Compare A Handler
    reti			; Timer1 Compare B Handler
    reti			; Timer1 Overflow Handler
    reti			; Timer0 Compare A Handler
    reti			; Timer0 Compare B Handler
    reti			; Timer0 Overflow Handler
    reti			; SPI Transfer Complete Handler
    reti			; USART, RX Complete Handler
    reti			; USART, UDR Empty Handler
    reti			; USART, TX Complete Handler
    reti			; ADC Conversion Complete Handler
    reti			; EEPROM Ready Handler
    reti			; Analog Comparator Handler
    reti			; 2-wire Serial Interface Handler
    reti			; Store Program Memory Ready Handler

;-------------------------- Инициализация стека

init:	ldi		r31, 0x8
    ldi		r30, 0xFF

    out		SPL, r30
    out		SPH, r31

;-------------------------- Активация прерываний

    ldi		r16, 1 << INT1 | 1 << INT0
    out		EIMSK, r16

    ldi		r16, 0 << ISC11 | 0 << ISC10 | 0 << ISC01 | 0 << ISC00
    sts		EICRA, r16

;-------------------------- Инициализация портов ВВ

    ldi		r16, 0b11110011
    out		DDRB, r16
    out		DDRD, r16

    ldi		r16, 0b11111111
    out		PORTB, r16
    out		PORTD, r16

    sei
main:
    rjmp	main

irq0:	ldi		r16, 0b11111110
    out		PORTB, r16
    reti

irq1:	ldi		r17, 0b11111101
    out		PORTB, r17
    reti

Регистры DDRD2:3 настроены на ввод, а так-же на генерацию прерывания при низком уровне. DDRB0:1 на вывод.
Прерывание по INT0 у меня вызывает не irq0, а irq1.
Дальше методом тыка я узнал, что INT1 у меня вызовет irq0, если я напишу так:
rjmp	init	; Reset Handler
    reti			; IRQ0 Handler
    rjmp	irq0	; IRQ1 Handler
    reti			; PCINT0 Handler
    rjmp	irq1	; PCINT1 Handler
    reti			; PCINT2 Handler

Я совсем ничего не понимаю, тк в даташите по другому написано.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
vanyamba-electronics, 2015-01-04
@Ramirag

In the datasheet, there is a typo about the vector table. RJMP is relative jmp, it takes 2 bytes. You need to use JMP, which takes 4 bytes. Four bytes per vector.

Button_1_LED.cpp.elf:     формат файла elf32-avr

Дизассемблирование раздела .text:

00000000 <__vectors>:
   0:   0c 94 63 00     jmp     0xc6    ; 0xc6 <__ctors_end>
   4:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
   8:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
   c:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  10:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  14:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  18:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  1c:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  20:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  24:   0c 94 c3 00     jmp     0x186   ; 0x186 <__vector_9>
  28:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  2c:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  30:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  34:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  38:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  3c:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  40:   0c 94 5c 04     jmp     0x8b8   ; 0x8b8 <__vector_16>
  44:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  48:   0c 94 09 03     jmp     0x612   ; 0x612 <__vector_18>
  4c:   0c 94 50 03     jmp     0x6a0   ; 0x6a0 <__vector_19>
  50:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  54:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  58:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  5c:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  60:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>
  64:   0c 94 8b 00     jmp     0x116   ; 0x116 <__bad_interrupt>

00000116 <__bad_interrupt>:
  116:   0c 94 00 00   jmp      0           ; 0x0 <__vectors>

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question