Да я ведь уже озвучил алгоритм, там не нужны двухбайтные счетчики - надо только по шагам разобраться с конфигурацией таймера и по шагам реализовать достаточно простой алгоритм.
Вывод на индикатор реализовать совсем просто - выдели массив из 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
можно разлочить... по ходу проблема решена. запустились. дебильный кварц. теперь другая проблема. дикое мерцание. индикацию из прерывания придётся выбрасывать, или во второй таймер?..
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения