Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Ещё раз о прерывании PCINT


Ещё раз о прерывании PCINT

Сообщений 1 страница 4 из 4

1

:canthearyou:
Вот бывает так, что мозги отказываются работать и всё тут. Приспичило тут сделать некое устройство, которое подсчитывает импульсы от внешних устройств.
Так как МК в основном спит, то прицепил эти устройства на прерывания PCINT1, в частности 1-й счётчик на PCINT8 (PB0), а второй на PCINT10 (PB1).
Всё хорошо срабатывает, но тупо уткнулся на распознавание фронта и спада импульсов, ведь прерывания происходят и по фронту и по спаду.
Бьюсь второй день, короче упёрся в тупик.
Вот часть кода:

Код:
$regfile = "m644Pdef.dat"                                 
$crystal = 1843200                                         
$baud = 9600                                                
$hwstack = 16                                               
$swstack = 32                                               
$framesize = 64                                            
CONFIG SUBMODE = NEW

'------------------------------------- Главный цикл ------------------------------------------------
Main:
'------------- Процедура обработки прерываний от счётчиков ------------------
   If CNT_int = 1 Then
      CNT_int = 0

      If StatusCNT1 = 1 Then
         Incr CNT1
         Call Led(1 , 1 , 50)                         'Моргнём светодиодом
      End If
      If StatusCNT2 = 1 Then
         Incr CNT2
         Call Led(2 , 1 , 50)                         'Моргнём светодиодом
      End If

      GoTo Main
   End If
'---------------------------------------------------------- Спим дальше -----------------------------------
   CONFIG POWERMODE = IDLE                                 
   GoTo Main
   End
'---------------------------------------------------------- Прерывания -------------------------------------
'Прерывание от счётчиков
CNT:
   $asm
      push R24                                              'Сохраним регист R24
      in R24,sreg                                           'Сохраним регистр SREG
      push R24                                              'Сохраним регистры R24,R25,R26
      push R25
      push R26
      push R27
  'Читаем порт B
      in R25,pinB
'Загрузим значение статусов
      lds R26,{StatusCNT1}
      lds R27,{StatusCNT2}
'Начали проверку первого входа
      andi R25,1                                            'Проверяем первый вход маской на порт 001
      cpi R25,1                                             'Если в регистре 1
      brEq  A1                                              'Идём на обработку
      sbrC R26,1                                            'Если бит в статусе =0 то пропустим следующую команду
      rjmp A2                                               'Уходим на продолжение
      LDI R26,0                                             'Загрузим в статус 0
      sts {StatusCNT1},R26
      rjmp A2                                               'Идём дальше
A1:
      cpi R26,1                                             'Проверяем что там 1
      breq A2                                               'Да, 1, уходим на проверку второго входа
      ldi R26,1                                             'Загрузим в статус 1
      sts {StatusCNT1},R26
'Начали проверку второго входа
A2:
      andi R25,4                                            'Проверяем первый вход маской на порт 100
      cpi R25,1                                             'Если в регистре 1
      brEq  A3                                              'Идём на обработку
      sbrC R27,1                                            'Если бит в статусе =0 то пропустим следующую команду
      rjmp A4                                               'Уходим на продолжение
      LDI R27,0                                             'Загрузим в статус 0
      sts {StatusCNT1},R27
      rjmp A4                                               'Идём дальше
A3:
      cpi R27,1                                             'Проверяем что там 1
      breq A4                                               'Да, 1, уходим на проверку второго входа
      ldi R27,1                                             'Загрузим в статус 1
     sts {StatusCNT2},R27
A4:
'Покажем, что было прерывание от счётчиков, установим флаг прерывания
      ldi R25 , 1
      sts {CNT_int} , R25
 'Восстановим все регистры
      pop R27
      pop R26
      pop R25
      pop R24
      out sreg , R24
      pop R24
   $end asm
Return

Короче полный абзац.

0

2

sva-don написал(а):

Всё хорошо срабатывает, но тупо уткнулся на распознавание фронта и спада импульсов, ведь прерывания происходят и по фронту и по спаду.

Можно попробовать после события прерывания сохранять состояние пина в переменной и при следующем событии прерывания сравнивать текущее состояние с сохраненным.

0

3

Или по низкому делить на 2

0

4

sva-don написал(а):

но тупо уткнулся на распознавание фронта и спада импульсов, ведь прерывания происходят и по фронту и по спаду.


dim флаг_фронт_спад as byte

.......

isr_pcint:

toggle флаг_фронт_спад

if флаг_фронт_спад > 0 then
   'фронт
else
   'спад
end if

return

+1


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Ещё раз о прерывании PCINT