|
|
  |
Много вопросов накопилось... Сильно не глумитесь, ATMega16 & etc |
|
|
|
Dec 1 2006, 12:37
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(defunct @ Dec 1 2006, 01:35)  Цитата(SasaVitebsk @ Nov 30 2006, 16:38)  фразу "Т.е. получится, такая же цепочка из допустимых прерываний"? И что Вас пугает? Кстати двух уровней достаточно для 99% случаев. Это же не IBM.
С тем же успехом можно заявить - одного уровня достаточно для 99% случаев. Вот и появляется вопрос: зачем ломать, естественным образом полученный, простой механизм синхронизации? Ведь, добавляя второй уровень, добвляется также и ряд проблем связанных с синхронизацией данных. этот вопрос, чуть выше Вы назвали: Цитата это непереводимая игра слов. Возможно, отвечая другому, я подумал бы что у Вас мало опыта. Но анализируя другие Ваши топики, понимаю что это не так. Из этого я делаю такой вывод - или область Ваших работ абсолютно не перекрывается с моей (иными словами Вам действительно не требуется то, что мне необходимо ежедневно) либо Вы выработали какой-то свой стиль и подход мне неведомый. 1) Непереводимая игра слов я ответил потому, что она там была. Поясните мне что значит фраза "запутаться" или "нарушить баланс стэка" и какие у Вас проблемы "связанные с синхронизацией данных"? Ещё раз Вам повторяю. Я с этим работаю постоянно. Никаких проблем нет. По крайней мере у меня. 2) На счёт "второго уровня", давайте банально обратимся к оборудованию. Если бы это было не нужно, то этого нигде или почти негде небылобы. Но это есть аппаратно в x51 (2 уровня) в ARM (8) в других просто не интересовался. Приведу простой и по моему доступный пример, - приведите своё решение. У меня идёт сигнал со станции 32 кГц(31.25мкс) (АТС С32) где "0" импульс длительностью 2мкс, "1" - длительностью 4мкс. Ч/з 2мкс от среза мне необходимо выдать ответный импульс длительностью 2мкс. Есть прерывание от таймера и USART. Частота 7.3728. Всё это на уровне ощущений, как и везде в программировании. Я лишнее никогда не добавляю. Я сразу чуствую что можно, а что лишнее. И если получается как-то не так, то чуствую какой-то дискомфорт. Я понимаю что скорее всего уважаемый defunct чувствует что-то вроде этого. То есть ему просто не нравится данное решение. Кажется ему некрасивым. Но это не так! Надо просто попробовать. Там всё Ok. И проблем не больше чем везде. Кстати всё прекрасно работает и из под Си. Это видно из моего примера.
|
|
|
|
|
Dec 1 2006, 17:26
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(Screw @ Nov 30 2006, 17:34)  Т.е. из обработчика прерывания вызвать подпрограмму обработки? А МК не будет думать, что этот код относится к обработчику (ну и загнул  ? Можно, но увеличится время прерывания. Так делают пацаны  , когда в одном прерывании много обработчиков событий, а в проекте много файлов. Например, я вот так: Код #pragma vector=TIMERB0_VECTOR __interrupt void TimerB_modul0() { KbdService(); ValveService(); BackgroundService(); PumpsService(); SendByteFromBuffer0(); ChemCounterSimulation(); SensorService(); } (был реальный открытый проект, но на MSP, не обессудьте  ) То есть Вам и обработку клавиш можно, как и я, включить в одно прерывание с чем-нибудь. После включения тиристоров до пятницы (следующего прерывания) контроллер абсолютно свободен. 2. По поводу лазанья глубоко и проектика. Пока кажется, что наоборот, Вы плаваете по поверхности Успехов
--------------------
Уходя, оставьте свет...
|
|
|
|
|
Dec 1 2006, 17:28
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Цитата(Screw @ Nov 30 2006, 17:49)  Вообще что-то сильно я вглубь полез.... Есть у меня такое качество. По сути проект будет делать следующее: 1) есть 2 равноприоритетных прерывания высшего уровня INT0 и INT1. Перехлест их невозможен, происходят они с частотой 50 Гц каждое (нули синусоиды ловлю). Так же в этом прерывании происходит открытие тиристоров в зависимости от алгоритма и данных с клавиатуры. 2) Есть прерывание от таймера счетчика для опроса клавиатуры. (А надо ли прерывание.... Но как подругому сделать клавиатуру доступной все время - пока непонятно) 3) В основной программе обработка данных с клавиатуры, вывод на LCD.
Вот такой вот проектик. Если у кого есть какие мысли - поделитесь, буду благодарен. Я так понял симисторами регулируете движок,делал я такое когда у меня контроллер в стиралке здох. 1 По прерываниям выставляете и запускаете таймер ,он и будет управлять симистором,и выходите. 2 С таким же успехом можно и в основной программе опрашивать клаву. ЗЫ Зачем такие глобальные проблемы решать ,приоритетности,скоростя,синхронизации,для данной задачи у контроллера просто навалом времени. Насчет стабилитрона на замер сетевой фазы,ставте 100кОм и стабилитрон 5.1в ,будет вам и 0 и 1.
|
|
|
|
|
Dec 2 2006, 02:03
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(SasaVitebsk @ Dec 1 2006, 12:37)  1) Непереводимая игра слов я ответил потому, что она там была. Поясните мне что значит фраза "запутаться" или "нарушить баланс стэка" и какие у Вас проблемы "связанные с синхронизацией данных"? как минимум две очевидных проблемы: 1. Чтение частично обновленных данных. 2. повторный вход в текущий обработчик прерывания, как следствие - переполнение стека. Цитата Ещё раз Вам повторяю. Я с этим работаю постоянно. Никаких проблем нет. По крайней мере у меня. Спору нет, охотно Вам верю, но применять сложное решение там, где есть более простое - не рационально. Цитата 2) На счёт "второго уровня", давайте банально обратимся к оборудованию. Если бы это было не нужно, то этого нигде или почти негде небылобы. Но это есть аппаратно в x51 (2 уровня) в ARM (8) в других просто не интересовался. Аргумент не очень убедительный, т.к. в противовес этому примеру можно поставить AVR'ы, PIC'и где уровней всего один.. Цитата Приведу простой и по моему доступный пример, - приведите своё решение. У меня идёт сигнал со станции 32 кГц(31.25мкс) (АТС С32) где "0" импульс длительностью 2мкс, "1" - длительностью 4мкс. Ч/з 2мкс от среза мне необходимо выдать ответный импульс длительностью 2мкс. Есть прерывание от таймера и USART. Частота 7.3728. Через 2us от среза это не строго? Иначе ваша задача нерешаема и с двумя уровнями вложенности, так как просто переход на обработчик прерывания занимает около 11 тактов, что с приведенным кварцем займет примерно ~1.5 us. С учетом вложенности прерываний - "люфт" будет приблизительно равен ~3 us. Первым делом я бы поставил кварц на 14.7456, ну а дальше смотрел бы.. Возможно пришлось бы добавлять на формирование импульсов отдельный MK или внешнюю логику. Цитата Всё это на уровне ощущений, как и везде в программировании. Я лишнее никогда не добавляю. Я сразу чуствую что можно, а что лишнее. И если получается как-то не так, то чуствую какой-то дискомфорт. Есть такое ;> Цитата Я понимаю что скорее всего уважаемый defunct чувствует что-то вроде этого. То есть ему просто не нравится данное решение. Кажется ему некрасивым. Но это не так! Надо просто попробовать. Там всё Ok. Как по мне, то там где многоуровневость действительно нужна, лучше применить упомянутые Вами x51 или ARM в которых многоуровневость поддерживается аппаратно.
|
|
|
|
|
Dec 2 2006, 23:58
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(defunct @ Dec 2 2006, 02:03)  как минимум две очевидных проблемы: 1. Чтение частично обновленных данных. 2. повторный вход в текущий обработчик прерывания, как следствие - переполнение стека. Это очевидные "не проблемы". Стек может переполнится и с одним уровнем прерываний и ошибка совместного использования данных - также. Простой пример - проверка свободного остатка кольцевого буфера - а между сравнениями младшего и старшего байта указателя вызов процедуры прерывания от UART с переходом по кольцу. (Я один раз получил - долго искал) Это не проблемы выбранного метода, - это просто недостаток опыта или знаний у программиста. Цитата Аргумент не очень убедительный, т.к. в противовес этому примеру можно поставить AVR'ы, PIC'и где уровней всего один.. Для меня убедительный. Если для x51 я могу выполнить две команды setb ex1 setb px1 и получу практически то же самое что я делаю здесь софтово, и там никому в голову не придёт меня "осудить" за "неправильное" использование оборудования, то непонимаю как это мне можно пришить здесь. Цитата Как по мне, то там где многоуровневость действительно нужна, лучше применить упомянутые Вами x51 или ARM в которых многоуровневость поддерживается аппаратно. Аппаратно - это громко сказано. Чего Вы боитесь? Это мне напоминает момент когда я написал свою первую прогу на x48. Вижу - ошибка, найти не могу. И тут ... о ужас ... этот процессор не делает автоматического сохранения PSW (читай SREG) процессора при входе/возврате в/из прерывания.... как дальше жить ... какой бред.... С тех пор прошло много лет. Оказывается земля не рухнула, и всё я это делаю руками. Как то привык и эмоций это у меня не вызывает. И там тоже нет никаких проблем. Я не делаю ничего крамольного. Я не обращаюсь к стеку и не модифицирую его. В x51 можно переключить банки регистров - в avr можно использовать разные регистры (это при написании на asm). Для Си вообще ничего делать не надо. Компилятор обо всём сам позаботится. Да - нельзя использовать совместные ресурсы в прерывании. Так я этого и так стараюсь не делать во избежание. Я стараюсь чтобы каждый процесс был завершён. Выходные данные одного процесса - входные для другого. А перепинговывание - это просто доп сложности. В завершение скажу, что допускаю возможность повторного входа в прерывание (если оно грамотно написано). Ну например ситуация: идут нерегулярные прерывания от Int0 со средним временем не более одного прерывания в 200мкс. Обработка его занимает 60мкс. При этом оно может придти в конце интервала или в начале, таким образом минимальный разрыв м/у ними может составлять 10мкс. Ничего нет сложного в написании данного прерывания без применения дополнительных внешних аппаратных средств. И процедура будеть выглядеть обычно. Кстати изделие с протоколом описанным в моём топике выше выпускалось серийно с момента появления 4414 (максимальная тактовая частота 8000 поэтому о 14745600 речи не шло). К слову скажу что аналогичное изделие выпускалось в Днепропетровске. И было оно основано на PIC и тоже частота кварца была невысока. Дальнейший спор на эту тему считаю бессмысленным, так как он просто отражает "пристрастия" авторов. А свои пристрастия, по моему убеждению, каждый должен выбирать себе сам. Так что выбор за Вами.
|
|
|
|
|
Dec 3 2006, 01:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Пожалуй я тоже вставлю слова, т.к. вложенные прерывания использовал, и как решить ту задачу без них не представляю (при помощи ШИМ генерится огибающая аналогового сигнала, при периоде ШИМ 128 тактов процессора его обработчик прерывания выполняется за 105...120 тактов, а в оставшиеся такты надо за 40 периодов ШИМ подготовить данные для следующих 40 периодов без участия основной программы, т.е. в обработчике другого прерывания). Цитата(defunct @ Dec 2 2006, 01:03)  2. повторный вход в текущий обработчик прерывания, как следствие - переполнение стека. Решается довольно просто: Код void Timer1_compA_handler() { TIMSK &= ~(1<< OCIE1A); //запрещаем это прерывание
__enable_interrupts(); // разрешаем вложенные
собственно обработчик, вложенные прерывания разрешены
__disable_interrupts(); // запрещаем вложенные
TIMSK |= (1<< OCIE1A); разрешаем это прерывание } Резюме - панически бояться вложенных прерываний не нужно. Но тщательно обдумывать любое решение необходимо.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 3 2006, 02:09
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(SasaVitebsk @ Dec 2 2006, 23:58)  Аппаратно - это громко сказано. Чего Вы боитесь? Гм.. Аппаратно - это не громко, а точно сказано, т.к. имеются средства аппаратуры, которые автоматически блокируют возможность вызова прерываний того же уровня. Чтобы повторить это на AVR, Вам потребуется на входе в прерывание вручную блокировать все прерывания того же уровня, и лишь после этого устанавливать флаг I. Т.о. накладные расходы получатся весьма значительными, а выигрышь от всего этого - практически никаким. Цитата Это мне напоминает момент когда я написал свою первую прогу на x48. Вижу - ошибка, найти не могу. И тут ... о ужас ... этот процессор не делает автоматического сохранения PSW (читай SREG) процессора при входе/возврате в/из прерывания.... как дальше жить ... какой бред.... С тех пор прошло много лет. Оказывается земля не рухнула, и всё я это делаю руками. Как то привык и эмоций это у меня не вызывает. И не надо его сохранять т.к. в x48 одноуровневый КП. Вот интересно, что бы Вы сказали если бы у x51-го PSW не сохранялся.. такой проц можно было бы сразу "фтопку". Цитата И там тоже нет никаких проблем. Я не делаю ничего крамольного. Я не обращаюсь к стеку и не модифицирую его. Разрешая прерывания глобально, вне зависимости от Вас, идет работа со стеком. (вызовы других обработчиков прерываний). Цитата Для Си вообще ничего делать не надо. Компилятор обо всём сам позаботится. Ну-ну.. Компилятор ни о чем не позаботится, ему все равно какие строки переводить в код. Заботиться обо всем нужно разработчику. Цитата Да - нельзя использовать совместные ресурсы в прерывании. Так я этого и так стараюсь не делать во избежание. Я стараюсь чтобы каждый процесс был завершён. Выходные данные одного процесса - входные для другого. А перепинговывание - это просто доп сложности. Вот это и есть та самая забота - по устранению проблем связанных с синхронизацией, которую компилятор за Вас не сделает. Цитата В завершение скажу, что допускаю возможность повторного входа в прерывание (если оно грамотно написано). Ключевое слово "если"  Цитата Ну например ситуация: идут нерегулярные прерывания от Int0 со средним временем не более одного прерывания в 200мкс. Обработка его занимает 60мкс. При этом оно может придти в конце интервала или в начале, таким образом минимальный разрыв м/у ними может составлять 10мкс. Вопрос, зачем это надо? Ведь после завершения обработки первого прерывания можно спокойно обработать и второе. Цитата Кстати изделие с протоколом описанным в моём топике выше выпускалось серийно с момента появления 4414 (максимальная тактовая частота 8000 поэтому о 14745600 речи не шло). К слову скажу что аналогичное изделие выпускалось в Днепропетровске. И было оно основано на PIC и тоже частота кварца была невысока. Видимо это изделие решает не такую задачу как Вы описали. На PIC'е подозреваю ребятам тяжко пришлось поизвращаться на асме, причем без прерываний, т.к. ваша задача (в том виде в каком Вы ее поставили) на PIC с 200ns циклом @20Mhz с прерываниями нерешаема вообще.
|
|
|
|
|
Dec 3 2006, 11:56
|
Участник

Группа: Новичок
Сообщений: 38
Регистрация: 30-09-05
Пользователь №: 9 098

|
Я думаю, что стабилитрон как ограничитель работать не будет. Если в сети 220В и резистор 100к то ток будет 2 мА. Нужно смотреть характеристику стабилитрона. Минимальный ток стабилизации около 20 мА. Он не выходит на обратную ветвь характеристики и получается вместо 5В примерно 2,5В. Лучше поставить регулируемый стабилитрон TL431.
|
|
|
|
|
Dec 3 2006, 15:05
|
Участник

Группа: Новичок
Сообщений: 38
Регистрация: 30-09-05
Пользователь №: 9 098

|
Автор топика не говорит какой у него стабилитрон. У меня вот какие мысли по этому поводу. Чтобы с точностью допустим микросекунды отловить нули сетевого напряжения в двух каналах Int0 и Int1 нужно две цепочки диод резистор стабилитрон. Диоды включить противофазно и выпрямить две разных полуволны. Стабилитрон с большим диапазоном тока стабилизации, например 1 мА - 100 мА. Каждое прерывание настроить на задний фронт прямоугольного импульса. Прерывания будут срабатывать почти точно в нулях. Как рассчитать резистор? Допустим мах напряжение 310В+20%=370В Ток 100 мА - резистор 370В/0,1А=3,7кОм. Что-то мало для розетки? Не сгорит ли? Допустим 10 кОм поставим. Тогда мгновенное напряжение сетевой синусоиды, при котором еще лог.1 на входе Int будет 1 мА*10кОм=10В. Дальше стабилитрон уже не держит 5В и наступает крутой задний фронт. Я тут никак не учитывал ток через PIN процессора. TL431 имеет ток катода от 1 до 100 мА и регулируемое напряжение стабилизации от 2,5 В до 36 В и с помощью еще двух резисторов по 10 кОм может быть настроен на 5 В. Получим хорошие прямоугольники с крутыми фронтами. Какие у кого мысли по этому поводу?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|