Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Микроконтроллеры (MCU) и микропроцессоры (MPU) > ATtiny84 прерывание PCINT0


Автор: daemon17 10.5.2011, 18:46
Всем привет!
Помогите пожалуйста разобраться с прерыванием.
необходимо фиксировать на ножке перепад 0->1 и 1->0 и соответствующие события обрабатывать в прерывании.
Оговорюсь что при использовании прерывания EXTINT0 все работает, но уперся в то что нехватает к-ва ножек на обработку событий, по этому решил перейти на прерывание PCINT0.
Но тут началась непонятка в эмуляторе AVRStudio (v 4.18 build 700).
Дело в том, что при выставлении на Pin-е соответствующего порта уровень "1" прерывание срабатывает, 
но почему то на этом Pin-е самостоятельно изменяется урвень с "1" на "0" через 42 такта и снова отрабатывает прерывание.
Никак не пойму почему на ноге порта самостоятельно изменяется уровень. Этот уровень должен изменяться от прихода внешнего сигнала но никак не самостоятельно. (Может я чего-то не дочитал в даташите?)
вот кусок кода

Код

      .DEVICE      ATtiny84
      .nolist
      .include   "tn84def.inc"
      .list

      .def   zero      = r13   ; "0x00"
      .def   full      = r14   ; "0xFF"
      .def   one      = r15   ; "0x01
      .def   temp      = r16   ; temp
      .def   razr0      = r18   
      .def   razr1      = r19   
;--------------------------------------------------------------------
      .cseg            
      .org   0         

      rjmp   RESET         ; Reset Handler
      rjmp   PCI0         ; PCINT0 Handler


RESET:
      ldi      temp,   low(RAMEND)
      out      SPL,   temp
      ldi      temp,   high(RAMEND)
      out      SPH,   temp

      clr      zero         
      ldi      temp,   0xFF      
      mov      full,   temp      
      ldi      temp,   0x01      
      mov      one,   temp      
      sbi      DDRA,   PA3      
      cbi      PORTA,   PA3      
      cbi      DDRA,   PA6      
      sbi      PORTA,   PA6      
;      ldi      temp,   1<<ISC00   
;      out      MCUCR,   temp      
      ldi      temp,   1<<PCINT6|1<<PCINT2    
      out      PCMSK0,   temp
      ldi      temp,   1<<PCIE0   
      out      GIMSK,   temp      
      ldi      temp,   3<<CS10   
      out      TCCR1B,   temp   
      ldi      temp,   0x86<<ADPS0   
      out      ADCSRA,   temp   
      ldi      temp,   1<<ACD      
      out      ACSR,   temp      


      sbic   PINA,   PINA6      
      rjmp   PC-1
      rcall   debounce      
      out      GIFR,   full   
      sei            
      rjmp   PC         

; ----------------------------------------------------
PCI0:
      sbi      PORTA,   PA3      
      reti               

debounce:   
      in      temp,   SREG   
      ldi      razr0,   0xC5   
      ldi      razr1,   0x07   
      subi   razr0,   1      
      sbci   razr1,   0      
      brcc   PC-2         
      out      SREG,   temp   
      ret

Автор: UniBomb 12.5.2011, 14:33
daemon17, первое что бросается в глаза - неправильно написана таблица векторов прерываний. Должно быть как-то так:

Код

rjmp RESET ; Reset Handler
reti       ; неиспользуемый вектор прерывания INT0
rjmp PCI0  ; PCINT0 Handler


И по идее на все неиспользуемые прерывания надо ставить заглушки в виде reti, т.е. так:

Код

rjmp RESET ; Reset Handler
reti       ; неиспользуемый вектор прерывания INT0
rjmp PCI0  ; PCINT0 Handler
reti       ; неиспользуемый вектор прерывания Pin Change Interrupt Request 1
reti       ; неиспользуемый вектор прерывания Watchdog Time-out
reti       ; неиспользуемый вектор прерывания Timer/Counter1 Capture Event
reti       ; неиспользуемый вектор прерывания Timer/Counter1 Compare Match A
reti       ; неиспользуемый вектор прерывания Timer/Counter1 Compare Match B
reti       ; неиспользуемый вектор прерывания Timer/Counter1 Overflow
reti       ; неиспользуемый вектор прерывания Timer/Counter0 Compare Match A
reti       ; неиспользуемый вектор прерывания Timer/Counter0 Compare Match B
reti       ; неиспользуемый вектор прерывания Timer/Counter0 Overflow
reti       ; неиспользуемый вектор прерывания Analog Comparator
reti       ; неиспользуемый вектор прерывания ADC Conversion Complete
reti       ; неиспользуемый вектор прерывания EEPROM Ready
reti       ; неиспользуемый вектор прерывания USI START
reti       ; неиспользуемый вектор прерывания USI Overflow


Потому, что когда срабатывает прерывание, то счётчик команд перепрыгивает по нужному и вектору и не найдя команды возврата продолжает молотить с того места. В данном случае, покуда вектор PCINT0 Handler был не на своём месте, программа начинала выполняться сначала со всеми вытекающими - сброс и реинициализация портов.

Автор: daemon17 12.5.2011, 23:01
да так оно и есть, просто чтоб не вставлять лишнего, я чего-то решил сократить да и махнул косой  smile 
в исходниках у меня как надо написано.

Автор: UniBomb 13.5.2011, 07:58
daemon17, тогда выложи полный исходник, а то вдруг ты ещё чего "лишнего" вырезал  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)