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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Прерывания ATMEGA88


Прерывания ATMEGA88

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

1

Здравствуйте, есть проект, работает по прерываниям PCINT, проблема в том, что по отдельности каждое из прерываний работает, если закомментировать другие действия, но если попытаться раскомментировать, то работает одно из них,остальные не действуют, как будто прерываний не происходит:

Код:
$regfile = "m88def.dat"
$crystal = 8000000



ddrb = &B01111111
portb = &B01111111
Config Pind.0 = Input
Config Pind.4 = Input
Config Pind.7 = Input
Config Pinb.7 = Input


'Enable Pcint0
PCICR.PCIE0=1
Pcmsk0 = &B10000000
On Pcint0 isr2 nosave
'Enable Pcint2
PCICR.PCIE2=1
Pcmsk2 = &B10010001
On Pcint2 isr2 nosave
Enable Interrupts


do

loop
end


'isr0:
   if  Pinb.7  = 1 then portb = &B00101000 else  portb = &B01111111
'   PCIFR.PCIF0=1
'return


isr2:  ' действия при прерывании
   if  Pind.4 = 0 then portb = &B00010000 else  portb = &B01111111
   if  Pind.7  = 0 then portb = &B01111100 else  portb = &B01111111
   if  Pind.0  = 1 then portb = &B00001010 else  portb = &B01111111
   if  Pinb.7  = 1 then portb = &B00101000 else  portb = &B01111111


'   PCIFR.PCIF2=1
return 

По поиску в других темах ,решения не нашел

0

2

nosave подразумевает что регистры будут сохранены в прерывании, но этого нет в коде.

0

3

В общем поковырял примеры, нашел ,вроде работает, но портянка кода большая и ассемблерные вставки, может кому понадобится

Код:
$regfile = "m88def.dat"
$crystal = 8000000
$baud = 9600

Const Const_used_pinb = &B_1000_0000
Const Const_used_pinc = &B_0011_1000
Const Const_used_pind = &B_1001_0001
Dim mask_pcint_0 As Byte
Dim mask_pcint_1 As Byte
Dim mask_pcint_2 As Byte
Dim status_pcint_0 As Byte
Dim status_pcint_1 As Byte
Dim status_pcint_2 As Byte       ' Ïåðåìåííàÿ äëÿ õðàíåíèÿ íàæàòîé êíîïêè
!ldi R16 , Const_used_pinb       ' ïîëó÷àåì ìàñêó, èíâåðòèðîâàíèåì èñïîëüçóåìûõ ïèíîâ
!com R16
!sts {mask_pcint_0} , R16

!ldi R16 , Const_used_pinc       ' ïîëó÷àåì ìàñêó, èíâåðòèðîâàíèåì èñïîëüçóåìûõ ïèíîâ
!com R16
!sts {mask_pcint_1} , R16

!ldi R16 , Const_used_pind       ' ïîëó÷àåì ìàñêó, èíâåðòèðîâàíèåì èñïîëüçóåìûõ ïèíîâ
!com R16
!sts {mask_pcint_2} , R16

Ddrb = mask_pcint_0       ' Êîíôèãóðèðóåì èñïîëüçóåìûå âûâîäû ÌÊ íà âõîä
Ddrc = mask_pcint_1       ' Êîíôèãóðèðóåì èñïîëüçóåìûå âûâîäû ÌÊ íà âõîä
Ddrd = mask_pcint_2       ' Êîíôèãóðèðóåì èñïîëüçóåìûå âûâîäû ÌÊ íà âõîä

Pcmsk0 = Const_used_pinb
Pcmsk1 = Const_used_pinc
Pcmsk2 = Const_used_pind       '  äàííîì ñëó÷àå âûñòàâëåíî ðàçðåøèòü ïðåðûâàíèÿ: PCINT16; PCINT18 - PCINT23

On Pcint0 isr0 nosave
On Pcint1 isr1 nosave
On Pcint2 isr2 nosave
Enable Pcint0
Enable Pcint1
Enable Pcint2


Enable Interrupts


do
   print bin(status_pcint_0);" ";status_pcint_0;
   print " ";bin(status_pcint_1);" ";status_pcint_1;
   print " ";bin(status_pcint_2);" ";status_pcint_2
   waitms 100
loop
end


isr0:
   !Push R30       ' Ñîõðàíÿåì èñïîëüçóåìûå â ïðåðûâàíèè ðåãèñòðû
   !In R30 , Sreg       ' Ò.ê., èñïîëüçóþòñÿ ëîãè÷åñêèå îïåðàöèè, îáÿçàòåëüíî ñîõðàíÿåì SREG
   !Push R30       ' Ñîõðàíÿåì SREG
   !push R31       ' Ñîõðàíÿåì èñïîëüçóåìûå â ïðåðûâàíèè ðåãèñòðû

   !in R30 , Pinb       ' ×èòàåì ïîðò

   !lds R31 , {mask_pcint_0}       ' Ñ÷èòûâàåì ìàñêó äëÿ îáðåçàíèÿ íåíóæíûõ áèò
   !OR R30 , R31       ' Îáðåçàåì ïî ìàñêå èñïîëüçóåìûõ âûâîäîâ ÌÊ

   !andi R30 , Const_used_pinb
'    !com R30       ' Ïîáèòíàÿ èíâåðñèÿ, ìîæåò êîãäà è ïðèãîäèòñÿ

   !sts {status_pcint_0} , R30       ' Çàáèðàåì â ïåðåìåííóþ íàæàòóþ êíîïêó

   !Pop R31       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûå ðåãèñòðû
   !Pop R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûé SREG
   !Out Sreg , R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûé SREG
   !pop R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûå ðåãèñòðû

   !reti

isr1:
   !Push R30       ' Ñîõðàíÿåì èñïîëüçóåìûå â ïðåðûâàíèè ðåãèñòðû
   !In R30 , Sreg       ' Ò.ê., èñïîëüçóþòñÿ ëîãè÷åñêèå îïåðàöèè, îáÿçàòåëüíî ñîõðàíÿåì SREG
   !Push R30       ' Ñîõðàíÿåì SREG
   !push R31       ' Ñîõðàíÿåì èñïîëüçóåìûå â ïðåðûâàíèè ðåãèñòðû

   !in R30 , Pinc       ' ×èòàåì ïîðò

   !lds R31 , {mask_pcint_1}       ' Ñ÷èòûâàåì ìàñêó äëÿ îáðåçàíèÿ íåíóæíûõ áèò
   !OR R30 , R31       ' Îáðåçàåì ïî ìàñêå èñïîëüçóåìûõ âûâîäîâ ÌÊ

   !andi R30 , Const_used_pinc
'    !com R30       ' Ïîáèòíàÿ èíâåðñèÿ, ìîæåò êîãäà è ïðèãîäèòñÿ

   !sts {status_pcint_1} , R30       ' Çàáèðàåì â ïåðåìåííóþ íàæàòóþ êíîïêó

   !Pop R31       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûå ðåãèñòðû
   !Pop R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûé SREG
   !Out Sreg , R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûé SREG
   !pop R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûå ðåãèñòðû

   !reti


return

isr2:

   !Push R30       ' Ñîõðàíÿåì èñïîëüçóåìûå â ïðåðûâàíèè ðåãèñòðû
   !In R30 , Sreg       ' Ò.ê., èñïîëüçóþòñÿ ëîãè÷åñêèå îïåðàöèè, îáÿçàòåëüíî ñîõðàíÿåì SREG
   !Push R30       ' Ñîõðàíÿåì SREG
   !push R31       ' Ñîõðàíÿåì èñïîëüçóåìûå â ïðåðûâàíèè ðåãèñòðû

   !in R30 , Pind       ' ×èòàåì ïîðò

   !lds R31 , {mask_pcint_2}       ' Ñ÷èòûâàåì ìàñêó äëÿ îáðåçàíèÿ íåíóæíûõ áèò
   !OR R30 , R31       ' Îáðåçàåì ïî ìàñêå èñïîëüçóåìûõ âûâîäîâ ÌÊ

   !andi R30 , Const_used_pind
'    !com R30       ' Ïîáèòíàÿ èíâåðñèÿ, ìîæåò êîãäà è ïðèãîäèòñÿ

   !sts {status_pcint_2} , R30       ' Çàáèðàåì â ïåðåìåííóþ íàæàòóþ êíîïêó

   !Pop R31       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûå ðåãèñòðû
   !Pop R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûé SREG
   !Out Sreg , R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûé SREG
   !pop R30       ' Âîññòàíàâëèâàåì ðàíåå ñîõðàí¸ííûå ðåãèñòðû

   !reti

return

Отредактировано stas732 (2020-01-14 17:30:33)

0

4

Как искали ? ;)
Так вот тут Прерывания INT0, INT1, PCINTx Atmega8_88_328 Александр все разложил... ;)

0

5

Да, на основе этого и пришлось реализовать, предполагал,что будет проще, штатными средствами

0

6

Салют.  Начал общаться с bascom.  Вопрос- во время wait  должны исполняться прерывания?  У меня не выполняет, пока время wait не истечет. Спасиб за помощь.

Код:


$regfile = "m16def.dat"
$hwstack = 40
$swstack = 16
$framesize = 32
$crystal = 16000000
Rem $sim

Start:
      Config Portb.0 = Output
      Portb.0 = 0                                    'у ЖКИ r/w подключен к этому пину

      Config Lcdpin = Pin , Db7 = Portc.7 , Db6 = Portc.6 , Db5 = Portc.5 , Db4 = Portc.4 ,
      Config Lcdpin = Pin , E = Portb.2 , Rs = Portb.1 ,
      Config Lcd = 16 * 4

      Config Portd.0 = Input                        'определил пины кнопок
      Config Portd.1 = Input
      Config Portd.2 = Input   
      Config Timer0 = Timer , Prescale = 1024       'готовим таймер для прерывания
      Initlcd      

      Do
      Cls
      Enable Interrupts
      Enable Timer0                                  'разрешил прерывание от таймера 0
      On Ovf0 Pressbutton                            'объявил прерывание по переполнению таймера, как  pressbutton
      Locate 1 , 1
      Lcd "неважно чё"
      Wait 5
      Loop

Pressbutton:                                          'обработка прерывания таймера 0
      Disable Interrupts
      If Pind.0 = 0 Then Goto Button1
      If Pind.1 = 0 Then Goto Button2
      If Pind.2 = 0 Then Goto Button3      
      Goto M1
Button1:
      Locate 3 , 1                                     'нажата кнопка 1
      Lcd "Нажата кнопка 1"
      Goto M1
Button2:
      Locate 3 , 1                                     'нажата кнопка 2
      Lcd "Нажата кнопка 2"
      Goto M1
Button3:
      Locate 3 , 1                                     'нажата кнопка 3
      Lcd "Нажата кнопка 3"
      Goto M1
M1:      
      Reset Timsk.0
      Return
      End

Отредактировано shunin (2020-02-04 08:31:39)

0

7

Для начала эти строки вынесите выше цикла Do...Loop, после Initlcd.
Лучше, если в указанном порядке

On Ovf0 Pressbutton
Enable Timer0
Enable Interrupts

0

8

Nord написал(а):

Для начала эти строки вынесите выше цикла Do...Loop, после Initlcd.

Нельзя. В обработке прерывания они запрещаются и сбрасывается флаг. Можно вынести лишь строку On Ovf0 Pressbutton. Дела не меняет. Да это и не волнует. Интересует, wait блокирует прерывания? У меня  получается- да.

Отредактировано shunin (2020-02-04 09:36:01)

0

9

прерывания на то и прерывания, чтобы прерывать код. Нет, не должно
Nord вам всё верно указал, сперва куда переводить указатель исполняемого кода, только затем разрешить прерывания

ps
Включение прерываний вынести ДО Do-loop!
а то вы его постоянно включаете
Алгоритм неверен

Отредактировано Александр Д. (2020-02-04 09:40:32)

+1

10

Александр Д. написал(а):

прерывания на то и прерывания, чтобы прерывать код. Нет, не должно

И я, и я, и я такого ж мнения. Тогда совершенно непонятно, почему нет прерывания в моих трех строках? bascom 2.0.5.0  установлен.

0

11

Вы пытаетесь отловить нажатия кнопок по прерыванию таймера.
Вот и нажимайте их в этот момент (если успеете) ;)

Если требуется отловить именно нажатия на кнопки, то используйте другие прерывания (INT0, INT1 например).

В данном случае таймер пригоден только для мигания диодиком... ;)

0

12

Разобрался. Я из прерывания вываливаюсь с запрещенными прерываниями в 99,9% времени в длинный wait. Разрешил прерывания в конце обработки, и заработало.
Хотел уже bascom фтопку послать :D

Всем спасибо!

0

13

Nord написал(а):

Вы пытаетесь отловить нажатия кнопок по прерыванию таймера.
Вот и нажимайте их в этот момент (если успеете) ;)

Если требуется отловить именно нажатия на кнопки, то используйте другие прерывания (INT0, INT1 например).

В данном случае таймер пригоден только для мигания диодиком... ;)

Работает всё прекрасно. Прерывания по таймерам,  опросить чего-то, старинная штука. Таймер тикает весело. 16мГц с делителем 1024. Около 60 раз/с. Успеваю попасть пальцем.
Почему не INT, плата для тренировок используется от готового изделия.

Отредактировано shunin (2020-02-04 11:07:51)

0

14

shunin написал(а):

В обработке прерывания они запрещаются

Зачем? В обработчиках они и так аппаратно запрещены.
На самая  лучшая идея выводить текст на дисплей в цикле и в прерывании.

+1

15

shunin написал(а):

Прерывания по таймерам,  опросить чего-то, старинная штука.

Таймер практичен для опроса "чего-то", имеющего самостоятельный отклик на это (датчики температуры и т.п., например) или опроса расширителей (PCF8574, например) на котором висят кнопки, для периодического вывода информации "чем-то".
А кнопки и им подобные элементы логичнее опрашивать в постоянном цикле, силами других прерываний (см.выше).

В вашем случае, когда имеются на руках остатки чего-то, не стоит забывать, что во главе этих "остатков" - МК.
Используйте его ресурсы грамотно (не в ваш адрес). ;)

0

16

Пётр написал(а):

Зачем?
На самая  лучшая идея выводить текст на дисплей в цикле и в прерывании.

Это всё понятно. Просто тренировка и разбор системы прерываний.

Пётр написал(а):

В обработке прерывания они запрещаются

Вот здесь не понял. Каким образом аппаратно? Мало того, даже при глобальном запрете, после разрешения, наступают вложенные прерывания, если не сбросить флаг в Timsk

Отредактировано shunin (2020-02-04 15:05:50)

0

17

shunin написал(а):

Разобрался. Я из прерывания вываливаюсь с запрещенными прерываниями в 99,9% времени в длинный wait. Разрешил прерывания в конце обработки, и заработало.

Увы... Это называется не "разобрался", а "подобрал костыль"... ;)
Походу, вы до конца сути понятия "прерывание" так и не поняли...

shunin написал(а):

Хотел уже bascom фтопку послать

Как говорил один мой наставник - "Не спеши выбрасывать сломаный гаечный ключ - пригодится орехи колоть" ;)

0

18

Nord написал(а):

shunin написал(а):

    Разобрался. Я из прерывания вываливаюсь с запрещенными прерываниями в 99,9% времени в длинный wait. Разрешил прерывания в конце обработки, и заработало.

Увы... Это называется не "разобрался", а "подобрал костыль"... ;)
Походу, вы до конца сути понятия "прерывание" так и не поняли...
shunin написал(а):

А по теме? Я старый тролль. Меня этим не проберешь. Не хотите общаться и помогать, я вас конкретно и не прошу.

Отредактировано shunin (2020-02-04 15:20:34)

0

19

shunin написал(а):

Вот здесь не понял. Каким образом аппаратно? Мало того, даже при глобальном запрете, после разрешения, наступают вложенные прерывания, если не сбросить флаг в Timsk

Фрагмент перевода ДШ для ATMega8:
Прерывания работают только тогда, когда в регистре состояния SREG разрешены общие прерывания (бит 7 = 1). В случае наступления прерывания этот бит автоматически сбрасывается в 0, блокируя выполнение последующих прерываний.

Строки Disable Interrupts и Enable Interrupts как раз и занимаются соответственно сбросом или установкой этого бита.

Сброс этого бита не отключает назначенные ранее прерывания (их может быть не одно), а только глобально запрещает их работу.
Можно запретить отдельные ранее включенные прерывания, Disable INT0 (например), при этом остальные разрешенные прерывания будут в работе.

0

20

shunin написал(а):

А по теме? Не хотите общаться и помогать, я вас конкретно и не прошу.

Если вы уже листали Форум, а не кинулись сразу с вопросом, то, думаю, заметили, что помогать здесь "в 9 из 10" случаях принято в указании правильного пути (в хорошем смысле ;) ), а не в правке вашего кода... ;)

Один из путей - возьмите ДШ на любой МК.
Там ВСЕ есть ! Не по-русски ?
Тоже не беда ;) В сети болтается полный перевод ДШ на ATMega128.

Так что не стОит надуваться... ;)

+1

21

Еще один вопрос остался неотвеченным:

shunin написал(а):

во время wait  должны исполняться прерывания?

Да, прерывания выполняются.
Время задержки (Wait) увеличивается на время выполнения прерывания (начало Wait - прерывание - окончание Wait).

0

22

Спасибо за активнейшее участие.)) Я лишь интересовался прерываниями в wait. Неверно логику построил. Разобрался еще в пост №12.
За конкретный ответ, особое спс Александру Д.

0

23

shunin написал(а):

Хотел уже bascom фтопку послать

Тогда в топку нужно посылать МК потому что в других средах наступили бы на те же грабли.  :dontknow:
Посмотрите Евстифеева чтобы лучше понять работу ATmega.

0

24

На какие грабли? Логическую наводную неявную ошибку? Все делают ошибки.

Пётр написал(а):

Посмотрите Евстифеева чтобы лучше понять работу ATmega.

По поводу аппаратного блокирования прерывания регистром.  Не всё маскируется однозначно. Был поражен, когда стек уехал с степь. Оказалось, спасибо товарищам в сети, натолкнулся, не все однозначно. Поэтому и сбрасываю флаги в регистре управления прерываниями таймера. Хоть аппаратно, хоть программно  запрещай прерывания, ан шиш, произойдет по флажку, когда разрешишь.
Веселый кусок силициума. Поэтому и шальная мысель появилась- а отрабатывает ли wait прерывания. бггг
Смотрел бегло конечно. Я поэтому и bascom стал тренировать, что не надо вникать глубоко в железную среду. Так бы на астме написал. Тем более она у меня с детства))

Отредактировано shunin (2020-02-04 18:50:04)

0

25

shunin написал(а):

Логическую наводную неявную ошибку?

В чем по вашему была ошибка?

shunin написал(а):

По поводу аппаратного блокирования прерывания регистром. Не всё маскируется однозначно.

Раньше работали с AVR (на важно в какой среде)?
В AVR при входе в прерывание они запрещаются аппаратно, а при выходе разрешаются ассемблерной инструкцией reti. Это нужно запомнить.
Если подпрограмма прерываний выполняется долго и вы в ней разрешаете прерывание, это приведет к вложенности прерываний. Не нужно разрешать прерывания в обработчике прерываний если не понимаете к чему это может привести.

0

26

Пётр написал(а):

В чем по вашему была ошибка?

Да уже всё понятно. Нет смысла разбирать простейший кодик.

Пётр написал(а):

Раньше работали с AVR (на важно в какой среде)?
В AVR при входе в прерывание они запрещаются аппаратно, а при выходе разрешаются ассемблерной инструкцией reti. Это нужно запомнить.
Если подпрограмма прерываний выполняется долго и вы в ней разрешаете прерывание, это приведет к вложенности прерываний. Не нужно разрешать прерывания в обработчике прерываний если не понимаете к чему это может привести.

Сам никогда AVR не программил. Давным- давно  PDP11 и intel8080))
В курсе. Насколько помню, наверное у большинства процессоров возврат из прерывания команда RET или т.п. мнемоника. Как  восстанавливается состояние всех запчастей, дело индивидуальное.
Я явно запрещал прерывания в прерывании. Не помогало. При разрешении происходило прерывание по  флагу переполнения используемого таймера и прерывания вкладывались. Особенность AVR. В общем, это совсем иное, чем я интересовался.

Отредактировано shunin (2020-02-04 18:49:22)

0

27

Это ваше решение ?

shunin написал(а):

Разрешил прерывания в конце обработки, и заработало

Вставили Enable Int на метку М1 и радуетесь ? ;)

У вас в прерывании обрабатывается одно из самых медленных устройств - LCD...
Совсем неудачное решение.
Разве, только в экспериментальных целях, не более... ;)

shunin написал(а):

Я поэтому и bascom стал тренировать, что не надо вникать глубоко в железную среду.

Что с Bascom, что с Си, а с асс-ром тем более - без знания железа делать нечего.

shunin написал(а):

Так бы на астме написал.

А в Ассемблере подходы к обработке прерываний другие ? ;)
Мне всегда казалось, что железо определяет правила работы, а ЯП лишь инструмент, действующий в рамках этих правил...

shunin написал(а):

Тем более она у меня с детства))

Она - это что ?
Ваша "плата для тренировок ... от готового изделия" ? ;)

0

28

Правильнее было бы так:
- крутимся в цикле Do...Loop и ждем появления флага
- по прерыванию таймера убежали в п/пр
- в п/пр прочитали порт с кнопками и выставили флаг
- вернулись в цикл
- в цикле, т.к. флаг появился, разгребаем прочитанное из порта, выводим на LCD, гасим флаг
- возвращаемся в начало...

0

29

Пропал куда-то shunin...
Не проникся нашей гостеприимностью... ;)
"Не по-ардуиновски" как то получилось... ;)

0

30

Если в ардуине также включать и выключать прерывания, получим тот же эффект.  :D  :dontknow:

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Прерывания ATMEGA88