Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
03.03.2015, 18:49
|
|
Гражданин KAZUS.RU
Регистрация: 15.08.2010
Адрес: Днепр
Сообщений: 842
Сказал спасибо: 74
Сказали Спасибо 199 раз(а) в 174 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от prosto_andriy
|
Большое спасибо Вам за подсказку! Отредактировал код, как Вы посоветовали, но всё равно компилятор почему-то считает функцию бесполезной?
|
Всем доброго времени суток.
Добавляю дополнительные замечания, после более подробного просмотра. Обратите внимание на инициализацию, так, как даже режим ШИМ оказался не выбранным.
Последний раз редактировалось МВА; 03.03.2015 в 19:01.
|
|
|
|
03.03.2015, 20:32
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от МВА
|
Обратите внимание на инициализацию, так, как даже режим ШИМ оказался не выбранным.
|
Вы считаете это важным?
Особенно учитывая реинит таймера при побудке, а первое, что МК делает после инита, это здоровый и крепкий сон.
По сути, весь инит должен состоять из определения параметров порта, установки режима сна и инициализации внешнего прерывания.
Инициализация переменных в данном конкретном случае весьма приветствуется.
|
|
|
|
03.03.2015, 21:32
|
|
Гражданин KAZUS.RU
Регистрация: 15.08.2010
Адрес: Днепр
Сообщений: 842
Сказал спасибо: 74
Сказали Спасибо 199 раз(а) в 174 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от omercury
|
Вы считаете это важным?
Особенно учитывая реинит таймера при побудке, а первое, что МК делает после инита, это здоровый и крепкий сон.
По сути, весь инит должен состоять из определения параметров порта, установки режима сна и инициализации внешнего прерывания.
Инициализация переменных в данном конкретном случае весьма приветствуется.
|
Вот это прерывание при пробуждении:
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
GIMSK=0x00; //Disable External Interrupt-0
MCUCR=0x20; //Idle Mode interrupt by level
TCCR0A&=~(3‹‹6); //‹= ПРЕРЫВАНИЕ INT0 - ДОЛЖНО ИСПОЛЬЗОВАТЬСЯ ДЛЯ ВКЛЮЧЕНИЯ, А ВЫ ВЫКЛЮЧАЕТЕ ШИМ.
TCCR0B=0x03; //CLK/64 Enable Timer
TCNT0=0x00; // ‹= ЭТА СТОРКА ЛИШНЯЯ. ЗАПИСЬ В ЭТОТ РЕГИСТР ДЕЛАЕТСЯ, КОГДА НУЖНО ПОДОГНАТЬ ДЛИТЕЛЬНОСТЬ МЕЖДУ ПРЕРЫВАНИЯМИ, НО ПРИ ШИМ ЕЕ ТРОГАТЬ НЕЛЬЗЯ.
clr_var(); //Сброс переменных
BACKLIGHT_on = 0;//ЕСЛИ ЭТО ПРЕРЫВАНИЕ ВКЛЮЧЕНИЯ - ПОЧЕМУ ВЫКЛЮЧАЕТСЯ ПОДСВЕТКА?
BACKLIGHT_on_off;
}
Попробуйте показать здесь РЕИНИТ. Тольлко выключение ОС0А.
При побудке таймера значения РОН, ОЗУ и РВВ не меняется. Поэтому можно управлять отдельными битами, для включения выключения устройств, и не делать РЕИНИТ. Может я и ошибаюсь, не буду спорить, но в программе, которую я выкладывал для Prosto Andriy, я один раз все инициализировал, и при сне и побудке больше ничего не делал, как только разрешал или запрещал прерывания. Еще сбрасывал или устанавливал COM0A0 и COM0A1 и больше ничего. Даже не трогал биты управления режимом сна, хотя это рекомендуют в даташитах. И все работает без замечаний.
|
|
|
|
03.03.2015, 23:03
|
|
Почётный гражданин KAZUS.RU
Регистрация: 25.05.2010
Адрес: г. Королёв
Сообщений: 8,497
Сказал спасибо: 30
Сказали Спасибо 3,072 раз(а) в 2,013 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от МВА
|
TCNT0=0x00; // ‹= ЭТА СТОРКА ЛИШНЯЯ. ЗАПИСЬ В ЭТОТ РЕГИСТР ДЕЛАЕТСЯ, КОГДА НУЖНО ПОДОГНАТЬ ДЛИТЕЛЬНОСТЬ МЕЖДУ ПРЕРЫВАНИЯМИ, НО ПРИ ШИМ ЕЕ ТРОГАТЬ НЕЛЬЗЯ.
|
Где Вы такую глупость вычитали?
Да, в ДШ есть упоминание, что запись в счётчик таймера может вызвать коллизии в случае TOP›TCNT (что невозможно, ибо и то и другое 0xFF), либо пи обнулении счётчика при счёте вниз (что тоже неправда, ибо считает вверх).
Хотя с тем, что трогать его не нужно, согласен.
Сообщение от МВА
|
Попробуйте показать здесь РЕИНИТ.
|
Здесь не покажу.
У меня был.
Кстати, не наезжайте , в вашей на асме я Вам тоже лишние строки показать могу.
|
|
|
|
04.03.2015, 01:24
|
|
Временная регистрация
Регистрация: 25.06.2013
Сообщений: 58
Сказал спасибо: 25
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
МВА, большое спасибо за то, что указали на ошибки, - в общем, получается, что там строк с ошибками больше, чем без ошибок
Переписал функцию key_scan(); теперь она выглядит так:
PHP код:
|
void key_scan(void)
{
{
if KeyPress //Если кнопка нажата. ЕСЛИ КНОПКА НАЖАТА МЫ ВОШЛИ В ЭТУ ФУНКЦИЮ
{
count++; //Увеличиваем счётчик задержки. ПОСЛЕ ИНКРЕМЕНТА, ЕСЛИ СЧЕТЧИК НЕ ДОСТИГ МЫ ПРОПУСКАЕМ ЭТУ ИНСТРУКЦИЮ
if (count›longkey) //Если длинное нажатие
{
BACKLIGHT_on_off();
count--; // "замораживаем" значение счетчика
} //Выход
}
else
{
count=0; // сбрасываем счетчик
} //Выход
systemClock = 0; //Сброс таймаута выключения подсветки.
}
else
#asm("sleep")
}
|
Теперь правильно???
|
|
|
|
04.03.2015, 18:07
|
|
Гражданин KAZUS.RU
Регистрация: 15.08.2010
Адрес: Днепр
Сообщений: 842
Сказал спасибо: 74
Сказали Спасибо 199 раз(а) в 174 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от omercury
|
Где Вы такую глупость вычитали?
Да, в ДШ есть упоминание, что запись в счётчик таймера может вызвать коллизии в случае TOP›TCNT (что невозможно, ибо и то и другое 0xFF), либо пи обнулении счётчика при счёте вниз (что тоже неправда, ибо считает вверх).
|
Всем доброго времени суток.
Эту глупость я нигде не читал. Эту глупость придумал я сам. Дело в том, что если изменять TCNT0 тогда, когда работает ШИМ, короче, представьте, что Вы при выходе из прерывания инициализируете какое-то значение в ТСNT0, а регистр OCRA или OCRB, а то и оба сразу в этот момент имеют значение меньше, чем вы заложили в TCNT, и в итоге, будет или срыв ШИМа, я не проверял, или будет включение или выключение выхода, в зависимости от того, какой режим используется, сразу в следующем тике таймера. Но, повторяю, это мое мнение.
И для Вас, Prosto Andriy, С точки зрения синтаксиса - ошибок не вижу, но переменная сount, я понял, что она отвечает за длительность нажатия. Поэтому для того, чтобы она инкрементировалась равномерно, это лучше делать в прерывании вместе со всеми счетчиками. А в программе просто обнулять его перед тем как начинаешь отсчет. Но тут тоже не все так просто. У меня в программе именно так и сделано, но делал это я по отрицательному фронту сигнала на кнопке, в противном случае можешь наткнутся на камень, сам не замечая того, что пока будет нажата кнопка счетчик будет сбрасываться. Так как сделано это у Вас, тоже можно, но дело в том, что длительность между инкрементами будет зависеть от длительности цикла, а он в свою очередь не всегда одинаковый и зависит от многих условий в программе и отсчитанная длительность может плавать в очень больших пределах.
PS. Если у Вас цель поучиться, то продолжайте грызть программу, пока не добьете. А если Вам нужно просто, чтобы устройство работало можете установить фьюз SCKDIV8 =0 и заливать ту прошивку, что я выкладывал в последний раз. Там все работает, только в макросе Sleep_ строку
ori r16, 1‹‹0 ;высокий уровень в РВ0(для демоплаты) выключение подсветки
заменить на
and r16,~(1‹‹0).
Последний раз редактировалось МВА; 04.03.2015 в 18:24.
|
|
|
|
04.03.2015, 18:26
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.10.2007
Сообщений: 2,760
Сказал спасибо: 1,105
Сказали Спасибо 1,037 раз(а) в 569 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от МВА
|
Эту глупость придумал я сам. ...
и в итоге, будет или срыв ШИМа, я не проверял,
|
Не проверяли - а пишете.
Ничего не будет, кроме того, что бывает когда счётчик имеет это значение. Он идёт себе дальше...
Сообщение от МВА
|
С точки зрения синтаксиса - ошибок не вижу
|
Вы о №355?
Там такие отступы, что совершенно непонятно, что к чему. В результате - последнее else чьё? Две скобки в начале подряд...
|
|
|
|
04.03.2015, 18:45
|
|
Гражданин KAZUS.RU
Регистрация: 15.08.2010
Адрес: Днепр
Сообщений: 842
Сказал спасибо: 74
Сказали Спасибо 199 раз(а) в 174 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от makakus
|
Не проверяли - а пишете.
Ничего не будет, кроме того, что бывает когда счётчик имеет это значение. Он идёт себе дальше...
Вы о №355?
Там такие отступы, что совершенно непонятно, что к чему. В результате - последнее else чьё? Две скобки в начале подряд...
|
Точно, скобки я не считал и логику в отрыве от программы рассматривать тоже бесполезно.
Prosto Andriy, обрати внимание на последнюю строчку от makakus.
А насчет того что счетчик считает дальше это верно. Длительность цикла до следующего прерывания будет меньше и этим можно подгонять цикл я тоже согласен, но, в момент совпадения регистра сравнения и счетчика должен поменять состояние выход ШИМ. Но, если в прерывании будем инициализировать TCNT значениями больше чем регистр сравнения, то и совпадения не будет никогда. Кстати, я могу это сейчас прогнать в AVR Studio
PS. Только что прогнал в AVR Studio свои предположения по инициализации. Все подтвердилось - ШИМ пропадает. Проэкт прилагаю, правда там есть кое-что лишнее, я его закоментировал. Для проверки запустите автовыполнение и ШИМ будет. Потом раскоментируйте строчку в прерывании, где в TCNT0 заносится значение, и ШИМ пропадет.
Кстати, если после условия идет только одна инструкция, фигурные скобки можно не ставить. Поэтому в №355 остается ошибкой только вторая фигурная скобка, хотя так лучше не делать.
Последний раз редактировалось МВА; 04.03.2015 в 20:11.
|
|
|
|
04.03.2015, 23:31
|
|
Временная регистрация
Регистрация: 25.06.2013
Сообщений: 58
Сказал спасибо: 25
Сказали Спасибо 3 раз(а) в 3 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от makakus
|
Вы о №355?
Там такие отступы, что совершенно непонятно, что к чему. В результате - последнее else чьё? Две скобки в начале подряд...
|
else, которое внизу проги, относиться к if KeyPress, то есть по идее строка кода #asm("sleep") должна выполняться, когда кнопка не нажата
но я вот думаю, может там вообще не нужно было писать else, а просто написать #asm("sleep")
Это бы что-то изменило?
|
|
|
|
05.03.2015, 10:38
|
|
Почётный гражданин KAZUS.RU
Регистрация: 08.10.2007
Сообщений: 2,760
Сказал спасибо: 1,105
Сказали Спасибо 1,037 раз(а) в 569 сообщении(ях)
|
Re: Как отследить короткое и продолжительное нажатие кнопки в фонаре?
Сообщение от prosto_andriy
|
по идее строка кода #asm("sleep") должна выполняться, когда кнопка не нажата
но я вот думаю, может там вообще не нужно было писать
|
Последние 5 слов - категорически присоединяюсь! в вашей программе вы должны отвечать за каждую букву (и даже пробел) - почему и для чего. Ковырять палкой и наблюдать результат можно, но ничего путного не получится.
А программа у вас такая:
несчастливая строка подвела.
компилятор не ругается на else без if?
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 16:21.
|
|