Да я ведь уже озвучил алгоритм, там не нужны двухбайтные счетчики - надо только по шагам разобраться с конфигурацией таймера и по шагам реализовать достаточно простой алгоритм.
Вывод на индикатор реализовать совсем просто - выдели массив из 4-х байт, и в прерывании последовательно выводи их на индикатор переключая знакоместа. Это все что нужно реализовать в прерывании. Когда это будет реализовано то чтобы вывести что-то на индикатор достаточно изменить значение этого массива, а дальше оно "само" подхватит.
Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34 Сообщений: 1292 Откуда: Запад Беларуси
Рейтинг сообщения:0
таймер по совпадению. индикация в прерывании. оказывается не нужно было принудительно гасить цифру, они все автоматом гасятся при записи цифры в порт В. Вроде бы как в шпротеусе всё красиво... В чём разница между PORTD |= 0<<6 и PORTD.6=0? Я знаю, что это для разных компиляторов (одна для AVR Studio, а другая для CV AVR), но когда пишу первую команду - точка не светится, а со второй командой всё отлично... В моём исходнике строка 50...
Вложение:
12-41.rar
Странно, но с задержками размер hex файла получался меньше... По ходу фьюзы будут уже такие:
Работать не будет в принципе: 1) Сколько ноль ни сдвигай в [нулевом] байте, результат будет ноль. 2) PORTD | 0b00000000 == PORTD, поэтому присваивание |= оставит PORTD без изменений
Правильный вариант для сброса одиночного бита, если нужна независимость от среды разработки:
Код:
PORTD &= ~(1 << 6)
для установки:
Код:
PORTD |= (1 << 6)
для инвертирования (мигать разделителем можно именно так):
Код:
PORTD ^= (1 << 6)
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Да, есть такой недостаток - когда надо работать с несколькими битами сразу, от сдвигов начинает рябить в глазах Особенно адово это выглядит в STM32
Не знаю, как в других средах разработки (не пользуюсь, поскольку юниксоид ), но в avr-gcc есть _BV(<имя_бита>), например, чтобы сбросить 6-й бит порта D, надо писать
Код:
PORTD &= ~_BV(PD6)
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34 Сообщений: 1292 Откуда: Запад Беларуси
Рейтинг сообщения:0
Вот ещё одна оптимизация. Зачем при формировании числа перед записью в массив надо сдвигать на 4, если можно в исходнике в массив чисел (digits) записать уже готовые числа вместе со сдвигом и сразу их записывать в массив и в порт...
Странно... Вроде бы в CV AVR и AVR Studio одинаковые исходники, но в шпротеусе с исходником от CV будильник и индикация работают нормально, а с исходником от AVR Studio при срабатывании будильника шпротеус начинает жрать ресурсы проца и тормозит..
Наверное осталось оптимизировать только генерацию сигнала для будильника (там остались задержки, а у меня есть свободный таймер) и это деление на 10... Как организовать ШИМ для будильника?
А надо ли ШИМ? У таймера есть режим работы Wave - каждое переполнение таймера вывод инвертируется, это и используют для генерации звука(чистый меандр) частота которого в 2 раза ниже частоты переполнения таймера - устанавливаешь коэфициент деления и...
Используется выход OC0B контроллера.
Код:
генерация частоты: от F/4 до F/512 это примерно 31кГц до 240Гц. ; Расчет частоты: F = (8000000/64) / ((OCR0A+1) * 2) при условии OCR0A <> 0 из-за аппаратных особенностей счетчика. ; Рассчет делителя: OCR0A = ((8000000/64) / (2*F)) - 1
sound_init: set_io TCCR0A, 0b00010010 ; COM0B1:0 = '01' -> Toggle OC0B on Compare Match ; WGM01:00 = '10' -> режим таймера 2 - CTC, счет до OCR0A set_io TCCR0B, sound_disable_config set_io OCR0B, 0 ; Инверсия выхода по началу счета. RET
do_sound: ; ACCUM задает тональность out OCR0A, ACCUM ; устанавливается период таймера set_io TCNT0, 0 set_io TCCR0B, sound_enable_config ; Разрешить работу таймера. RET
Вот ещё одна оптимизация. Зачем при формировании числа перед записью в массив надо сдвигать на 4, если можно в исходнике в массив чисел (digits) записать уже готовые числа вместе со сдвигом и сразу их записывать в массив и в порт...
Это несущественно. Вообще, оптимизация никогда не должна быть самоцелью. Если нет действительной необходимости в этом, надо использовать более понятные для человека алгоритмы (ведь программу надо сопровождать, иногда этим будут заниматься другие люди, да и автор через несколько месяцев может подзабыть), нежели хитро закрученные трюки ради экономии нескольких байт или 10% увеличения быстродействия.
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34 Сообщений: 1292 Откуда: Запад Беларуси
Рейтинг сообщения:0
Контроллер у меня SOIC. Фиг я его выпаяю без фена. Можно ли в плате подпаять провода и прошить через Uniprof и COM порт? Между базами транзисторов и портами контроллера стоят резисторы по 1кОм. Между сегментами индикатора и К176ИД2 - по 100ом. Подойдут ли такие номиналы? Есть ещё 3 кнопки, для которых не сделан антидребезг... "Установка будильника", "Минуты/секунды" и "Включить будильник". Для них также придётся делать переменные...
_________________
Последний раз редактировалось Xatrix Пт фев 07, 2014 03:47:50, всего редактировалось 1 раз.
Насчет прошивки через COM не подскажу, всегда во всех конструкциях предусматриваю SPI разъем для программирования, хоть он и денег стоит, и места на плате занимает. Если габариты корпуса не позволяют поставить разъем, то надо было тебе сделать хотя бы контактные площадки, чтоб подпаяться.
В моем программаторе (китайская USB поделка) есть последовательные резисторы 100 ом. Если будешь подпаиваться прямо к ногам, то эти резиторы между портами и выводами программатора желательно включить, если их нет в самом прграмматоре. Кроме того, смотри на уровни питания программатора и контроллера - они должны быть одинаковы.
Как рассчитать резисторы - да просто по закону Ома Для катодных (те, что между сегментами индикатора) - напряжение питания минус падение на сегменте делишь на ток в импульсе. Разумеется, выходные каскады дешифратора должны выдерживать этот ток в длительном(!) режиме работы - т.е., как если бы он был постоянным. И соответственная должна быть мощность рассеяния этих резисторов - так, в моих гигантских часах двухваттные резисторы сильно грелись. Для базовых - 1 кОм нормальная величина.
Что касается меня, я делаю антидребезг аппаратно - для меня не составляет проблем на каждую кнопку предусмотреть три "лишних" деталюшки 0805. Незначительное и копеечное усложнение схемы - зато в программе заботиться об этом уже не надо.
В будущем, наверное, сделаю программно, больше ради спортивного интереса - но настоящие джедаи не ищут легких путей - есть у меня на примете относительно простой алгоритм цифрового ФНЧ, повесить можно на то же прерывание, которое рулит динамической индикацией
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Такой аппаратный дребезг не гарантирует отсутствие дребезга, он только уменьшает его вероятность.
А чем собственно программный плох? Фиксируешь кнопки один раз в 10мс, и больше ни о чем заботится не нужно - этот процесс можно привязать к процедуре динамической индикации. Программа просто будет читать их не с порта а с отдельных бит в сохраненной переменной. Так можно легко определять моменты нажатия/отпускания просто сверяясь с предыдущим состоянием кнопки.
Такой аппаратный дребезг не гарантирует отсутствие дребезга, он только уменьшает его вероятность.
Естественно, не гарантирует. Но то же самое можно сказать и о программных методах Поскольку в основе принципа лежит все та же назкочастотная фильтрация, а производится она аппаратно или программно - неважно. Но если правильно подобрать постоянную времени - чтобы и дребезг подавить, и не слишком затормозить реакцию схемы, работать будет и аппаратный, и программный способ. У меня RC-фильтр имеет постоянную времени как раз 10 мс. (100 кОм и 0.1 мкФ). Так какая тогда разница с твоим с точки зрения функциональности? Разумеется, вход должен иметь иметь гистерезис, в AVR это есть.
Единственный способ гарантированного подавления дребезга при сохранении минимального времени отклика - RS-триггер. Только вот двухпозиционные кнопки стоят дорого, да и ассортимент куда меньше, чем обычных.
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Программная-то как раз гарантирует, если период опроса больше чем длительность дребезга - никакие лишние импульсы через этот барьер не пройдут. RC-фильтр же, дает сглаженный но аналоговый сигнал с кнопки, гистерезиса может не хватить и какая-то иголочка да проберется, зачем оставлять проблеме лишний шанс? Да еще за счет лишних деталей.
Как иголка может пробраться через интегрирующую цепь с достаточно большой постоянной времени? Ты ставишь задержку 10 мс, допустим, что дребезг длится не дольше 10 мс, но это сам дребезг. Иголки гораздо короче, поэтому не пролезут, если я сделаю постоянную времени фильтра 10 мс.
Программная задержка не может гарантировать подавление дребезга - ты уверен, за 10 мс дребезг прекратится? Даже если это работает с той маленькой кнопкой, на которой ты отлаживал, не факт, что будет работать с большой (та же проблема и у ФНЧ), которую поставит кто-то, кто решит повторить проект.
В сущности, все программные методы - это все тот же ФНЧ (хотя они могут и не выглядеть таковыми на первый взгляд), и болезни у этого способа те же, что у ФНЧ - увеличение постоянной времени (задержки) дает больше шансов дребезг подавить, но будет ухудшать время реакции схемы на нажатие, так что можно будет и пропустить двойной клик (правда, для часов как мне кажется неактуально )
Мне кажется, 10 мс нормальная постоянная времени для обычных кнопок. Конечно, для здоровенной кнопки от магнитного пускателя или чего-нибудь подобного может и не хватить
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Если у кнопки дребезг доходит до 10мс, то такую кнопку надо менять однозначно. RC-фильтр плох тем что он аналоговый, и когда напряжение на его выходе достигает уровня срабатывания то нужна довольно маленькая помеха чтобы преодолеть гистерезис и несколько раз опрокинуть триггер шмидта на входе. С нуля конечно иголочка не пролезет, но в середине хода - запросто. Уж если на то пошло, то в качестве аппаратного подавления лучше всего одновибратор, но это уже оверинженеринг при наличии такого же по эффективности программного подавления дребезга.
Если у кнопки дребезг доходит до 10мс, то такую кнопку надо менять однозначно.
С нуля конечно иголочка не пролезет, но в середине хода - запросто.
Хм... менять однозначно? Когда я хотел сделать часы из ламп дневного света, была мысль не мутить гальваническую развязку силовой части, а чтобы юзера не убило током при настройке времени, просто поставить такие кнопки, которые используются в высоковольтных цепях - как раз здоровые, контакторные (ну, других и не было). Но это, разумеется, можно учесть при разработке - увеличить задержку или постоянную времени.
Вообще-то в триггере Шмитта помеху считать надо от противоположного порога, а не от середины гистерезиса. Я не знаю, какой в AVR гистерезис, но наверное уж он не микроскопический (а иначе какой смысл вообще делать?), и 0.6 В есть. Такая иголка не пролезет.
Вообще, практика показывает, что работает и программный и аппаратный способ, так что это дело вкуса. Может все дело в том, что мне просто лень программировать
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34 Сообщений: 1292 Откуда: Запад Беларуси
Рейтинг сообщения:0
Кто-нить может написать по этим фьюзам или не в них проблема? Часы стоят на месте и хоть тресни. Когда прикасаюсь пальцем до конденсатора - начинают что-то показывать с примерно 4Гц частотой...
Не, по фьюзам не подскажу Сам то оставляю по умолчанию, только частоту внутреннего RC ставлю по максимуму - 8 МГц. Но там еще как то задавать надо, то ли фьюзами, то ли регистром, какой частоты кварц подцеплен.
Попробуй прошить фьюзы так, чтобы запустить от внутреннего RC - там видно будет, в какую сторону копать.
Только с фьюзами осторожно - если запрограмишь RESET как простой вывод порта, потом перепрошить по SPI не сможешь. Я так "залочил" один МК по незнанию
_________________ У кошки четыре ноги - вход, выход, земля и питание. Но трогать ее не моги - получится замыкание.
Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34 Сообщений: 1292 Откуда: Запад Беларуси
Рейтинг сообщения:0
можно разлочить... по ходу проблема решена. запустились. дебильный кварц. теперь другая проблема. дикое мерцание. индикацию из прерывания придётся выбрасывать, или во второй таймер?..
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения