Добрый день! Написал программку для проигрывания одноголосной мелодии. В принципе, адаптировал кусок с книги Белова. Контроллер - Tiny2313. Работает от внутреннего генератора 4МГц. Но почему-то глотает некоторые ноты. Причем, чаще одни и те же. Как будто запаздывает начало ноты, а воспроизводится с середины. Остальные играют хорошо. Может кто сталкивался. Прошу прощения что на Ассемблере.
;======М У З Ы К А========
m3: mov YL, count ; счетчик мелодий -> YL ldi ZL, low(tabm*2) ;в Z -> начальный адрес "tabm" ldi ZH, high(tabm*2) ; rcall addw ; сложение смещения по счетчику и ; начального адреса "tabm"
lpm XL, Z+ ; извлечение из "tabm" lpm XH, Z
;---------- m4: mov ZH, XH ; пересылка в рабочий регистр mov ZL, XL ;
m5: ldi b,255 ldi d,255
ldi e, 0 ; установка таймера1 out tccr1a, e
lpm temp, Z ; пересылка данных, находящихся ; по адресу в Z -> temp cpi temp, 0xFF ; последняя нота???? breq m6 ; выход
andi temp, 0x1F ; выделяем код тона (И=И) mov fnota, temp ; кидаем его в fnota lpm temp, Z+ ; первую ноту в temp rol temp ; 4-кратный круговой сдвиг кода ноты rol temp ; rol temp ; rol temp ;
andi temp, 0x07 ;выделение кода длительности mov dnota, temp ; помещаем его в "dnota"
rcall nota
rjmp m5 m6: cbi portB,3; заглушка 2 для порта (пищалка не такая как нужно) ret
Причем, заметил что если перепад между тональностью небольшой (к примеру, гамма) - то все ноты играют чётко. А в мелодии, если нота резко выделяется вверх тоном, то именно она начинает играть с задержкой почти в половину длительности.
Добавлено after 1 minute 25 seconds: Как будто долго выбирает из памяти.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
скоросои мало надо такт мег 12 делать а лучше 25мег
_________________ ZМудрость(Опыт и выдержка) приходит с годами. Все Ваши беды и проблемы, от недостатка знаний. Умный и у дурака научится, а дураку и .. Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Добавлено after 1 hour 44 minutes 16 seconds: Все, я понял! Во первых неправильно написал. У меня внутренний тактовый 8МГц. В общем, чтобы обеспечивать при помощи счетчика Т0 частоту 1Гц, я понизил общую тактовую до 250кГц. Вот он и стал заикаться при проигрывании музыки. Попробовал уменьшить коэффициент деления с 32 до 16 (соответственно поменяв коэффициенты в таблицах). Все работает как автомат Калашникова Теперь задача - как сделать чтобы и музыка работала стабильно и таймер отсчитывал секунды. Создать программный счетчик? Может есть какие-нибудь ещё варианты?
ты музыку играшь ДАЖЕ без кварца??? о какой стабилности может идтиречь??? НУ ВЫ БОЛИН ДАЕТЕ
_________________ ZМудрость(Опыт и выдержка) приходит с годами. Все Ваши беды и проблемы, от недостатка знаний. Умный и у дурака научится, а дураку и .. Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
Добрый день! Подскажите, пожалуйста, как может влиять то, в каком месте расположен блок программы с закодированными мелодиями на возникновение разного рода глюков при проигрывании музыки? Если я его перемещаю в самый конец, то музыка превращается в какие-то непонятные звуки. Если перемещаю ближе к основному циклу мелодия играет, но некоторые ноты глючат. Если располагаю почти сразу за основным циклом - все играет нормально. Может быть в этом была причина? Почему это может происходить?
Программу не смотрел и не разбирался, но по описанным симптомам, что-то похожее на вылет за приделы памяти... Смотрите, как организована у вас отсылка к данным в массиве с нотами. Т.е. может адресация страдает. Относительные переходы и все такое. ))))
Карма: 13
Рейтинг сообщений: 163
Зарегистрирован: Сб дек 22, 2012 08:17:42 Сообщений: 744 Откуда: Караганда, Казахстан
Рейтинг сообщения:0
Точно, там не сохраняются SREG и регистр e=r21. Не вникал, может этот регистр и должен управляться из прерывания, но про SREG топикстартер точно забыл.
2 Vjatheslav: Я подобные программы делаю так.
Во-первых выбираю квант времени. Он должен быть достаточно маленьким, чтобы обеспечить все нужные значения времени и, в то же время, достаточно большим, чтобы за это время можно было выполнить вменяемое количество команд, допустим, 1000, лучше - 10000. Допустим, для 8-й меги с тактовой частотой 8 МГц квант в 1 мс - это около 8000 команд за квант, очень неплохо.
Инициализирую таймер на многократные прерывания с периодом, равным кванту. Не все таймеры могут это делать аппаратно, такие приходится подправлять в прерывающей программе. В частности у 8-й Меги нулевой таймер не имеет аппаратной перезагрузки количества тиков до прерывания, приходится его каждый раз обновлять из прерывающей программы. Саму прерывающую программу делаю предельно короткой - отметил факт произошедшего прерывания в специально выделенной ячейке ОЗУ, допустим, с меткой TQOK (Time Quantum OK, исходно в ней лежит ноль, а программа прерывания заносит туда единицу), далее (возможно) подправил таймер и RETI. Да, естественно, не забыть сохранить и в конце восстановить рабочий регистр и SREG.
Во-вторых, строю таблицу задач. Каждая строка имеет два-три поля: (1) счетчик квантов, т.е. количество квантов времени, оставшееся до запуска этой задачи, (2, возможно) какие-то флажки, типа "задача активна" или что-то подобное, и, наконец, адрес подпрограммы, выполняющей эту задачу.
Ну, и, собственно, программа. Все ожидания делаются в основной задаче. Основной цикл состоит в периодической проверке того самого флага TQOK. Конкретно - закрываем прерывания и проверяем TQOK. Если там ноль, открываем прерывания и засыпаем, затем идем в начало цикла. Если же в TQOK не ноль, очищаем его и открываем прерывания.
Далее проходим по таблице задач. Для каждой задачи первым делом проверяем флаг активности (если он предусмотрен), неактивные задачи просто пропускаем. Активной же задаче уменьшаем на единицу счетчик квантов и смотрим не ноль ли получился. Если ноль, вызываем подпрограмму этой задачи. После проверки и (возможно) исполнения всех задач, уходим на начало основного цикла, где закроют прервыания и проверят TQOK. Все!
Это получилась простейшая примитивная таймерная RTOS. Задачи в ней должны быть предельно короткими - что-то включить, что-то выключить, что-то подкрутить, и выйти. Тем не менее, поставленную задачу она решает влет.
Допустим, динамическая индикация. Выдал на пины нужные коды, записал в свой счетчик квантов время (количество квантов), которые следует светить это состояние, и выходи. Прйдет запрошеннов время, тебя снова вызовут, выдавай на пины следующий набор кодов, и вперед!
Часы. Раз в секунду запускаем программу часов, которая, собственно, и считает время.
Будильник. Раз в минуту запускаем задачу будильника, которая сравнивает показания часов и установленное время побудки. При совпадении, активизирует задачу "проиграть мелодию", а именно, задает ей адрес начала мелодии, заносит ей в счетчик квантов единичку (запуск на следующем кванте) и ставит ей флаг "Задача активна". Получается, здесь этот флаг нужен, то есть таблица задач будет иметь три поля. Что бывает, в общем-то, далеко не всегда.
Проигрывание мелодии. Смотрим, последняя у нас нота, или нет. Если последняя, снимаем свой флажок "задача активна" и выходим, иначе отсылаем нужный код в таймер Т1, отсылаем себе в счетчик квантов код длительности этой ноты, вестимо, в квантах, и можно выходить.
При желании можно сделать отдельную задачу "Злобный будильник", которую должен будет активировать основной будильник, опять же на следующем кванте, вместо проигрывания мелодии. Злобный будильник запускает мелодию и ставит свой повтор через, допустим, 5 мин. При повторном запуске можно выдать и мелодию позлее и погромче, и все, на что хватит фантазии.
Да, при такой организации, если не принять довольно сложных мер, задачи ничего не могут хранить в регистрах, также сложно использование динамической памяти, но, учитывая, что памяти у 2313 и так копейки, ее следует распределить статически, у каждой задачи свой набор статических переменных, и все. При запуске задача поднимает из них в регистры то, что надо, по окончании сохраняет что надо в них же, и выход. Все регистры при входе в задачу можно считать свободными, кроме, может быть указателя на обрабатываемую строку таблицы задач. Впрочем, никто не мешает главному циклу сохранить этот указатель перед вызовом задачи и восстановить его после возврата из задачи.
_________________ Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Кстати, сейчас только глянул, и в глаза бросилось: addw: push YH lsl YL ldi YH,0 add ZL, YL add ZH, YH
pop YH ret Vjatheslav, У вас неправильно вычисляется адрес, поэтому "проигрывается" код из программной области. Вы играете не ноты, а саму программу. Поменяйте так: adc ZH, YH
_________________ Я всё-всё узнAю и стану профессором.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 42
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения