Если ничего не получается с наскоку, то... перво-наперво все стереть и нарисовать блок-схему будущего алгоритма. Для прерывания - одну, для программы - другую.
Причем делать так как ты делаешь - нельзя. в твоем случае этого вобщем-то не так заметно, но переменная button у тебя используется как программой так и прерыванием, а прерывание может возникнуть в ЛЮБОЙ МОМЕНТ времени, даже непосредственно перед проверкой! А у тебя подряд идут целых 8 проверок. Перед такими проверками надо обеспечить неизменность переменной, иначе получишь такую ситуацию значение button = 5, только что проверили значение на 5 - совпало что-то делаем и тут возникает прерывание, button меняется на 6 заканчиваем действие и происходит очередное сравнение button с числом 6 - это условие тоже срабатывает... Беда в том что отловить такую ситуацию крайне сложно, в тестах она будет возникать довольно редко - когда момент проверки во времени совпадет с прерыванием да еще в нужной фазе.
Как это обеспечить? до окончания проверок запретить прерывания, или скопировать значение переменной и сравнивать уже копию.
Но лучше, действовать через флаги - в прерывании можно только установить флаг, а в основной программе только сбросить и только один раз. Тогда никаких конфликтов не происходит.
Просто почитать про атомарные операции. А ещё лучше - понять, что это такое. Применительно к Си советую глянуть тут
Да, это все здорово. Но к чему я это? А к тому, что у нас тут есть еще и прерывание. В котором может быть изменены наши значения, а еще тот милый факт что прерывание, будучи разрешенным, может выскочить между двух любых инструкций. И при этом родить очень адский глюк которой может ВНЕЗАПНО вылезти через пару лет безглючной работы, а потом также бесследно исчезнуть, оставив разработчика задумчиво чесать репу на предмет «ЧТО ЭТО БЫЛО»? Часто тут грешат на глюки железа и дырявые процы. Хотя на самом то деле просто программа была корявая
Alexeyslav, это не вам разумеется, это в дополнение
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
А я буквально на днях написал похожий велосипед... По прерываниям у меня идет динамическая индикация (5 мС). Нажатие на кнопку устанавливает флаг, отжатие - сбрасывает. Если нажата кнопка, счетчик в прерываниях инкрементируется и сравнивается с константой - задатчиком длительности антидребезга. При каждом отпускании кнопки в момент опроса счетчик сбрасывается. Подпрограммы выполнения нажатий вызываются по соответствию флага (установлен или нет). В каждой подпрограмме и происходит сравнение инкрементного счетчика с антидребезгом. После одиночного срабатывания подпрограммы выставляется 2-й флаг для запрета выполнения процедуры до отпускания и следующего нажатия на кнопку. Таким образом, в прерывании выполняется примерно 50 - 200 строк кода (на 4 кнопки) в зависимости от нажатий. При этом нет никаких задержек в прерывании.
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Счетчик лишний, чтобы подавить дребезг опроса каждые 5мс вполне достаточно если дребезг кнопки длится меньше 5мс, если около 5мс - опрашиваешь кнопку через раз.
Просто в таком случае, самое неприятное что может произойти из-за дребезга это зарегистрируешь нажатие на один опрос позже.
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
Когда вместо кнопок что зря (попадалось раз, ... его) с переходным процессом в 150 мС (+-)... Сколько я промучился (делал дистанционно - настроил с кнопками на столе, а в поле . . .)
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Со 150мс уже проще применять аппаратные подавители - например перезапускаемые одновибраторы - так и дребезг будет проглочен и момент нажатия не упущен. А если момент нажатия не важен - с таким дребезгом опрашивать каждые 250мс, 500мс...
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
Оператор цикла for (насколько я помню С++) считает до 20-ти тактов? Если так, то этого может быть мало (дребезг). А так, идею уловили.
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Почему в обработчике прерываний сразу начинаю опрашивать кнопку, просто моё мнение (может и не прав) но мне кажеться что если кнопка не нажата, то пусть обработчик просто прогонит пустой цикл, тем самым не нагружая его!
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
Не заметил последней строки про 8 мС. Alex - циклы нужны там, где 8 мС времени между прерываниями не обеспечивают четкое срабатывание кнопки. 2 таких цикла дадут 16 мС без значительного прироста затрат машинного времени. PS С особо не знаю, пишу на Ассемблере, поэтому я мог не совсем понять приведенный участок кода.
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4570 Откуда: Планета Земля
Рейтинг сообщения:-1 Медали: 1
Цитата:
Аlex то бишь вот так?
Не совсем понимаю что у Вас написано, но что-то не то. Зачем второе вложенное условие, если оно такое-же ? Понятно что оно выполнится, по этому оно лишнее. И что за переменная button, которую Вы всё пытаетесь инкрементировать ?
... if ((PIND&0x80) == 0) { temp = PIND; if ((PIND&0x80) == 0) ...
Ты опять проверяешь значение которое может изменится в любой момент два раза и на этом строится алгоритм... он обязательно будет давать сбои! Причем сбои именно из-за дребезга(от чего боролись на то и напоролись)!
Достаточно считать значение с порта зафиксировать его(скопировать во временную переменную) и сравнить его с предыдущим, потом после сравнения скопировать в предыдущее.
Тогда ты запросто можешь различить 4 разных состояния кнопки - нажата, отпущена, момент нажатия(один раз, когда предыдущее равно 0 а текущее 1), момент отпускания(когда предыдущее равно 1 а текущее 0).
Цитата:
Зачем второе вложенное условие, если оно такое-же ? Понятно что оно выполнится
В том-то и дело что если момент дребезга попадет на прерывание то существует вероятность что сравниваемые значения в условиях будут разными! и если первое условия будет выполнено, то второе иногда может и не выполнится даже если кнопка идеальная. Ведь переключение может произойти и в момент между проверками.
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4570 Откуда: Планета Земля
Рейтинг сообщения:-1 Медали: 1
Цитата:
В том-то и дело что если момент дребезга попадет на прерывание то существует вероятность что сравниваемые значения в условиях будут разными! и если первое условия будет выполнено, то второе иногда может и не выполнится даже если кнопка идеальная. Ведь переключение может произойти и в момент между проверками.
Тут я согласен, полностью. Но я имел ввиду - какой смысл от двух одинаковых вложенных условий. Мне интересно, о чём думал человек, писав это А так, безусловно, Вы правы, нужно сначала прочитать, потом работать. О чём человеку уже и было сказано.
Достаточно считать значение с порта зафиксировать его(скопировать во временную переменную) и сравнить его с предыдущим, потом после сравнения скопировать в предыдущее.
ни как не въеду, от кудо берёться предыдущее значение? если я допустим только что запустил МК, от куда в нём предыдущее значение хоть убей не пойму
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4570 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Если только включили, то оно (значение) будет определённым Вами, т.б. то, которое Вы напишите при инициализации. А дальше, оно будет сохраняться из текущего.
В процессе инициализации, предыдущее значение можно записать тем что имеется на входе на самом деле, например включили с нажатой кнопкой - и в таком случае событие "момент нажатия" не будет зарегистрировано в обработчике прерывания. Но если надо обязательно отреагировать как на нажатие - то просто записать "отжата" в процессе инициализации контролллера, и через 8мс когда возникнет прерывание он посмотрит что кнопка была отжата а стала нажата - значит произошло нажатие и обработает как полагается.
if ((PIND&0x80) == 0) temp_1 = PIND; // Достаточно считать значение с порта зафиксировать его if (temp_1 == temp) {y = 1;} // и сравнить его с предыдущим temp = temp_1; //потом после сравнения скопировать в предыдущее
Карма: 90
Рейтинг сообщений: 1430
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4570 Откуда: Планета Земля
Рейтинг сообщения:-1 Медали: 1
Примерно так. ТОлько нужно сохранить состояние вывода в темп, а потом с ним уже работать. И чара многовато будет для 1 бита, хотя можно сначала и с чарами побаловаться, потом, когда поймёте принцп, создадите уже битовые поля.
Так верно, в temp_1 сохраняется весь порт... любое изменение в любых битах и будет срабатывать нажатие.
ты сначала сохрани один раз в temp_1 = PIND&0x80, и потом используй только temp_1 в условиях и т.д.
и у тебя сейчас происходит копирование temp_1 = PIND только когда кнопка нажата... и что в результате останется в переменной когда кнопка не нажата? да еще и не инициализированной...
Рано тебе программы писать "с наскока". Начни с блок-схем. На них хорошо видны все возможные ситуации и узкие места.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения