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

Прерывания по любому фронту


DrobyshevAlex

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

Почитал несколько статей по прерываниям, но ответа не нашел :)

Суть примерно следущая. мк Attiny2313. Две кнопки на INT0 и INT1. Включаю прерывания по смене лог уровня

Цитата

0 1 Any logical change on INT1 generates an interrupt request.

MCUCR |= (1 << ISC10) | (1 << ISC00);

GIMSK |= (1 << INT1) | (1 << INT0);

Прерывание срабатывает только по одному фронту. Если я подтягиваю к +5 и кнопка подает 0, прерывание срабатывает, но когда я отпускаю кнопку не срабатывает, не меняя прошивку, я подтягиваю на 0 ногу мк, а кнопка пропускает +5 - прерывание тоже срабатывает. То есть да, по любому уровню срабатывает :) Но я бы хотел что бы я мог отследить и нажатие и отпускание кнопки.

На всякий случай пробовал сбросить ISC11 и ISC01 - результата нет.

Я пробовал сделать иначе, Я включал прерывания по нисходящему фронту, а во время прерывания менял регистр MCUCR и включал по восходящему. Не работает!

Я могу как то отследить нажатие кнопки прерыванием и отпускание?

Я конечно могу в основном цикле мониторить отпущена ли кнопка, но как то это дико))

 

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

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

2 часа назад, DrobyshevAlex сказал:

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

Вы ещё одна жертва "поверхностного программирования" :)

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

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

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

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

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

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

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

3 часа назад, DrobyshevAlex сказал:

Прерывание срабатывает только по одному фронту

этого не может быть

#include <avr/io.h>
#include <avr/interrupt.h>

ISR (INT0_vect){
PORTB ^= (1<<PB0);
}

int main(void)
{
	DDRB |= (1<<PB0);
	PORTD |= (1<<PD2); 
	MCUCR |= (1<<ISC00); // внешнее прерывание int0 по любому изменению уровня
	GIMSK |= (1<<INT0);
	GIFR |= (1<<ISC00);
	sei(); 
   
    while (1);
}

прижимаем int0 к земле - на PB0 лог.1

отжимаем - на PB0 лог.0

PB0 применил для наглядности, а так просто флаг заводим и все. кнопка нажата (прижата к земле) flag_butt будет равен 1, если отжата flag_butt=0

uint8_t flag_butt;

ISR (INT0_vect){
	flag_butt ^= (1<<0);
}

 

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

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

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

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

Так я так и проверяю, тоже для наглядности вывод на ноге мк меняю. нажал он сменился бросил - нет :) Нажал еще раз опять сменился.

Настройки я показал выше, с даташита брал.

Единственная разница в том что я GIFR (В данном случае по даташиту это EIFR как я понял) не трогал. Я так понял из даташита, это само ставится при наступлении события и очищается при вызове прерывания. То есть это имеет смысл если не использовать ISR а обрабатывать в цикле или если надо сбросить флаг прерывания не из этого прерывания)

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

12 часа назад, DrobyshevAlex сказал:

Я могу как то отследить нажатие кнопки прерыванием и отпускание?

Конечно можете!

но время считать все равно придется:

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

запустить таймер на это "время чуть больше чем максимальное время дребезга", И

в этом прерывании таймера считать значение кнопки (ноги) для дальнейшего использования - зафиксировать нажатие - или ложное срабатывание если уровень не изменился от предыдущего(!), И(обязательно!)

вновь разрешить прерывание на кнопке-ноге, а таймер соответственно запретить или выключить!

 

Это понятно, несколько сложнее чем просто:

Запустите таймер на 10мс и в прерывании от него опрашивайте кнопки.

Но экономит процессорное время, правда совсем чуть-чуть, Главное же в том что нет постоянных прерываний от неактивной кнопки, которые могут стать причиной разных плохо прогнозируемых побочных эффектов!

Изменено пользователем ruhi
дополнение

Можно сделать все! Но чем больше можно, тем больше нельзя!

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

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

Эх... форум все же помогает)) Вот вставил сюда кусок кода, и увидел где моя ошибка. При чем вчера выше я написал без ошибки, а в коде ошибка

MCUSR |= (1 << ISC00) | (1 << ISC10);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • А как же вы квазар спаяли? Или ЛУТом не владеете? Можно даже маркером все прорисовать. А за осцил боятся не стоит, ему на вход будет приходить допустимое напряжение (указано в хар-ках осциллографа).
    • Релюхи не причём. При неисправности релюх симптомы были бы другие. И ИБП даже не клацает когда переходит в  "аварию".   Да. Аккум новый. Более того - 2 новых пробовал. И без АКБ тоже. Не влияет. Да мелкие особо не вздуваются ж. Хотя С21 под подозрением..   Спасибо. Буду иметь ввиду.
    • #include <Wire.h> #include <Oregon_TM.h> #include <BME280I2C.h> //////////////////////////////////////////////////////////////////////////////////////////////////////////// //Скетч для устройства, передающего данные датчика BME280 в формате Oregon Scientific THGN132N //Принципиальная схема прилагается. //Для работы необходима библиотека https://github.com/finitespace/BME280/ //Устройство работает от 3-ех пальчиковых батареек, для экономии электричества заливать скетч нужно через ISP //////////////////////////////////////////////////////////////////////////////////////////////////////////// //Также возможна передача данных в формате - THP (температура, влажность, давление, напряжение батареи) //Пример с приёмником поддерживает расшифоовку THP //////////////////////////////////////////////////////////////////////////////////////////////////////////// # define THGN_SEND 1 // Передавать ли данные в формате THGN132 # define THP_SEND 0 // Передавать ли данные в формате THP # define DEVICE_LOG 1 //Писать ли лог В Serial # define DONE_PIN 15 // вывод сигнала об окончании работы на таймер # define BME_WAIT 10 // Сколько мс ожидать датчик BME # define BATTERY_THR 3.5 // Порог напряжения для выставляения флага разряда батарейки (THGN) ///////////////////////////////////////////////////////////////////////////////////////////////// //Ниблы датчика THP //Во всех полях младшие ниблы идут вперёд!!! // 1-2 - тип (55) // 3 - канал (0-7) // 4-6 - (температура от -100С) * 10. Т.е. +25.1С = 1251 = 4E3h // 7-9 - Влажность *10 Т.е. 25.1% = 251 = 0FBh // 10-12 - (давление от 500ммртст) * 10. Т.е. 765мм = 2650 = A5Ah // 13-15 - данные с АЦП (A0) // 16-17 - CheckSUM // 18-19 - CRC8 (poly 0x07 start 0x00) ///////////////////////////////////////////////////////////////////////////////////////////////// Oregon_TM transmitter(4); BME280I2C bme; bool bme_present = false; float bme_temp(NAN), bme_hum(NAN), bme_pres(NAN); ///////////////////////////////////////////////////////////////////////////////////////////////// void setup() { digitalWrite(DONE_PIN, LOW); pinMode(DONE_PIN, OUTPUT); #ifdef DEVICE_LOG Serial.begin(115200); Serial.println("Waiting for BMEsensor..."); #endif //Обмен данными с BME////////////////////////////////// Wire.begin(); while(!bme.begin()) { if (millis() > BME_WAIT) break; } if (!bme.begin()) { #ifdef DEVICE_LOG Serial.println("No BME sensor found"); #endif bme_present = false; } else { switch(bme.chipModel()) { case BME280::ChipModel_BME280: bme_present = true; bme.read(bme_pres, bme_temp, bme_hum); #ifdef DEVICE_LOG Serial.println("Found BME280 sensor! Success."); Serial.print("Temperature = "); Serial.print(bme_temp, 1); Serial.println("C"); Serial.print("Humidity = "); Serial.print(bme_hum, 1); Serial.println("%"); Serial.print("Pressure = "); Serial.print(bme_pres * 0.75, 1); Serial.println("mmHg"); #endif break; default: #ifdef DEVICE_LOG Serial.println("Found UNKNOWN sensor! Error!"); #endif bme_present = false; } } //Напряжения батареи/////////////////////////////////////////// word battvotage = (word)(((float)(1.1 * 16368) / Vbg()) * 100); #ifdef DEVICE_LOG Serial.print("Battery voltage = "); Serial.println(battvotage,HEX); #endif //Подготовка и отправка данных THGN////////////////////////////////////// transmitter.protocol == 2; if (THGN_SEND) { transmitter.setType(THGN132); transmitter.setChannel(3); transmitter.setBatteryFlag(battvotage < BATTERY_THR); if (bme_present) { if (bme_hum > 98) bme_hum = 98; if (bme_hum < 2) bme_hum = 2; if (bme_temp > 70) bme_temp = 70; if (bme_temp < -50) bme_temp = -50; transmitter.setTemperature(bme_temp); transmitter.setHumidity(bme_hum); transmitter.setComfort(bme_temp, bme_hum); } else { transmitter.setTemperature(-49.9); transmitter.setHumidity(2); transmitter.setComfort(-49.9, 2); } transmitter.SendPacket(); } // Если отправляются оба формата пакетов, межу ними надо выдержать паузу if (THP_SEND && THGN_SEND) delay(100); //Подготовка и отправка данных THP////////////////////////////////////// if (THP_SEND) { transmitter.setType(THP); transmitter.setChannelTHP(1); transmitter.setBatteryTHP( battvotage); if (bme_present) { transmitter.setTemperatureTHP(bme_temp); transmitter.setHumidityTHP(bme_hum); transmitter.setPressureTHP(bme_pres * 0.75); // перевод Pa в mmHg } else { transmitter.setErrorTHP(); } transmitter.SendPacket(); } #ifdef DEVICE_LOG Serial.println(); Serial.print(millis()); Serial.println("ms"); Serial.println(); #endif //Команда на отключение питания digitalWrite(DONE_PIN, HIGH); } ///////////////////////////////////////////////////////////////////////////////////////////////// void loop(){} ///////////////////////////////////////////////////////////////////////////////////////////////// int Vbg() { ADMUX = (1<<REFS0)|(0<<REFS1)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(0<<MUX0); long buffersamp=0; for (int n=0x0; n<=0xff; n++ ) { ADCSRA = 0xc7; while (bit_is_set(ADCSRA,ADSC)); buffersamp += ADC; } buffersamp >>=4; //16368 full scale 14bit ADCSRA &= ~(1 << ADEN); // отключаем АЦП return buffersamp; } Вот код программы. Пробовал по разному и от 5в запитывал и всю систему от 3,3 в. Причем голая ардуинка с таймером работает в нормальном режиме некоторое время, но потом все равно слетает и начинает питать мк постоянно( Причем это происходит всегда через разный промежуток времени.
    • На фото может быть название , характеристики и т.д. И по этому фото я смогу выбрать такой же в инете.. самому мне не собрать..
    • А что даст фотка? Тот же щуп, только чуть крупнее и с проводами питания.
    • Для меня наверное лучше купить готовый.. цель повысить чувствительность до 1 mV.. Наверное на Авто стоит покупать , мне бы фотку какую нить..такого активного щупа..))
×
×
  • Создать...