Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Тема закрыта

ATmega16A-AU не работают прерывания

Пт июн 29, 2012 00:02:44

Подключил ATmega16A-AU, подключил к ней дисплей nokia 1110
Дисплей работает нормально.

Вывод 11 (прерывание INT0) - но в программе срабатывает INT1 и при этом работает нормально
Вывод 12 (прерывание INT1) - когда пожношу руку на расстоянии 1...3 см. к контроллеру, на экране появляется какая-то фигня. Причём независимо от настроек MCUC и GICR
Вывод 42 (прерывание INT2) - вобще никак не реагирует

Код:
.include "m16def.inc"
 
.def  tmp    = R16   //
.def  loop   = R17   //
.def  tmp1   = R19   //
.def  tempL  = r22
.def  tempH  = r23
 
// LCD
.equ   lcd    = PORTB
.equ   clk    = PB7  // Lcd clock
.equ   dat    = PB6  // Lcd data
.equ   cs     = PB5  // Lcd data

rjmp   Reset               ;вектора прерываний
rjmp   SUBI_INT0
rjmp   SUBI_INT1
rjmp   SUBI_INT2


Reset:
 
      ldi tmp,low(RAMEND)  ;определение начала стека
      out SPL,tmp
      ldi tmp,high(RAMEND) ;определение начала стека
      out SPH,tmp

     ldi tmp,(1<<clk)|(1<<dat)|(1<<CS)   ;|(1<<res)
     out ddrb,tmp   
     ldi tmp,(1<<clk)|(1<<dat)|(1<<CS)   ;|(1<<res)
     out portb,tmp 


// Инициализация ЖКИ модуля
   ldi tmp,0xE2 // Internal reset
   rcall lcd_cmd
//   rcall wait_20ms      // ждем
   ldi   tmp,0xEB // температурная компенсация включена
   rcall lcd_cmd
   ldi   tmp,0x2F // режим питания
   rcall lcd_cmd
   ldi   tmp,0xA1 // направление LSB -> MSB
   rcall lcd_cmd
   ldi   tmp,0xA4 // очистить все пиксели жки
   rcall lcd_cmd
   ldi   tmp,0xA6 // позитивное изображение, 0xA7 - негативное изображение
   rcall lcd_cmd
   ldi   tmp,0x95
   rcall lcd_cmd    ; устанавливаем контрастность
   ldi   tmp,0xAF // включить дисплей
   rcall lcd_cmd
    rcall clr_lcd        // Очищаем ЖКИ от случайного мусора


   // Прерывания
   ldi  R16,(0<<ISC00)|(1<<ISC01)|(0<<ISC10)|(1<<ISC11)|(1<<ISC2)
   out  MCUCR,R16
   ldi  R16,(1<<INT0)|(1<<INT1)|(1<<INT2);INT.Enable=1
   out  GICR,R16

   sei 

   // Генератор
   sbi  ddrc,PC1

  // Светодиод
   sbi  ddrd,PD0
   sbi  ddrc,PC3
   sbi  ddrc,PC4

   // Светодиод
   sbi  portc,PC3
   sbi  portc,PC4
 





//**************************************************************
// разовые действия до основного  цикла (демонстрация)
mmm1: 

  ldi   xl,0x2A     
  rcall print_char

  ldi   xl,0x2A     
  rcall print_char

  ldi   xl,0x2A     
  rcall print_char


//**************************************************************
// основной код

main:

  ldi r24,255
nop0:
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  nop
  dec r24
  brne nop0


  ldi r25,100
nopX:

  //sbi  portc,PC1
  ldi r24,20
nop1:
  dec r24
  brne nop1

  cbi  portc,PC1
  ldi r24,20
nop2:
  dec r24
  brne nop2

  dec r25
  brne nopX


rjmp main



//****************************************************************
;Начало подпрограммы обработки прерывания от INT0
                               ;SUBI INT0
SUBI_INT0:

   sbi   portd,PD0

   ldi   xl,0x30     
   rcall print_char

   reti


//****************************************************************
;Начало подпрограммы обработки прерывания от INT1
                               ;SUBI INT1
SUBI_INT1:

  //sbi   portd,PD0

  ldi   xl,0x31     
  rcall print_char

  reti


//****************************************************************
;Начало подпрограммы обработки прерывания от INT2
                               ;SUBI INT2
SUBI_INT2:

  sbi   portd,PD0

  ldi   xl,0x32     
  rcall print_char

  reti

  reti


//****************************************************************
// Send COMMAND to LCD   - код команды должен быть уже в tmp
lcd_cmd:               
   cbi    lcd,CS    // CS -> 0
   cbi    lcd,dat   //признак передачи КОМАНДЫ
   sbi    lcd,clk   // CLK -> 1
    rjmp ob
 // Send DATA to LCD
lcd_data:             
   cbi    lcd,CS    // CS -> 0
   sbi    lcd,dat   // признак передачи ДАННЫХ
   sbi    lcd,clk   // CLK -> 1
ob:
   cbi     lcd,clk  // CLK -> 0
out_byte:            // если  подавать последовательно несколько байт подряд
   ldi     loop,8   // заряжаем счётчик цикла
outs12:
   clc              // обнуляем признак переполнения
   rol     tmp      // сдвигаем влево данные
   brcc    d_zer    // если старший бит был 0, то переходим
   sbi     lcd,dat  // если старший бит был 1, то выдаем на DATA контроллера "1"
   rjmp    d_one
d_zer:
   cbi     lcd,dat  // если старший бит был 0, то выдаем на DATA контроллера "0"
d_one:
   sbi     lcd,clk  // CLK -> 1
   cbi     lcd,clk  // CLK -> 0
   dec     loop
   brne    outs12
   sbi     lcd,CS    // CS -> 1
   clc   
ret

//**************************************
// очистка экрана (без параметров)
clr_lcd:
   ldi    xl,low (864)
   ldi    xh,high(864)
clcd:
   clr    tmp
   rcall  lcd_data
   sbiw   xl,1
   brne   clcd
ret

print_char:            // Вывод на ЖКИ символа ASCII 5 х 7
// моя версия печати символа. Символ передаётся через xl
   ldi   ZH,high(Font*2); загрузка Z-указателя адресом начала
   ldi   ZL,low (Font*2) ; массива с прошивкой сегментов цифр   
   subi xl,0x20       ; печатные символы начинаются с 0x20
    ldi tmp1,6          ; учитываем, что символ занимает 6 байт (в конце пустая позиция)
   mul xl,tmp1        ; вычисляем смещение нужного символа
   add ZL, r0
   adc ZH, r1         ; загружаем регистр адреса
lp:
   lpm tmp,Z+         ; достаём байт для вывода на экран
   rcall lcd_data     ; выводим на экран
    dec tmp1
   brne lp            ; циклимся пока не выведем все 6 столбцов символа
ret


.include "char_tables.asm"

Re: ATmega16A-AU не работают прерывания

Пт июн 29, 2012 05:28:29

Как то так.
Код:
   .ORG $0
jmp   Reset               ;вектора прерываний
   .ORG $2
jmp   SUBI_INT0
   .ORG $4
jmp   SUBI_INT1
   .ORG $24
jmp   SUBI_INT2

Re: ATmega16A-AU не работают прерывания

Пт июн 29, 2012 11:23:33

Ура заработало ! Большое спасибо !
А я вчера весь день промучался, даже контроллер поменял, т.к. думал что не рабочий.

Re: ATmega16A-AU не работают прерывания

Пт июн 29, 2012 13:48:01

ну вот еще одна жертва "обучалки"
а админы категорически не хотят опубликовать мои заметки про прерывания :dont_know:

Re: ATmega16A-AU не работают прерывания

Сб июн 30, 2012 10:10:15

Если человеку проще мучиться и менять контроллеры, вместо того чтобы открыть даташит и посмотреть на таблицу векторов с адресами прерываний и примерами кода, то обучалка тут вряд ли поможет. Жертва... :))

Re: ATmega16A-AU не работают прерывания

Вс июл 01, 2012 14:38:46

Не подскажите где взять даташит на русском языке для этого микроконтроллера ?

Re: ATmega16A-AU не работают прерывания

Вс июл 01, 2012 14:57:38

P.S. Хм, что-то ссылки не отображаются нормально... Заработали, вроде. По сути своей, это сборные даташиты по всему семейству.

Микроконтроллеры AVR семейства Mega А.В.Евстифеев.

Микроконтроллеры AVR семейства Tiny. А.В.Евстифеев.

Но лучше читать оригинальные даташиты. Ничего страшного там нет, а ошибок от корявого перевода точно избежите. Ну или хотя бы читать книжки и одновременно поглядывать в даташит. Потом и книги не понадобятся. :)
Тема закрыта