Почему мое прерывание в AVR не работает правильно? - PullRequest
0 голосов
/ 04 февраля 2020

РЕДАКТИРОВАТЬ: ЭТО РАБОТАЕТ

Я программирую связь Atmega8 с P C. Я использую Treminal v1.9b для отправки и получения «сообщений». Вот мой код:

#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <string.h>
#include <avr/interrupt.h>
#include <stdlib.h>

void print_char(char letter)
{
    if( bit_is_set(UCSRA, UDRE) )
    {
        _delay_ms(10);
        UDR=letter;
        loop_until_bit_is_set(UCSRA, TXC);
    }
}

volatile char what = 'x';

int main(void)
{
    DDRC |= (1<<PC0);
    DDRC |= (1<<PC1);
    DDRC |= (1<<PC2);

    UBRRL = 12;//4800 1mhz
    UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

    sei();

    PORTC ^= (1<<PC1);

    while(1)
    {
        print_char(what);
        PORTC ^= (1<<PC0);
        _delay_ms(100);
    }
}

ISR(USART_RXC_vect)
{
    what = UDR;
    PORTC ^= (1<<PC2);
}

После включения u C в консоли (Terminal v1.9b) появляется «x», после попытки что-либо отправить, «x» перестает появляться. Это как программа зависла или прерывание не вернулось к основной программе. (после отправки чего-либо на u C данное значение должно отображаться в консоли).

Когда u C включен, светодиод на ПК1 светится, на ПК0 мигает, на ПК2 темный. После отправки любого символа на u C: светодиод на ПК0 темный, на ПК1 светится, на ПК2 темный. Как будто функция ISR () не запускается.

В чем проблема?

.iss file:

usb2.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000106  00000000  00000000  00000074  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000002  00800060  00000106  0000017a  2**0
                  CONTENTS, ALLOC, LOAD, DATA

Disassembly of section .text:

00000000 <__vectors>:
   0:   29 c0           rjmp    .+82        ; 0x54 <__ctors_end>
   2:   00 00           nop
   4:   3a c0           rjmp    .+116       ; 0x7a <__bad_interrupt>
   6:   00 00           nop
   8:   38 c0           rjmp    .+112       ; 0x7a <__bad_interrupt>
   a:   00 00           nop
   c:   36 c0           rjmp    .+108       ; 0x7a <__bad_interrupt>
   e:   00 00           nop
  10:   34 c0           rjmp    .+104       ; 0x7a <__bad_interrupt>
  12:   00 00           nop
  14:   32 c0           rjmp    .+100       ; 0x7a <__bad_interrupt>
  16:   00 00           nop
  18:   30 c0           rjmp    .+96        ; 0x7a <__bad_interrupt>
  1a:   00 00           nop
  1c:   2e c0           rjmp    .+92        ; 0x7a <__bad_interrupt>
  1e:   00 00           nop
  20:   2c c0           rjmp    .+88        ; 0x7a <__bad_interrupt>
  22:   00 00           nop
  24:   2a c0           rjmp    .+84        ; 0x7a <__bad_interrupt>
  26:   00 00           nop
  28:   28 c0           rjmp    .+80        ; 0x7a <__bad_interrupt>
  2a:   00 00           nop
  2c:   55 c0           rjmp    .+170       ; 0xd8 <__vector_11>
  2e:   00 00           nop
  30:   24 c0           rjmp    .+72        ; 0x7a <__bad_interrupt>
  32:   00 00           nop
  34:   22 c0           rjmp    .+68        ; 0x7a <__bad_interrupt>
  36:   00 00           nop
  38:   20 c0           rjmp    .+64        ; 0x7a <__bad_interrupt>
  3a:   00 00           nop
  3c:   1e c0           rjmp    .+60        ; 0x7a <__bad_interrupt>
  3e:   00 00           nop
  40:   1c c0           rjmp    .+56        ; 0x7a <__bad_interrupt>
  42:   00 00           nop
  44:   1a c0           rjmp    .+52        ; 0x7a <__bad_interrupt>
  46:   00 00           nop
  48:   18 c0           rjmp    .+48        ; 0x7a <__bad_interrupt>
  4a:   00 00           nop
  4c:   16 c0           rjmp    .+44        ; 0x7a <__bad_interrupt>
  4e:   00 00           nop
  50:   14 c0           rjmp    .+40        ; 0x7a <__bad_interrupt>
    ...

00000054 <__ctors_end>:
  54:   11 24           eor r1, r1
  56:   1f be           out 0x3f, r1    ; 63
  58:   cf e5           ldi r28, 0x5F   ; 95
  5a:   d4 e0           ldi r29, 0x04   ; 4
  5c:   de bf           out 0x3e, r29   ; 62
  5e:   cd bf           out 0x3d, r28   ; 61

00000060 <__do_copy_data>:
  60:   10 e0           ldi r17, 0x00   ; 0
  62:   a0 e6           ldi r26, 0x60   ; 96
  64:   b0 e0           ldi r27, 0x00   ; 0
  66:   e6 e0           ldi r30, 0x06   ; 6
  68:   f1 e0           ldi r31, 0x01   ; 1
  6a:   02 c0           rjmp    .+4         ; 0x70 <.do_copy_data_start>

0000006c <.do_copy_data_loop>:
  6c:   05 90           lpm r0, Z+
  6e:   0d 92           st  X+, r0

00000070 <.do_copy_data_start>:
  70:   a2 36           cpi r26, 0x62   ; 98
  72:   b1 07           cpc r27, r17
  74:   d9 f7           brne    .-10        ; 0x6c <.do_copy_data_loop>
  76:   0c d0           rcall   .+24        ; 0x90 <main>
  78:   44 c0           rjmp    .+136       ; 0x102 <_exit>

0000007a <__bad_interrupt>:
  7a:   c2 cf           rjmp    .-124       ; 0x0 <__vectors>

0000007c <_Z10print_charc>:
  7c:   5d 9b           sbis    0x0b, 5 ; 11
  7e:   07 c0           rjmp    .+14        ; 0x8e <_Z10print_charc+0x12>
  80:   e4 ec           ldi r30, 0xC4   ; 196
  82:   f9 e0           ldi r31, 0x09   ; 9
  84:   31 97           sbiw    r30, 0x01   ; 1
  86:   f1 f7           brne    .-4         ; 0x84 <_Z10print_charc+0x8>
  88:   8c b9           out 0x0c, r24   ; 12
  8a:   5e 9b           sbis    0x0b, 6 ; 11
  8c:   fe cf           rjmp    .-4         ; 0x8a <_Z10print_charc+0xe>
  8e:   08 95           ret

00000090 <main>:
  90:   1f 93           push    r17
  92:   cf 93           push    r28
  94:   df 93           push    r29
  96:   a0 9a           sbi 0x14, 0 ; 20
  98:   a1 9a           sbi 0x14, 1 ; 20
  9a:   a2 9a           sbi 0x14, 2 ; 20
  9c:   8c e0           ldi r24, 0x0C   ; 12
  9e:   89 b9           out 0x09, r24   ; 9
  a0:   88 e9           ldi r24, 0x98   ; 152
  a2:   8a b9           out 0x0a, r24   ; 10
  a4:   86 e8           ldi r24, 0x86   ; 134
  a6:   80 bd           out 0x20, r24   ; 32
  a8:   85 b7           in  r24, 0x35   ; 53
  aa:   81 60           ori r24, 0x01   ; 1
  ac:   85 bf           out 0x35, r24   ; 53
  ae:   8b b7           in  r24, 0x3b   ; 59
  b0:   80 64           ori r24, 0x40   ; 64
  b2:   8b bf           out 0x3b, r24   ; 59
  b4:   78 94           sei
  b6:   85 b3           in  r24, 0x15   ; 21
  b8:   92 e0           ldi r25, 0x02   ; 2
  ba:   89 27           eor r24, r25
  bc:   85 bb           out 0x15, r24   ; 21
  be:   11 e0           ldi r17, 0x01   ; 1
  c0:   c8 ea           ldi r28, 0xA8   ; 168
  c2:   d1 e6           ldi r29, 0x61   ; 97
  c4:   80 91 60 00     lds r24, 0x0060
  c8:   d9 df           rcall   .-78        ; 0x7c <_Z10print_charc>
  ca:   85 b3           in  r24, 0x15   ; 21
  cc:   81 27           eor r24, r17
  ce:   85 bb           out 0x15, r24   ; 21
  d0:   ce 01           movw    r24, r28
  d2:   01 97           sbiw    r24, 0x01   ; 1
  d4:   f1 f7           brne    .-4         ; 0xd2 <main+0x42>
  d6:   f6 cf           rjmp    .-20        ; 0xc4 <main+0x34>

000000d8 <__vector_11>:
  d8:   1f 92           push    r1
  da:   0f 92           push    r0
  dc:   0f b6           in  r0, 0x3f    ; 63
  de:   0f 92           push    r0
  e0:   11 24           eor r1, r1
  e2:   8f 93           push    r24
  e4:   9f 93           push    r25
  e6:   85 b3           in  r24, 0x15   ; 21
  e8:   94 e0           ldi r25, 0x04   ; 4
  ea:   89 27           eor r24, r25
  ec:   85 bb           out 0x15, r24   ; 21
  ee:   8c b1           in  r24, 0x0c   ; 12
  f0:   80 93 60 00     sts 0x0060, r24
  f4:   9f 91           pop r25
  f6:   8f 91           pop r24
  f8:   0f 90           pop r0
  fa:   0f be           out 0x3f, r0    ; 63
  fc:   0f 90           pop r0
  fe:   1f 90           pop r1
 100:   18 95           reti

00000102 <_exit>:
 102:   f8 94           cli

00000104 <__stop_program>:
 104:   ff cf           rjmp    .-2         ; 0x104 <__stop_program>

1 Ответ

0 голосов
/ 14 февраля 2020

Как видите, в сгенерированной таблице векторов:

00000000 <__vectors>:
   0:   29 c0           rjmp    .+82        ; 0x54 <__ctors_end>
   2:   00 00           nop
   4:   3a c0           rjmp    .+116       ; 0x7a <__bad_interrupt>
   6:   00 00           nop
   8:   38 c0           rjmp    .+112       ; 0x7a <__bad_interrupt>
   a:   00 00           nop
...
  2c:   55 c0           rjmp    .+170       ; 0xd8 <__vector_11>
  2e:   00 00           nop

каждый вектор прерывания использует 2 слова: одно для rjmp и одно заполнено nop.

Таким образом 12-й вектор расположен в адресах 0x002 C (или адрес слова 0x16).

В таблице в таблица 18 , сечение Векторы прерываний в ATmega8 на странице 46 вы можете видеть, что в ATmega8 для каждого вектора выделяется только одно слово (этого достаточно для инструкции rjmp, которая позволяет перейти на любой адрес в адресном пространстве 4Kwords).

Таким образом, вектор USART, RX C должен быть помещен в адрес слова 0x0B (или адрес байта 0x0016).

Другими словами, у вас неверные настройки для среда компиляции, возможно, вы выбрали неверный процессор.

Когда происходит фактическое прерывание, выполняется вектор при (байт-адрес 0x0016:

  16:   00 00           nop
  18:   30 c0           rjmp    .+96        ; 0x7a <__bad_interrupt>

, вызывающий пропуск операции nop и прыгает на __bad_interrupt метку:

0000007a <__bad_interrupt>:
  7a:   c2 cf           rjmp    .-124       ; 0x0 <__vectors>

, которая вызывает Ограм, чтобы остановить

...