В общем я делаю блок управления для УМЗЧ. Регулировка громкости будеи происходить при помощи валкодера (или как он там правильно называется, когда крутишь в одну сторону, контакты замыкаются в одном порядке, если в другую, то наоборот).
while (1)
{
if (PIND.7==0) {
if (enc_dec==1) {
enc_count--;
enc_dec=0;
enc_inc=0;
printf("%c\r",enc_count);
}
else {
enc_inc=1;
};
};
if (PIND.6==0) {
if (enc_inc==1) {
enc_count++;
enc_dec=0;
enc_inc=0;
printf("%c\r",enc_count);
}
else {
enc_dec=1;
};
};
};
Это пока главный цикл программы.
Тут для примера сделал вывод состояния переменной-счетчика enc_count.
Изначально переменные enc_dec, enc_inc установлены в 0.
Выводы PD6 и PD7 програмно подтянуты к + питания.
Проблема такая, при повороте движка на одно деление происходит многократное выполнение кода и соответственно число в счетчике уменьшается (увеличивается) не на 1, как требуется, а на много больше.
Как решить эту проблему, мож кто сталкивался, подскажите пожалуйста.
Можно оставить схему как у вас и две ножки МК подсоединить диодами к INT0 настроеному как вход с подтяжкой и прервание по спаду. А в прерывании инализировать направление.
Думайте сами, решайте сами ... а вот он-лайн перевод на корявый русский http://translate.ru
Тебе необходимо добавить в свой код цикл ожидания момента, когда состояние твоих входных портов изменится - и только после этого продолжать основной цикл. В этом случае при одном и том же состоянии счетчик увеличится только на 1.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
ARV писал(а):Тебе необходимо добавить в свой код цикл ожидания момента, когда состояние твоих входных портов изменится - и только после этого продолжать основной цикл. В этом случае при одном и том же состоянии счетчик увеличится только на 1.
У меня еще будет процедура вывода информации на ЖКИ от Nokia 3310, только вот не знаю куда ее засунуть, в главный цикл или в таймер. Задержки - это первое что мне пришло в голову, но тогда если состояние долго не изменится (например я не до конца провернул ручку и произошло замыкание только первого контакта) то программа подвиснет до его изменения и ничего кроме прерываний обрабатывать не будет. Кстати, на прерывание еще повешу IR приемник для декодирования сигналов с пульта.
tych писал(а):Если не использовать прерывание то твоя прога может вечно крутится в опросе ( поллинге ) валкодера и ничего больше делать не сможет.
Тот код который я привел - есть главный цикл функции main. так что после обработчика валкодера в него можно впринципе вставить еще чего-то. ЛАдно, попробую сделать с прерыванием, похоже это единственный приемлемый вариант.
Вообще-то, tych прав: делай в основном цикле вывод всего, чего надо, управление всем чем надо, а остальное (всю входящую информацию) делай по прерываниям - валкодер, IR-приемник, таймер...
а при ожидании можно извратиться и тоже че-то делать, но это муторно, имхо...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Значит так и сделаю. с задержками чет нет желания заморачиваться. Ладно, разработки данного давайса приостановлены до понедельника, отдыхаю. Потом отпишусь че получилось.
Автор пропал куда-то. Очень интересно увидет код этой штуки. Имеется такая штука, только она из мышки, современной (умерла бедная совсем). Он такой маленький имеет 3 вывода. Фото позже будет. Я уверен что в нем нет оптопары, по простой причине что она просто туда не поместиться.
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if ((PIND.7 == PIND.6)) vol++;
if ((PIND.7 != PIND.6)) vol--;
}
Принцип простой. Любой из выводов валкодера цепляем на внешнее прерывание, допустим PD7(все зависит от контроллера), а другой вывод на любую ножку контроллера сконфигурированную как вход, допустим PD6. Дальше из кода все понятно.
Мне бы хотелось выяснить как допустим можно сделать так: если быстро крутить его то значение инкремента увеличивалось на 10 единиц, а если медленно то на 1?
Последний раз редактировалось VenomXP Пт июн 05, 2009 11:21:01, всего редактировалось 1 раз.
VenomXP писал(а):Мне бы хотелось выяснить как допустим можно сделать так: если быстро крутить его то значение инкремента увеличивалось на 10 единиц, а если медленно то на 1?
я делал такой вариант и даже где-то выкладывал код... но меня раскритиковали - сказали, что неудобно... и я забросил это
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Я думаю принцип следующий. Запускаем таймер пусть он считает вообще не останавливаясь до максимума. Вводим переменную которая бы считала чколько времени прошло: count++; Далее когда приходит внешнее прерывание делаем так:
код не оптимальный и можно сделать красивее
но у меня работает хорошо и этим все сказано - переделывать лень и нет времени
в основном цикле
if (enc.flip == 1)
{
kbd_key = enc.code;
beep();
enc.flip = -1;
return 1;
// в зависимости от кода клавиши полученной от валкодера
// принимаем решение что делать
}