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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Обработка нескольких внешних прерываний


Обработка нескольких внешних прерываний

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

1

С праздником Пасхи уважаемые форумчане. У меня возникла одна проблема, которую уже несколько дней не могу решить. Мне требуется сделать приемо-передачик UART с преобразованием скорости. Используемый МК - Attiny 24. Разрабатываемый трансивер должен принимать данные на одной скорости и транслировать на другой скорости. Через некоторое время могут прийти данные по другому каналу и их необходимо передать далее уже на другой скорости. Т.к. у этого МК нет аппаратного UART использую - программный. Пока отсутствует прием данных по любому каналу МК занят своим делом но как только данные появились необходимо заняться их приемом и обработкой. А это можно только сделать если установить обработку прерываний с разных выводов. В общем все вопросы как-бы решаются, но вот вопрос с выявлением второго прерывания не идет. Вот часть программы, в которой у меня нерешаемая проблема:

$regfile = "Attiny24.dat"
$crystal = 8000000

Dim N1 As Byte
Dim A As Byte
Dim B0 As Word
Dim B1 As Byte
....
....

Config Porta.0 = Input
Config Porta.1 = Output
Config Portb.0 = Output
Config Portb.1 = Input

Config Int0 = Falling
Config Int1 = Falling

Open "coma.1:14400,8,n,1" For Output As #2
Open "coma.0:14400,8,n,1" For Input As #1
Open "comb.0:9600,8,n,1,1" For Output As #3
Open "comb.1:9600,8,n,1,1" For Input As #4

On Int0 Re_mag
On Pcint1 Re_pult

Enable Interrupts
Enable Int0
Set Porta.0
Set Portb.1

Main:

Do
N1 = 1 + 1
.....
Loop

Re_mag:
Disable Int0
B0 = Waitkey(#1)
If B0 = 72 Then
B0 = Waitkey(#1)
B1 = Waitkey(#1)
B2 = Waitkey(#1)
....
Enable Int0

Set Porta.0
Return

Re_pult:
Disable Int0
B0 = Waitkey(#1)
If B0 = 72 Then
B0 = Waitkey(#1)
B1 = Waitkey(#1)
B2 = Waitkey(#1)
....
End If
Set Portb.1
Enable Int0

Return
End

С портом А проблем нет. Идет обработка прерываний. А вот порт Б не могу заставить. Конфигурационная строчка

Config Int1 = Falling

никак не хочет обрабатываться компилятором. Пожалуйста, у кого есть какие мысли или опыт подскажите.

Отредактировано vladh (2013-05-05 10:31:38)

0

2

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

А откуда взялся Int1 в Attiny24?
Если использовать PCINTх, то нужно сначала его включить - Enable Pcintх, а затем прочитать даташит: PCINT0 сработает при изменениях на 0...7, PCINT1 - на 8...11. Чтобы выбрать, какой именно вывод исследовать, нужно задать маску, например: Pcmsk0 = &B00001000

А лучше взять нормальный мк. Будет очень удивительно, если в 2к все это влезет.


Уважаемый "Mrshilov", огромное спасибо за участие.
По первому вопросу. Int1 - остаток от моих бесплодных поисков. Т.е. проба наугад.
По второму вопросу. Из моих чтений файла помощи и исследований примеров вначале необходимо сконфигурировать контакт на тип прерываний. Но команда:
Config PCINT1 = Falling
не проходит, даже если вместо 1 поставить любую из действительных цифр для данного МК. А работу с маской и с Enable Pcintх я не пробовал. Сейчас поэкспериментирую и отпишусь.
И третий вопрос-предложение. Да объем памяти маловат. Но плата уже разложена под данный корпус, а поэтому можно будет использовать Attiny 44(84). Так что сам камень не ограничение. Ограничение корпус.

0

3

На сколько я помню, если прерывание не "INTx", а по пинам/выводам, то настраивается и срабатывает оно на весь порт, т.е. если сигнал поступает с любого входа, то срабатывает общее прерывание (на весь порт), далее нужно определять вручную, что конкретно побудило сработать прерывание (какой из входов или несколько).
В доке написано:

The External Interrupts are triggered by the INT0 pin or any of the PCINT11:0 pins. Observe
that, if enabled, the interrupts will trigger even if the INT0 or PCINT11:0 pins are configured as
outputs. This feature provides a way of generating a software interrupt. Pin change 0 interrupts
PCI0 will trigger if any enabled PCINT7:0 pin toggles. Pin change 1 interrupts PCI1 will trigger if
any enabled PCINT11:8 pin toggles. The PCMSK0 and PCMSK1 Registers control which pins
contribute to the pin change interrupts. Pin change interrupts on PCINT11:0 are detected asynchronously.
This implies that these interrupts can be used for waking the part also from sleep
modes other than Idle mode.

0

4

В моем переводе этот абзац читается так:
"Внешние прерывания вызываются с вывода INT0 или любого другого из выводов PCINT11: 0. Заметим, что, если он включено, прерывание то оно произойдет даже если выводы INT0 или PCINT11: 0 настроены как выходы. Эта функция предоставляет возможность генерации программного прерывания. Прерывание PCI0, если меняется любая из разрешенных ножек PCINT7..0, PCI1 – если меняется любая из разрешенных ножек PCINT11:8. Регистры PCMSK0 и PCMSK1, контролируют изменения на каких контактах способно совершать прерывания".
Здесь, с одной стороны, можно прочитать что INT0 это 0 вывод порта А, а с другой стороны, это общее указание на тип внешнего прерывания. И что такое PCI0 и PCI1?

0

5

Mrshilov, большое спасибо за участие. Но вот все таки "для тех кто на бронепоезде" расшифруйте пожалуйста фразу: "Внешние прерывания вызываются с вывода INT0 или любого другого из выводов PCINT11: 0". INT0 что это , вывод и разряд регистра маски прерываний или только разряд?
Тоже касается и PCI0 и PCI1. В разделе 9.2.3 описания сказано, что это вектора прерываний портов А и Б этого МК (это я так понял). Но в разделе 9.1 приведена таблица векторов прерываний, и этих векторов в таблице нет. В том месте где о них сообщается, идет описание разрядов PCIE1 и PCIE0 регистра маски прерываний. Вот мне и непонятно, что это все таки?
И еще одна непонятка. Получается команда
Config Int0 = Low Level
указывает компилятору, что обрабатывать все внешние прерывания надо по переходу в 0 на выводах выбранных маской?

Отредактировано vladh (2013-05-06 10:20:54)

0

6

Код:
Config Int0 = Low Level

из хелпа баскома:

LOW LEVEL to generate an interrupt while the pin is held low. Holding the pin low will generate an interrupt over and over again.
FALLING to generate an interrupt on the falling edge.
RISING to generate an interrupt on the rising edge.
CHANGE to generate an interrupt on the change of the edge. Not all microprocessors support CHANGE.


на счет прерываний по ножкам, взято через поиск инета:

Код:
Enable Interrupts        'enable global ints
Enable Pcint0              'we enable pcint0 as this has pcint0-pcint7
On Pcint0 Isr_pcint0    'we jump to this label when one of the pins is changed
Pcmsk0 = &B00001111      'enable pcint0-pcint3  (portb.0-portb.3)
'With pcmsk you individual select which pins must react on a logic level
'When you write a 1, the change in logic level will be detected.

сам не пробовал такое проделывать с тинькой (не было надобности), но описанную выше/ранее технологию опробовал с ХМегой и оно работает, что там со всем остальными мегами - пробуйте и всем тут расскажите

0

7

1 средствами BASCOM задача реализуется, если ГАРАНТИРОВАНО, что не поступит новое сообщения до завершения передачи предыдущего.
2 если наложение возможно, то структура программы должна быть иной:
- все пишется на ассемблере;
- прерывания не используются вообще. Вся программа - это главный цикл с ветвлениями. Все оперативные переменные в регистровом файле (указатели, программные счетчики, флаги). В ОЗУ только FIFO-буфер;
- запускается два таймера на удвоенной частоте приема и передачи (на период 52 и 35 мкс);
- по флагам таймеров производить считывание (анализ) приемных портов и изменения выходных.
3 На тактовой 8 МГц запросто удастся обрабатывать до 4-х каналов.
4 рекомендую потренировать мозги на ассемблере. Если не хочешь или сможешь, то  без вариантов делай
на ATMega162 или ATMegaxx4p

0

8

Для dmm. Огромное спасибо за участие и за советы.
Нет, у меня работа двух источников смещена во времени. Передача одного источника осуществляется кадрами по 9 байт, а другого, через ~75 мс, по 5 байт. Поэтому наложений невозможно.
Менять МК уже поздно. Ну может быть только в крайнем случае. Война, например, или неурожай  :crazyfun:
Спасибо за совет тренировать мозги ассемблером. Но мне, в мои 61 год уже этим заниматься "в лом". Слишком много времени будет потрачено впустую. Мне и Бейсика хватает для тренировки.

0

9

Всех с Днем Победы!
Простите за долгое молчание - хондра. Правда еще занимался исследованиями, правда в Протеусе. Понимаю, что не достаточно убедительный аргумент, но это хоть что то. Завтра надеюсь отчитаться о проделанной работе.
Уважаемы Mrshilov, мне непонятна Ваша ссылка на таблицу. Откуда здесь следует, что вектора с адресами 0х0002 т0х0003 это и есть PCI0 и  PCI1?

Отредактировано vladh (2013-05-10 06:14:42)

0

10

Сейчас наконец закончил свои эксперименты и перевод описания контроллера(раздел внешние прерывания). Так вот для того чтобы выбрать контакты МК работу с которыми необходимо осуществлять с помощью прерываний надо использовать, как об этом писал Mrshilov, регистры масок Pcmsk0 и Pcmsk1. Один регистр касается порта А, а другой порта Б. Где нужно установкой в 1 соответствующего разряда указать на вывод порта, который будет задействован в прерываниях. Также необходимо включить соответствующий вектор обработки прерываний Enable Pcint0, и\или Enable Pcint1 для указания какие порты МК будут обслуживаться прерываниями. И естественно необходимо включить общее прерывание командой Enable Interrupts.
Отдельно необходимо сказать о выводе INT0, который одновременно является выводом PCINT10. Вначале я его не увидел и меня при переводе сбивала с толку запись изменение на выводе INT0. И только сегодня я его обнаружил. Если все выводы могут участвовать в прерываниях, в том числе и PCINT10, но прерывания по этим выводам могут осуществляться только по изменению логического состояния выводов(переход в 0). Вывод же INT0 вы можете настроить так, чтобы прерывание осуществлялось либо по фронту, либо по спаду, либо по переходу в низкое логическое состояние.
Вот так. Спасибо всем кто помог мне разобраться. Я бы хотел прикрепить свой перевод, но что-то не могу разобраться как это сделать?

Отредактировано vladh (2013-05-10 14:12:21)

0

11

Можно выложить на любой файлообменник, а сюда ссылку.

0

12

vladh, в предыдущем моём посте я как раз об этом и написал (примером кода). :D

0

13

Да, RDW, писали. Но писали но по аглицки. На этом языке и файл описания, В этом и сложность. Надо было заниматься переводом и параллельно провести эксперименты. Вам бы лучше подсказывать на нашем - русском. Но и эта Ваша подсказка также помогла найти решение. Спасибо еще раз.

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Обработка нескольких внешних прерываний