Перейти к содержанию

Индивидуальное Запрещение/разрешение Прерываний


Рекомендуемые сообщения

Код пишу на С, компилятор AVRstudio, МК мега16. В программе нужно на время запретить внешнее прерывание int0, а по переполнению таймера 2, программа переходит в обработчик прерывания переполнения таймера. Здесь нужно очистить флаг прерывания int0 и затем разрешить прерывания int0. Т.е. это реализация антидребезга :)

Объясните, как индивидуально запрещать/разрешать прерывания. Ну, или совет, как бороться с антидребезгом :)

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Как вариант можно попробовать заносить 0x00 в регистры инициализации INT как по даташыту. А потом когда надо, заново инициализировать INT.

Изменено пользователем Krik99

Хочу AVR с тактовой частотой 100мгц.

Ну вот! Я же говорил - ноль... а ты единица... единица...

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Это изврат. Просто считывай состояние кнопок с частотой 50Гц, или меньше если это допустимо. никакого дребезга при этом не будет, кнопка будет распознана +0..20мс от её фактического нажатия, и поскольку изменения будут считываться гораздо реже импульсов дребезга, на сам дребезг прийдется лишь ОДНО считывание, результат которого не будет неопределен - он либо будет равен предыдущему состоянию, либо следующему(при переходе 0 в 1 промежуточное значение или 1 ил 0 роли не играет - просто нажатие будет зафиксировано либо раньше либо позже). Лишь кратковременное нажатие кнопки будет под вопросом(контроллер при этом может зарегестрировать только состояние приходящееся на момент дребезга а это либо 0 - тогда нажатие уйдет впустую либо 1 тогда следующее состояние будет 0 и зарегестрировано нажатие кнопки 1 раз), но раз это нажатие произошло оно всеравно должно быть зарегестрировано.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

:blink: ЛИбо я прав , либо все время ( недавно начал ) которое занимаюсь МК неправильно думал , не знаю , но добавлю и я свои 5 копеек .

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

Помойму дребезг страшен когда опрашиваются кнопки с помощю обыкных портов а если использовать прерывания то МК автоматически не даст себе больше раз прерваться .

Если надо не запрещать остальные прерывания во время обработки внешнего это можно сделать , но это не есть айс . Представьте себе что во время обработкивнешнего прерывания произойдет прерывание таймера , бедный стек :(

Народ ответьте правильно ли я думаю или нет ?

Ссылка на комментарий
Поделиться на другие сайты

Это изврат. Просто считывай состояние кнопок с частотой 50Гц, или меньше если это допустимо. никакого дребезга при этом не будет, кнопка будет распознана +0..20мс от её фактического нажатия, и поскольку изменения будут считываться гораздо реже импульсов дребезга, на сам дребезг прийдется лишь ОДНО считывание, результат которого не будет неопределен - он либо будет равен предыдущему состоянию, либо следующему(при переходе 0 в 1 промежуточное значение или 1 ил 0 роли не играет - просто нажатие будет зафиксировано либо раньше либо позже). Лишь кратковременное нажатие кнопки будет под вопросом(контроллер при этом может зарегестрировать только состояние приходящееся на момент дребезга а это либо 0 - тогда нажатие уйдет впустую либо 1 тогда следующее состояние будет 0 и зарегестрировано нажатие кнопки 1 раз), но раз это нажатие произошло оно всеравно должно быть зарегестрировано.

Все правы, и в то же время, все не правы :)

Во первых, сигнал снимается не с кнопки, а с трамблера, т.е. частота "нажатий" колебрится от 1600/сек (ХХ ДВС) до 16000/сек (8000 об. коленвала).

Из расчетов, я определил время задержки. Оно равно 20мсек. Можно, конешно сделать задержку в прерывании на это время, но есть еще 1 проблема:

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

Поэтому я решил по приходу сигнала запретить прерывание, и включить счетчик. Пока счентчик считает, мы показываем информацию на дисплей, потом очищаем флаг прерывания и тоключаем счетчик. Переходим снова в функцию индикации. :) Вот так :)

Ссылка на комментарий
Поделиться на другие сайты

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

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

:)

внчале речь шла про кнопку.
не-а :)
Возможно, будет лучше в прерывании запретить его и запустить таймер, а основная программа по признаку переполнения таймера разрешит прерывания

Вот так я и хочу! Ну, я уже в принципе разобрался - почитал ДШ:

Как я понимаю, нужно, в 6-й бит регистра GICR записать 0 для деактивации и 1 для активации прерывания инт0.

У меня есть вопрос, т.е. сомнение по поводу сдвига. Объясните, пожалуйста, а то недопонял как это правильно делается.

Вот, например, я хочу в PORTA.6 записать 1. На сколько битов нужно сдвинуть 1? На сколько я понимаю, то это нужно сделать так:

PORTA.6 |=(1<<7);

т.е. сдвигать нужно на 7 битов? Или на 6? Не пойму...

А если нужно туда вести 0, то как наложить маску?

Я читал по этой теме, но, так до конца недопонял эту тему со сдвигом и масками...

Ссылка на комментарий
Поделиться на другие сайты

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

потом, если масками - для уст.1 - делаешь операцию OR с константой у которой стоит 1 в нужном месте.

Если нужно обнулить бит - делаешь операцию AND с инверсией аналогичной маски.

Понавыучивают тут С, и не знают таких простых приемов ....

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Скажите, а разве для защиты от "дребезга" не поможет просто конденсатор и резистор ?

Вот я тут нарисовал, : ))))

post-31908-1258922700_thumb.jpg

В те несколько микросекунд, когда имеет место собственно дребезг, конденсатор заряжается/сглаживает... короче, потенциал на ноге МК возрастет до нужного значения уже после дребезга. Это не правильно ?

*******************************************

Извиняюсь, сам понял глупость: когда кнопку отожмут конденсатор будет поддерживать единицу на МК... Но как-то же можно на железе это устранить ?

Изменено пользователем Cavalryman
Ссылка на комментарий
Поделиться на другие сайты

то что он будет держать 1 то не проблема, решается резистором паралельным. Проблема в том что конденсатор будучи заряженным до порога срабатывания подводит логический вход до того состояния когда он обладает максимальной чувствительностью к переключению, даже гистерезис в этот момент не поможет. Ну и недостаток - инерционность всей схемы... пока зарядится, пока разрядится....

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Но как-то же можно на железе это устранить ?

Ну, дак вот так, собвственно и устраняют...

Просто МК не важно, будет ли лог 1 присудствовать на ноге после выхода из ф-и обработчика прерываний, или просто произойдет 2-е нажатие еще во время ф-и обрабоютчика.

На сколько я понял, то флаг (запрос) на прерывание устанавливается как только на ноге устанавливается нужный уровень напряжения (например лог1). Потом программа, как можно скорее переходит в ф-ю обработчик. Когда она туда попадает, то сразу глобально запрещаются прерывания (чтобы не скакать из 1-го прерывания в другое) и сбрасывается флаг (запрос) на это прерывание. Т.е. как только сброшен флаг, то, если опять на ноге появится напряжение, вызывающее прерывание, флаг выставится снова и при выходе из обработчика прерываний, мы опять попадем в этот же обработчик прерываний, т.к. флаг установлен. Это и есть дребезг.

Для устранения дребезга в обработчике прерывания применяют (иногда и это не совсем правильно) задержку. Т.е. попали в обработчик, сделали то, что надо, потом задержка, потом сбросили флаг этого прерывания и пошли дальше по программе.

Моя же задача стояла так, чтобы:

1. Не делать задержка в прерывании

2. Не делать глобального запрета прерываний, а запретить только это прерывание.

Это планирую сделать так: Входим в обработчик прерывания, делаем то, что нужно, запрещаем это прерывание (Заносим в бит 6 регистра GICR 0), затем активируем таймер и идем по программе. Как только таймер переполнится, вызовется другое прерывание, вызванное таймером. В нем, мы снимаем флаг прерывания, который мог установиться при дребезге, опять разрешаем это прерывание, отключаем таймер, чтобы дальше не сбивал нас с толку :)

2Alexeyslav:

ззачем сдвигать, записывай константу сразу

Ну, иногда возникает необходимость выставить 1 сразу в несколько битов :)

Писать каждый в отдельности, это как-то по-колхозному :)

Если нужно обнулить бит - делаешь операцию AND с инверсией аналогичной маски.

мм.. не совсем понял, что значит "аналогичной маски?"

Кароче мона пример реальный)))

Ссылка на комментарий
Поделиться на другие сайты

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

Тоесть, опять же, возможно "метание" воспринимаемого логического уровня из единицы в ноль и обратно ? Остается транзисторный ключ поставить :)

Дмитрий.

Для устранения дребезга в обработчике прерывания применяют (иногда и это не совсем правильно) задержку. Т.е. попали в обработчик, сделали то, что надо, потом задержка, потом сбросили флаг этого прерывания и пошли дальше по программе.

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

Изменено пользователем Cavalryman
Ссылка на комментарий
Поделиться на другие сайты

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

да

Ссылка на комментарий
Поделиться на другие сайты

Собственно, мы изначально усложнили задачу. Обычно в таких случаях проще сделать внешний подавитель дребезга - обыкновенный перезапускаемый одновибратор на NE555 - и ничего с прерываниями химичить не надо, будет четко одно прерывание на один импульс. и точка.

насчет битов... пример:

порт установлен в 11110111 надо сбросить 2 и 3 биты - делаем операцию AND с числом 11110011 получаем результат 11110011, не очень наглядно конечно но понятно -аналогично можешь поиграться с другими значениями.

еще интересна операция XOR - можно проинвертировать значение бита...

1) 00000000 XOR 00000100 = 00000100

2) 00000100 XOR 00000100 = 00000000

Изменено пользователем Alexeyslav

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо, все понял.

Еще на счет сдвига:

Например, бит 5 регистра Reg нужно установить в 1. Какая из инструкций правильная:

Reg|=(1<<5);

или

Reg|=(1<<6);

? Я думаю, что 1-я инструкция правильная. Да или нет?

Я никак не пойму это момент потому, что, во внешнем хидере (m8_128.h), содержатся определения битов регистров следующим образом:

#define REFS1 7

#define REFS0 6

#define ADLAR 5

#define MUX4 4

#define MUX3 3

#define MUX2 2

#define MUX1 1

#define MUX0 0

И, получается, что операция

ADMUX|=(1<<MUX0);

Равносильна операции:

ADMUX|=(1<<0);

? Получается сдвиг на 0 битов? Т.е. при сдвиге номерация позиций, на которые нужно сдвинуть единицу, ведется с 0 а не с 1?

Изменено пользователем Дмитрий Андреевич
Ссылка на комментарий
Поделиться на другие сайты

Для работы с регистром SREG, наверное удобней будет ассемблерная вставка:

SEx - установка флага

CLx - сброс флага

, где x - имя флага регистра SREG (C, N, Z, I, S, V, T, H)

Для примера: SEZ - установка флага нуля, а CLZ - сброс флага нуля.

Ссылка на комментарий
Поделиться на другие сайты

Моя же задача стояла так, чтобы:

1. Не делать задержка в прерывании

2. Не делать глобального запрета прерываний, а запретить только это прерывание.

Это планирую сделать так: Входим в обработчик прерывания, делаем то, что нужно, запрещаем это прерывание (Заносим в бит 6 регистра GICR 0), затем активируем таймер и идем по программе. Как только таймер переполнится, вызовется другое прерывание, вызванное таймером. В нем, мы снимаем флаг прерывания, который мог установиться при дребезге, опять разрешаем это прерывание, отключаем таймер, чтобы дальше не сбивал нас с толку :)

Иногда "жонглирование" с прерываниями (разрешение/запрещение) может привести к нежелательным результатам. Может сделать проще? А именно...

В начале обработчика прерывания (INT0) сделать проверку флага нажатия (или одноразового выпонения прерывания - как угодно) и если он поднят (поднимается при первом проходе обработчика, в конце тела) условным переходом проходить "насквозь" в конец обработчика (к RETI), ничего не делая. В мэйне, по поднятию флага, запустить таймер или организовать программный таймер/счетчик, если аппаратные все используются, по истечению времени которого сбросить флаг нажатия, что приведет к однократному срабатывания прерывания при следующем событии. Еще лучше запускать его при условии снятия уровня со входа INT0. В таком случае никаких запретов (для данной операции) вообще не потребуется, а наращивание счетчика будет происходить либо аппаратно, либо программно (один раз за один полный оборот Мэйна), что никак не повлияет на длительность общего цикла и не внесет заметной погрешности при включении/отключении таймера/счетчика.

Изменено пользователем Геннадий
Ссылка на комментарий
Поделиться на другие сайты

чета не понял про мейн. Чем в нем запускать таймер, так может из обработчика сразу его и запускать? Я так планировал делать.

пока мейн (или другие ф-и) будут выполнятся, таймер считает. Как досчитал - сбросил флаг, разрешил прерывание и все. Мне кажется, вариан наиболее простой :)

Ссылка на комментарий
Поделиться на другие сайты

При свободных таймерах простой. Но! Дребезг контактов бывает не только при нажатии, но и при отпускании кнопки (если используется вариант с кнопкой вообще), все зависит от состояния (изношенности) контактов. Поэтому я и предложил в Мэйн вставить функцию, которая проверяла состояние линии INT0 и при снятии сигнала "нажатия", только тогда запускала бы таймер, который опустит флаг нажатия. Это защитит лишний раз от сбоев программы при длительном (более периода таймера) нажатии на кнопку. Получится "как досчитал - сбросил флаг", а прерывания можно и не запрещать, если грамотно обработать флаг. Это еще проще.

Ссылка на комментарий
Поделиться на другие сайты

Что-то мне кажется, что простой буфер с диодом Шотки решит вашу проблему. А дальше просто по прерыванию от Int0 (если уж вы так хотите его использовать), обрабатываете событие On Level Change. Как по мне то такое должно работать.

Ссылка на комментарий
Поделиться на другие сайты

Буффер не решит, только уменьшит вероятность сбоя. А вот любой одновибратор с перезапуском - да. И не надо будет мучить прерывания и делать сложную программу.

Всегда нужно находить более простое решение - добавление одного внешнего элемента значительно упрощает программу.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • Cкорее всего, при 31,5 В на выходе драйвер не выдаст 300 мА.  Хотя, раз заявлено входное от 100 В, то при 230 В может что-то и получится. Но это уже за заявленными пределами работы.  Можно подключить проволочный резистор 100 Ом и померить напряжение, но лучше использовать как заявлено: в диапазоне 12-20 В.  
    • @MisterAnderson , напряжение на выходе светодиодного драйвера зависит от нагрузки, и определяется оно напряжением на светодиодах, а не самим драйвером. Светодиоды имеют характеристику близкую к стабилитрону, напряжение на них от тока зависит мало. Белые светодиоды имеют это напряжение примерно 3...3,4 В. Четыре последовательно включённых - примерно 12...14 В. На подключение таких "трёхвольтовых" белых светодиодов и расчитан ваш драйвер. Драйвер напряжением не управляет, есть только ограничение по максимальному, больше которого он выдать не может. Драйвер светодиодов стабилизирует ток. Ваш драйвер стабилизирует его на уровне 0,3 А. И выдать больше 20 В при этом не может. Измеренные вами 31,5 В на холостом ходу - это напряжение его внутреннего питания. Под нагрузкой 0,3 А напряжение на его выходе тут же "просядет", выше 20 В не поднимется. Мощность на одном трёхвольтовом 300-миллиамперном светодиоде будет (примерно, для светодиодов точность никогда особо не обеспечивают) 0,3 А * 3,3 В = 1 Вт. Трёхвольтовый белый светодиод на ток 300 мА - это и есть одноваттный светодиод. На четырёх будет 4 ватта. Следующие по напряжению в линейке белых осветительных светодиодов - шестивольтовые. У них в одном корпусе последовательно соединённые два светодиодных кристалла. Четыре таких светодиода, включённых последовательно, ваш драйвер не потянет, потому что им нужно минимум 6*4=24 В, а ваш драйвер может выдать не больше 20. Впрочем, можно бы было поставить вместо четырёх трёхвольтовых четыре шестивольтовых на 150 мА, две группы параллельно по два последовательно, но вряд ли справитесь с переделкой платы под светодиоды. Поэтому этот вариант вам и не предлагали. Проще, дешевле и с наименьшими затратами собственного времени, без переделки драйвера, платы и т.п., с которой вы точно не справитесь, поставить четыре одноваттных трёхвольтовых, на которые ваш драйвер расчитан. Тем более, что купить их - проблем нет. Именно этот оптимальнейший совет вам и дали. Всё вам правильно уже много людей много раз разными словами рассказали. Что вас ещё смущает?
    • Предусилители-корректоры на полевых транзисторах. Радио №9,   №10/2010.  А.Гурский.
    • Тоже самое в подсветках фирменных телеках даже 10 летней давности. Ток можно уменьшить на треть без потери качества легко. Потребитель должен потреблять и всё тут.
    • Естественно после 7 вольт то. Или аккум сам по себе хлам и садит в себя или ибп. Тут вариантов не много.
    • Попробуйте зарядить, а потом погонять ее  в полный цикл несколько раз. Это если акум нормальный а у ТС 100% давно не нормальный.
×
×
  • Создать...