Задача состоит в том, чтобы при нажатии кнопки переключались режимы: 1) последовательность импульсов, где 1- 667 мкс, 0-1333 мкс 2) последовательность импульсов, где 1- 1333 мкс, 0-667 мкс 3) уровень 1 4) уровень 0 Но у меня получается, что горит либо пока зажата кнопка, и то по одному режиму, либо после отпускания кнопки горит еще секунды 3 и все, а нужно после нажатия чтоб горело до следующего нажатия с переключением. Свой код прилагаю. Помогите подправить, пожалуйста.
Заголовок сообщения: Re: Плафон освещения кабины на pic12f615
Добавлено: Сб июл 20, 2019 12:42:49
Модератор
Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4599 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
У Вас в корне всё неправильно. Под Вашу задачу "подправить" не получится, нужно полностью переписывать весь код. Формирование импульсов сделайте на прерывании таймера. Периоды у Вас кратны одному значению. Обработку кнопок можно тоже туда же запихнуть, времени между вызовами должно хватить на всё. В крайнем случае, сделаете обработку и переключение режимов в основном цикле.
Заголовок сообщения: Re: Плафон освещения кабины на pic12f615
Добавлено: Сб июл 20, 2019 12:54:17
Модератор
Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4599 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Посмотрел даташит на ваш камушек, там даже есть модуль PWM. Проблем решить Вашу задачу нет вообще никаких... Курим раздел этого модуля в даташите... Если PWM будет сложно, то изучаем таймеры (в частности TMR2). Его описание есть также в ДШ.
Для начала смените сам подход к решению. Если Вы хотите перебирать неких 4 режима (не важно чего), то создайте автомат реализующий эти 4 режима. По сути - программный счетчик по нажатию кнопки. И учтите, что у кнопки есть дребезг. Дребезг удаляется с помощью чтения кнопки с интервалом бОльшим, чем время дребезга. Даже если кнопка посредственного качества, то 20...30 мс перекроют ее дребезг. На выходе такой защиты будет состояние кнопки без дребезга, но еще не сам счетчик режимов. Далее нужно ловить СОБЫТИЕ (а не состояние) нажатия. То есть анализировать ПРЕДЫДУЩЕЕ и ТЕКУЩЕЕ состояние кнопки. И при их сочетании соответствующем событию нажатия (01 или 10 - зависит от схемотехники кнопки) можно инкрементировать счетчик режимов. Далее нужно этот счетчик ограничить в счете или анализе (у Вас 4 режима, значит можно просто наложить маску &0b00000011 при анализе режима, но не ограничивать счет). Ну и анализируя номер режима, переключать этот самый режим по if, а лучше по case, загружая в PWM необходимые параметры. ЗЫ. По поводу реализации. И таки да, прерывания по таймеру для анализа кнопки, а не дурацкий блокирующий delay(), Вам помогут...
КРАМ, если с дребезжанием мне еще понятно, то вот на ловку события хотелось бы увидеть хотя бы несколько строк кода примера, ибо мои поиски не увенчались успехом, это вам легко на словах, а мне как не профи в этом не очень, поэтому и прошу хоть какой-то мини пример
Заводим некую переменную - состояние кнопки (назовем ее statButton, например): В нее вдвигаем (левый сдвиг) текущее бездребезговое значение кнопки и маскируем два младших разряда этой переменной:
Код:
uint8_t countMode=0; uint8_t reqChangeMode=0;
// в обработчике прерываний по таймеру - чтение кнопки GP0 static uint8_t statButton;
if (GP0) { statButton=((statButton<<1)|1)&0x3; } else { statButton=((statButton<<1)|0)&0x3; } if (statButton == 0b10) { reqChangeMode=1; }
// в main-e if (reqChangeMode) { reqChangeMode=0; countMode=(countMode+1)&0x3; switch (countMode) case 0: настраиваем режим 0 case 1: настраиваем режим 1 case 2: настраиваем режим 2 case 3: настраиваем режим 3 }
Какая то каша из того, что предложил я и странного кода... Объясните к чему в обработчике какой то счетчик и что за CheckButton? И почему в комментариях упоминается GP3 как пин с кнопкой, а Вы оставили GP0? Или давайте схему. Совершенно непонятно какая частота у МК.
В прерывании проверка пина должна находится ВНУТРИ обработчика таймера (T2IE&&T2IF), а не снаружи. Не надо выносить переменные используемые в прерывании наружу. Достаточно сделать их static. И уберите из кода все, что не относится к алгоритму.
Внимательно посмотрите что было в моем коде static. И static не инициализируют, иначе в нем нет никакого смысла. static - это локальная переменная не изменяющая своего значения между выходом и следующим входом в функцию. Только statButton локальная статик переменная. Остальные - глобальные. И не нужно их делать 16 разрядными. Все переменные алгоритма unsigned char или uint8_t
Добавлено after 6 minutes 3 seconds: ЗЫ. Кстати, а Вы работаете в железе или в симуляторе?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения