ILYAUL 0 1 мая, 2012 Опубликовано 1 мая, 2012 · Жалоба Всем здравствуйте! Помогая студенту написал почти этот код , но вот взял и переделал (дождь , дача , делать нечего )добавив посчёт минут , но не врублюсь никак , почему при переходе частоты обновления динамической индикации с 85гц на 56гц секундомер начинает пропускать 1 секунду из 5 . На 85Гц- всё нормально.На 56 счёт не пропускает - т.е. 1 2 3 4 5 ..... 20 21 и т.д. Но даже на глаз видно что медленне работает . И по вкл. компьютерному секундомеру видно, что мой на 5 сек он показывает 4 на 10 сек 8 и т.д. А при 85 всё тютелька в тютельку. Там в коде есть , где меняю значение . И оно не скрыто под прерыванием . Да и обработчики прерывний одни из самых коротких из возможных - можно ещё и запоминания SREG убрать в одном без потерь. Их два - один по переполнению - секунды, второй по сравнению - динамика. Timer работает в режиме - Normal (Free timer) Прерывания одно от другого не зависяще и всегда считает от 0 до FF. Каждое чётное число TCNT - прерывание динамики для 85 гц или каждое 3-тье для 56 . В первом случае прерывание секунд совпадает с прерыванием динамики , но сбоя нет и так каждый раз . Во- втором случае , только каждое второе прерывание секунд совпадёт с динамикой и идёт сбой. ( Как я подозреваю) Прескалер Timerа настроен на деление до 512 гц соответствено частота динамики или 256/3 или 170/3. Три индикатора. Не врубаюсь где засада. second.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
fox2trot 0 3 мая, 2012 Опубликовано 3 мая, 2012 · Жалоба Бегло посмотрел и обратил внимание, временный регистр temp используется в обработке прерывания и в теле основной программы. Может и не в этом дело, но я бы поостерегся. Обжигался на подобном не раз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kool 0 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба Здравствуй, Илья С регистрами там вроде все нормально, а вот с работой с асинхронным таймером - на первый взгляд вроде как непорядок. После записи в любой из асинхронных регистров полагается подождать очитски соответствующего флога в ASSR. У тебя же она отсутствует после записи в OCR0. Но, с другой стороны, в OCR ты пишешь редко (реже, чем 2 такта часового кварца), поэтому с этим проблем быть не должно. Но поправить все же не мешало бы. OUT_TIMER: lsl temp outr PORTC,temp ld temp,-Y outr PORTA,temp inr temp,TCNT0 subi temp,-1; !!!! Если здесь поставить 2 - секундомер врёт outr OCR0,temp rjmp MAIN Остается только грешить на атмеловцев (хотя маловероятно) - на то, что при записи OCR странным образом сбивается прескалер таймера. Или на разводку платы - возможно, смена чатосты развертки изменила характер наводок на кварц и он начал нестабильно работать. Или же превышены допустимые токи по ногам питания/массы/не все ноги припаянны. А может, стоит попробывать сделать развертку на отдельном таймере? благо, у 128меги их еще есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба Здравствуй, Илья Привет, Саша! Сколько лет , сколько зим!! РАД!! Всё это писалось так , ради помощи и то тот код разительно отличается от этого. Этот появился по ошибке , не ту плату взял не дачу , ну и от нечего делать решил добавить подсчёт минут (первоначально их не было) . Вот тут и обнаружил такое поведение. Теперь по вопросам. После записи в любой из асинхронных регистров полагается подождать очитски соответствующего флага в ASSR. В инит так и делаю . Но!, тогда бы при записи любого числа , возникала бы какая -то лажа. Тут поэксперементировал ставил 1 , 2, 3, 4 , 5 - со всеми чётными числами секундомер врёт, с нечётными нет , про индикацию при бОльших числах не говорю и так понятно что моргает безбожно. А может, стоит попробывать сделать развертку на отдельном таймере? благо, у 128меги их еще есть. Да как-то изначально я делал на одном таймере , так как его ресурсов вполне хватает и на индикацию и на подсчёт секунд . Задействовать ради секундомера ещё ресурсы mega128 - смысла не вижу . А код писался на то , что было под рукой и лежало в запаснике , а так он в итоге перекочевал практически один в один на Mega8 . Бегло посмотрел и обратил внимание, временный регистр temp используется в обработке прерывания и в теле основной программы. Может и не в этом дело, но я бы поостерегся. Обжигался на подобном не раз. Вы наверно забывали сохранять его в стек - push и pop, есть и ещё места куда его можно спрятать , но не вовсех процессорах . А регистров, чем меньше используется тем лучше, их и так мало. Вдруг захочется , что либо добавить в проект , вот тогда ресурсы и пригодятся.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kool 0 4 мая, 2012 Опубликовано 4 мая, 2012 · Жалоба Порылся еще в нете и нашел схожую тему 5-летней давности на нашем же форуме: ATmega timer2 в асинхронном режиме. После прочтения темы посмотрел эррату на мегу128 - проблема до сих пор существует для всех ревизий кристалла от F до М. Ниже выдержка из эрраты: 2. Interrupts may be lost when writing the timer registers in the asynchronous timer The interrupt will be lost if a timer register that is synchronous timer clock is written when the asynchronous Timer/Counter register (TCNTx) is 0x00. Problem Fix/Workaround Always check that the asynchronous Timer/Counter register neither have the value 0xFF nor 0x00 before writing to the asynchronous Timer Control Register (TCCRx), asynchronous Timer Counter Register (TCNTx), or asynchronous Output Compare Register (OCRx). В твоем коде воспользоваться данным воркэраундом не удастся (будет заметно подмигивание) Остается только посоветовать либо оставить все на 85Гц, либо отказаться от периодического изменения OCR: 1. настроить прескалер таймера на 1 2. Настроить таймер на режим CTC (автосброс при срабатывании output compare, WGM01 = 1, WGM00 = 0 ), в OCR занести значение (64-1). Таким образом, у нас прерывание про сравнению будет срабатывать с частотой 32768/64 == 512Гц. При каждом третьем входе в это прерывание выставлять флаг fl_Display (частота развертки 512/3/3==57Гц), а при каджом 512 входе - флаг fl_Second. 3. понятное дело, убрать обновление OCR0 из OUT_TIMER и отключить прерывание по переполнению. ЗЫ реинициализацию регистра count (если он останется после переделки) лучше осуществлять в самом прерывании. Это, конечно, +1 такт к прерыванию, но читабельность программы существенно улучшится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 5 мая, 2012 Опубликовано 5 мая, 2012 · Жалоба Порылся еще в нете и нашел схожую тему 5-летней давности на нашем же форуме: ATmega timer2 в асинхронном режиме. После прочтения темы посмотрел эррату на мегу128 - проблема до сих пор существует для всех ревизий кристалла от F до М. Да похоже я наступил на теже грабли . Вечером попробую Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ILYAUL 0 7 мая, 2012 Опубликовано 7 мая, 2012 · Жалоба Нашёл ещё один путь - там они никогда не пересекутся Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться