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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Mega48. Как работать с прерываниями PCintX ?


Mega48. Как работать с прерываниями PCintX ?

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

1

Доброго дня всем

стала задача посчитать импульсы из шести источников. Частота - до 500 кгц, кол-во импульсов - изменяется (но ёмкость счетчика должна быть около 30 млн.)
Хочу сделать аппаратно самим МК, т.е., повесить на ногу Прерывание (Int) и в обработчике их суммировать

вопросы:
не потеряю я импульс, если одноврмененно придёт несколько (т.е., как будет с обработкой прерываний)
я выбрал Мега48, так как там чуть ли не все ноги могут быть как датчик внешнего прерывания - Pcint
но не пойму, как с ними работать :(

прошу пояснить на пальцах, код- поможет ))

спасибо

0

2

Для работы с прерываниями ATMega48 PCINTx кроме разрешения глобальных прерываний существуют 5 регистров.
1. PCICR - разрешает прерывания блоками. Бит0 PCIE0 разрешает прерывания с выводов PCINT23..16. Бит1 PCIE1 с выводов PCINT14..8. Бит2 PCIE2 c выводов PCINT7..0.
2. PCIFR - флаги установки прерываний. Аналогично п.1, но биты называются PCIFx. Проверяя их можно определить факт прерывания.
3. Три регистра PCMSK0 - можно выбрать конкретные пины длля прерываний в блоке PCINT7..0. PCMSK1 - для блока PCINT14..8 и PCMSK2 для блока PCINT23..16.
В векторах прерываний все это определено следующим образом:
- Вектор 4 переход на прерывание PCINT0.
- Вектор 5 переход на прерывание PCINT1.
- Вектор 6 переход на прерывание PCINT2.
В BASCOM настройку этих прерывания я не нашел, так что придется наверное делать вставку на asme.
Еще, эти прерывания происходят при ЛЮБОМ изменении на входе, поэтому определять тип фронта - это прерогатива программиста.

Отредактировано sva-don (2012-01-27 20:15:58)

0

3

'---------------------
' назначение векторов прерывания.
On Pcint0 Pci_ab Nosave                 'вектор внешнего прерывания от изменения уровней в порту C(0)
...
'НАСТРОЙКА ДЛЯ ATMEGA88,168
Pcicr = &B00000001                      'разрешить прерывание по изменению уровня линий портов PCI0...PCI7
Pcmsk0 = &B00001100                     'а конкретно PBI2 и PBI3
Sei                                     'разрешить прерывания
...
'ПРЕРЫВАНИЕ ОТ ИЗМЕНЕНИЯ/ УРОВНЕЙ В ПОРТУ
Pci_ab:
    Push R31                            'сохраним регистры
    In R31 , Sreg
    Push R31
    Push R30
    Push R29

'.... ДЕЛАЕМ, ЧТО НАДО.

    Pop R29
    Pop R30
    Pop R31
    Out Sreg , R31
    Pop R31
    Reti
$end Asm
Return

0

4

спасибо!
надеюсь, разберусь :)

0

5

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

Push R31 In R31 , Sreg    Push R31    Push R30    Push R29

А почему выбраны именно эти регистры?

0

6

Верхние регистры обладают наибольшими функциональными возможностями. Это X,Y,Z-регистры которые часто очень нужны для доступа  в память как указатель, в них работают команды SBIW, ADIW

0

7

Я не про это. А вы уверены, что при компиляции именно эти регистры будут задействованы? По моим наблюдениям в небольших п/п прерываний компилятор "любит" использовать R24, а вообще то нужно дизассемблировать программу для того, чтобы точно узнать регистры, задействованные компилятором в п/п прерывания. Сделать это можно открыв файл obj в AVR Studio.

0

8

sva-don, использую студию 5, почему она так тормозит при отладки (при загрузке obj) - это нормально или неправильно что-то делаю?

0

9

Я ее попробовал и... снес к чертям, хотя машина у меня вполне приличная. Для этого монстра нужен не РС, а Cray o.O
Использую студию 4.19, да и то в качестве программатора или дизассемблера. Пишу в ней редко.
Для программирования либо BASCOM-80%, либо AVR GCC-20%. Его блокнота вполне хватает. Отладка чаще всего в железе, через СОМ.
А 5-ка Бета или уже релиз? Сегодня смотрел на сайте Atmel, там вроде бы уже релиз выложили. Правда полный инсталятор 609 метров! o.O и Бета не апгрейдится, только полное удаление и установка.
Может получше будет работать.

Отредактировано sva-don (2012-01-29 11:53:30)

0

10

У меня релизнутая версия.  :disappointed:
Почему пользуюсь именно ей: мне понравилось как просто организован программатор (интерфейс), после пробовал вернуться к 4-е - не понравилось. Возможно из-за диза (неожидано понадобилось) нужно ещё раз попробовать 4-ку, а так отладку делаю тоже сторонними аппаратными средствами.

0

11

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

как просто организован программатор

Да, программатор, инсталлятор которого весит 609 метров - это круто!  :crazyfun:
Мне кажется, что в Atmel кто то чуток перестарался. Мне это напомнило историю с Vista. Но там Билл хоть вовремя спохватился, будем надеятся, что и нам повезет. :huh:
Кстати, в инете нужно поискать дизассемблеры. Должны там они быть. Правда студия еще и исходные строки туда вставляет чаще всего  не по месту, но очень помогает.

Отредактировано sva-don (2012-01-29 15:27:10)

0

12

1 Сохранять нужно, те регистры, которые ты используешь. И прерывание писать на ассемблере. Иначе толку от программы в прерывании никакого (по опросу даже быстрее).
2 Если прерывание написано на Basic, то придется сохранять все! А отслеживать в отладчике - ерунда.

0

13

Парни, тут другая хрень может получиться (сейчас только вот дошло до меня):
я имею ДЛЯ ПРИМЕРА три входа
цепляю их на IntX
в прерывании увеличиваю переменную типа DWord (4 байта)
Может так получиться, что я начну отображать первую переменную, а в этот момент переменая и она портится
Пример: я получил 111 222 133 199 и начинаю отображать. А в этот момент пришло прерывание и стал последний байт 255+1 и потянул 133 до 134
т.е., процедура передачи должна быть быстрее(?) чем сама функция счета??

блин, так рука и тянется сделать по 4 сдвиговых регистра с параллельным выходом для каждого из входов и потом из вычитывать МК :)

0

14

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

Если прерывание написано на Basic, то придется сохранять все! А отслеживать в отладчике - ерунда.

DMM ты не прав. Вот реальный кусок кода с реального железа.

Код:
'-------------------------------- Прерывания --------------------------------
'Прерывание ГВС
Gvs:
  push r24
  Gvs_int = 1
  pop r24
Return
'Прерывание ХВС
Hvs:
  push r24
  Hvs_int = 1
  pop r24
Return
'Прерывание окончания цикла ГВС
Endgvs:
  push r24
  Endgvs_int = 1
  pop r24
Return
'Прерывание окончания цикла ХВС
Endhvs:
  push r24
  Endhvs_int = 1
  pop r24
Return
'Прерывание при отключении питания
Energ:
  push r24
  Energy_int = 1
  pop r24
Return
'Прерывание от клавиатуры
Keyboard:
  push r24
  Kbd_int = 1
  pop r24
Return
'Прерывание от часов
Clock:
 push r24
 Clock_int = 1
 pop r24
Return
'Контроль таймера выкл. LCD
Controllcd:
 push r24
 Lcd_int = 1
 pop r24
Return

R24 отслежено именно в отладчике. И было бы глупо и весьма расточительно сохранять все регистры в каждом из прерываний.
Кстати, в этом кусочке видно, что в п/п прерывания практически ничего не делается. Только устанавливается флаг срабатывания. Весь цикл обработки выполняется в основной программе.

Отредактировано sva-don (2012-01-30 10:11:02)

0

15

Вообще, когда запускается прерывание, то оно обязано полностью отрабатывать, т.е. его нужно запрещать, но понятное дело, что потеря такта прерывания непозволительная роскошь при длительном его выполнении... Скажем в кнопках и обмене с RTS и CTS - можно, но на таймере и счетчике - нет.  %-)

0

16

ну как ? у автора получилось реализовать, то что он хотел?

я например пишу на CVAVR под ATmega88 симулирую в протеусе. и как только я в программе записываю в регистр PCICR что либо программа - вылетает.
Подскажите пожалуйста, что может быть не так? Нужно как-то по-особенному записывать в этот регистр?? (глобально например запрещать все прерывания или еще что?)

0

17

я отказался это этого решения, сделал по-иному

0

18

не было похожей проблемы с регистром PCICR ?  все нормально переключалось?

как сделали в итоге?

0

19

Железячные счетчики надежнее

0

20

а как в меге48 сбрасывается флаг прерываний INT0 и INT1 ? Попробовал  записать в регистр GIFR  не получилось, видимо нужно писать в какой-то другой регистр, но вот в какой?

а вроде нашел, регистр EIFR (External interrupt flag register), оно?

Отредактировано Viktor (2012-04-20 18:32:51)

0

21

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

...
а вроде нашел, регистр EIFR (External interrupt flag register), оно?
...

Оно? А то он у меня не работает  :confused:
Вот, 246я страница - http://kazus.ru/nuke/users_files/19082009/8967238.pdf

0

22

Век живи, век учись!!!
Как думаете, возможно обработать 10 000 прерываний 3000 раз в минуту?

0

23

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

10 000 прерываний 3000 раз в минуту?

10000 * 3000 / 60 = 500000

500 тысяч прерываний в секунду проблематично обработать на AVR. Даже если получится, то МК придется разогнать, обработчик писать на асме и времени на обработку будет очень мало.
Для чего это нужно? Возможно есть аппаратное решение.

0

24

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

...
Для чего это нужно? Возможно есть аппаратное решение.

Нужно обработать данные с энкодера двигателя.
Всего 2500 делений, это по разным фронтам 10 000 прерываний. Двигатель 3000 оборотов в минуту. Я его-то наколхозил, но не могу никак 10 000 позиций принять, только 2500.

Труды моего гения  :blush:

Код:
$regfile = "m328pdef.dat"
$crystal = 16000000
$hwstack = 40
$swstack = 16
$framesize = 32
$baud = 57600

On Pcint0 Encod1


Config Int0 = Rising
Config Int1 = Rising

On Int0 Encod1
On Int1 Encod1

Config Pind.2 = Input                                    
Config Pind.3 = Input                                   

I1 Alias Pind.2
I2 Alias Pind.3


Dim Value As Word
Dim D1 As Bit
Dim D2 As Bit

Print "OK"

Enable Int1
Enable Int0
Enable Interrupts


Do

 If D1 <> I1 Or D2 <> I2 Then Print Value

D1 = I1
D2 = I2

Loop


Encod1:
Eifr.0 = 0
Eifr.1 = 0

If I1 = I2 Then
   If I1 = D1 Then Incr Value
   If I2 = D2 Then Decr Value

End If

D1 = I1
D2 = I2
Return

0

25

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

Нужно обработать данные с энкодера двигателя.

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

Судя по этой статье, таймеры xmega также поддерживают энкодеры.

0

26

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

.... работы таймера это считывание данных с инкрементальных (квадратурных) энкодеров.......

Странно, а зачем таймеры?
Может я чего путаю, голова кипит.
Микроконтроллер делает 16 000 000 операций в секунду. Двигатель вращается 3000 оборотов в минуту. За 1 оборот получаем 10 000 прерываний. 3000 оборотов/60сек=50 оборотов в сек., 50 оборотов/сек * 10 000 = 500 000 прерываний.
16 000 000 операций/ 500 000 это по 32 такта на обработку информации.
Надо просто как-то успеть обработать информацию и запихнуть в какой нибудь аппаратный регистр, который можно считать из вне.  :glasses:
:'( Боюсь я другие контроллеры.

0

27

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

а зачем таймеры

Таймер используется как счетчик щелчков энкодера, т. е. аппаратно с ним работает. Не нужно обрабатывать прерывания от входа INT. Необходимо периодически считывать содержимое счетчика таймера чтобы узнать сколько раз энкодер щелкнул после предыдущего считывания счетчика. Т. е. считайте что в данном случае таймер это аппаратный модуль для энкодера.

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

6 000 000 операций/ 500 000 это по 32 такта на обработку информации.

Если писать на асме то может и получится, но МК будет почти все время находится в прерываниях и ни на что другое у него времени не останется. Вариант с таймером хорош тем что пока таймер считает щелчки энкодера, процессор может выполнять какой-то код, т. е. процессор МК почти не будет участвовать в работе с энкодером.

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

Боюсь я другие контроллеры.

А зря. Они не кусаются. :D В любом случае попробовать можно, ведь даже если не получится, ну и ладно... :)
Ладно STM32, которые сильно отличаются от AVR, но xmega это же AVR и более того, поддерживается баскомом. :)  Правда для них с программаторами/отладчиками все не так хорошо как для STM32 для которых программатор/отладчик стоит около 130 рублей. Да и в целом xmega в несколько раз дороже STM...

0

28

В теории, можно взять ATTINY85, которая весьма неплохо гонится, но после разгона начинаются проблемы с записями в EEPROM, если не нужно его использовать, то можно идти дальше.
Дальше, данные передавать на такой скорости по UART...ммм...чот мне думается, что могут возникнуть проблемы стабильности, надо пробовать. В идеале использовать SPI (можно переходник найти SPI to USB)...
Ещё далее, зачем делать прерывание на такие высокие обороты, если проще сделать: прерывание в раз Х времени, за это время просто считать импульсы на входе (это быстро). Тут главная проблема будет: в момент отправки данных, могут быть пропуски. Тут либо надо брать МК с аппаратным UART или на хМеге....впрочем, при таком алгоритме, мне кажется уже высокая производительность не понадобится.

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Mega48. Как работать с прерываниями PCintX ?