pyzh_man, спасибо! Помогло! Если не сложно, объясните, когда нужно использовать PIN а когда PORT? А что я что-то запутался. Изначально писал, как вы сказали, потом вспомнил, что меня как-то уже поправляли на PIN ...
_________________ Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
IN PIN считывает из порта, когда тот настроен на ввод. OUT PIN не имеет смысла. OUT PORT подключает/отключает подтягивающие резисторы, если порт настроен на ввод; выводит инфу, если порт настроен на вывод. IN PORT считывает инфу, ранее записанную в порт, настроенный на вывод.
OUT PIN имеет смысл во всех новых AVR. «Новых» -- это где-то так от tiny13, tiny2313, mega48/88/168, ... с любыми буквами -- т.е. практически все, кроме старушки attiny26 да обновленных atmega8A, atmega64A, которые просто совместимы со старыми. Я на этом форуме уже приводил картинку из документации Вот где есть такой обведенный инвертор, там по сигналу WP (Write PIN) инвертируется триггер PORT. Очень удобно.
Код:
SBI PINB, 2 ; инвертировать PB2 LDI R16, 0x88 OUT PINB, R16 ; инвертировать одновремённо PB3 и PB7
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Мужики, а как в CV с областью видимости глобальных переменных? Видны во всех файлах проекта, без extern... Как то не аккуратненько. Или лыжи не едут?
"Интересно девки пляшут"! Этот фокус демонстрируется на v.1.25.9pro, с 2.04.4а всё как положено - глобальные (не static) не видны в других файлах проекта. Версиезависимость, однако, не солидно!
Последний раз редактировалось OKF Вс сен 11, 2011 10:04:55, всего редактировалось 1 раз.
Подскажите почему не работает такой способ установки битов в регистре TIMSK=(1<<TOIE1)|(1<<TOIE0); ну и стольные регистры с названием битов . и ели использовать такой вариант прокатит-будит лит аналогичен первому? TIMSK=(1<<2)|(1<<0);
Подскажите в какой версии CV пропадают глюки инициализации переменных?
Пользую 1.25.5 - при инициализации локальных переменных в строчку или присвоении им значений при инициализации в итоге в них совсем не то, что записывается явно в коде.
Помогите пожалуйста. Вот написал программу - мигание светодиода с периодом 1с. Только почему-то у меня идет период не 1с, а 1,675с. МС - atmega324p. Частота - 20 МГц. Светодиод подсоедиен с PD2.
Код:
/***************************************************** Chip type : ATmega324 Clock frequency : 20,000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 512 *****************************************************/
#asm("cli"); //запрещение прерываний на время обработки прерывания #asm("sei"); //разрешение прерываний
в прерывании не имеют смысла. Железо само заботится о разрешении прерываний здесь.
И работать это не будет, т.к. никакого антидребезга здесь нет. Только задержка. Хотя... почему? Вполне возможно. Ведь за 100 мс состояние кнопки успеет устаканиться. Другое дело, что на нажатие кнопки контролер будет реагировать дважды: первый раз на нажатие кнопки (появление дребезга) и второй при её отпуске (опять дребезг).
Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт сен 15, 2011 08:04:12
Поставщик валерьянки для Кота
Карма: 1
Рейтинг сообщений: 5
Зарегистрирован: Ср май 11, 2011 21:37:45 Сообщений: 1995 Откуда: Цветочный город
Рейтинг сообщения:0
DataLife писал(а):
Просто для того, что бы его не было, после задержки нужно снова проверять состояние кнопки, в этом случае этого нет, если не ошибаюсь..
да, именно это важно, а то, что сделано - бесполезно и, скорее всего, приведет к "задваиванию" нажатий и, опять же скорее всего, к реакции на отжатие. Ну и, само собой, к заметным тормозам - с такой-то зедержкой!
IfoR писал(а):
в прерывании не имеют смысла. Железо само заботится о разрешении прерываний здесь.
еще как имеют! особенно sei - может таких чудес наделать...
_________________ битва с дураками проиграна, победители торжествуют. слава победителям!
while (step!=100) { /// вывод значения conflict в ком порт. ....
Всё - тут оно становится 0xC0 почемуто. Може настройки компилятора? Такие же фокусы выкидывает в функции main. При этом - это НЕ повторяющийся глюк... В том то и проблема - анализу сложно поддаётся. ЗАИПАЛСЯ. Уже мысли появились слинять с cvavr...
interrupt [EXT_INT0] void ext_int0_isr(void) //обработка прерываний INT0 { delay_ms(100); // антидребезг <=== #asm("cli"); //запрещение прерываний на время обработки прерывания s=s+1; if (s==4) s=1; #asm("sei"); //разрешение прерываний }
1) кнопка нажата (пошёл некий дребезг) 2) сработало прерывание, но тут задержка, которая не даёт дребезгу несколько раз изменить значение переменной S 3) прошла задержка, дребезг устаканился, переменная увеличилась, как и должна
Просто если бы не задержка сразу увеличивались бы переменная и дребезг мог бы тут подпортить картинку...
На счёт #asm("cli"); и #asm("sei"); - не знаю как правильно, в обучающих статьях по прерываниям я видел, что делают так. У меня так работает, места в прошивке они практически не занимают...
_________________ Только те, кто предпринимают абсурдные попытки, смогут достичь невозможного.
Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт сен 15, 2011 15:53:44
Поставщик валерьянки для Кота
Карма: 1
Рейтинг сообщений: 5
Зарегистрирован: Ср май 11, 2011 21:37:45 Сообщений: 1995 Откуда: Цветочный город
Рейтинг сообщения:0
DataLife писал(а):
1) кнопка нажата (пошёл некий дребезг) 2) сработало прерывание, но тут задержка, которая не даёт дребезгу несколько раз изменить значение переменной S 3) прошла задержка, дребезг устаканился, переменная увеличилась, как и должна
Просто если бы не задержка сразу увеличивались бы переменная и дребезг мог бы тут подпортить картинку...
на самом деле все будет немного иначе: 1) нажали кнопку, пошел дребезг. по первому импульсу дребезга сработало прерывание. началась задержка. 2) импульсы дребезга устанавливают флаг запроса прерывания, пока длится задержка. 3) после задержки вы запрещаете прерывания - бессмысленно, т.к. в этот момент они и так запрещены. увеличиваете переменную, все путем. 4) разрешаете прерывания. тут, раз флаг запроса уже установлен (см. ранее), буквально ЕЩЕ ДО ВЫХОДА ИЗ ОБРАБОТЧИКА (Си генерирует на "закрывающую фигурную скобку" далеко не одну команду, а больше) снова осуществляется вызов обработчика, т.е. еще из него не вышли, но уже снова в него вошли. если очень не повезет - вы переполните стек, но скорее всего обработчик отработает ЕЩЕ РАЗ, т.е. ваша переменная увеличится на 2, а не на 1. 5) далее все по плану. однако, если кнопку держат нажатой больше 200 мс, то в момент отжатия снова скорее всего сгенерируется прерывание, и процесс повторится.
итак, в худшем случае вы попортите стек программы, что приведет к непредсказуемым последствиям, в лучшем - получите задваивание показаний, причем это может происходить и при нажатии, и при отпускании кнопки.
не мудрите, делайте, как положено: опрос-задержка-опрос, если оба опроса дают одинаковые уровни на пине - дребезг кончился, если разные - это надо игнорировать. для подавления дребезга ДОСТАТОЧНО 15-20 мс задержки.
_________________ битва с дураками проиграна, победители торжествуют. слава победителям!
Заголовок сообщения: Re: CodeVision AVR в вопросах и ответах
Добавлено: Чт сен 15, 2011 16:14:49
Встал на лапы
Зарегистрирован: Вт мар 22, 2011 22:31:01 Сообщений: 102
Рейтинг сообщения:0
Мастер Ломастер писал(а):
в лучшем - получите задваивание показаний
не знаю не знаю... может и так. поделюсь своим опытом:
опрос кнопки в основном цикле программы: если кнопка нажата, ставим флаг игнорировать кнопку и пускаем таймер на 20мс. ПО переполнению таймер сбрасывает флаг. Работал максимум с 4-6 кнопок, поэтому блочил все одновременно, но при желании можно сделать не тупой флаг, а битовую маску и проверять запрет на каждую кнопку.....
думаю в случае с прерыванием имеет смысл вручную сбросить флаг прерывания перед выходом из обработчика......
Простеший способ : запускаете таймер по срабатыванию кнопки на 10-20мкс и по прерыванию таймера опрашиваете её. В прерывании счётчик - если кнопка нажата ( 1 или 0 - в зависимости от реализации) , то к счётчику +1 и перезапускаете опять на 10-20 мкс. После 100 циклов - 1-2 мс - смотрите значение счётчика - если больше 60%( к примеру - в зависимоти от кнопки) - значит ктото её нажимал. Если пустить таймер в цикле, а на каждую кнопку завести свой счётчик - можно паралельно опрашивать целую клавиатуру.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 21
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения