Мелкие вопросы по МК и ПЛИС.
Ну вот таймер отсчитал положенное кол-во импульсов, сработало прерывание, и в обработчике на тактовой частоте пропали 3 периода пока таймер обнулялся.
- Реклама
Вы немного не так считаете. Когда прерывание возникло, таймер уже обнулился сам. Пока мы войдем в прерывание пройдет 8 тактов!, прежде чем начнется выполнение обработчика - 4 такта на реакцию, и 4 такта на сохранение адреса возврата в стеке. потом только таймер начнет обнуляться за 3 такта еще раз.
Вообще, эти все "блохи" решаются просто - введи коррекцию хода часов. Каждое прерывание накапливай счетчик, когда он будет равен определенному значению - прибавь к времени ЕЩЕ ОДИН квант времени, или просто пропусти это прерывание. Прибавление кванта ускорит ход, вычитание замедлит. Чем больше значение счетчика при котором выполняется сие действие, тем ближе коррекция времени к нулю. Если будешь добавлять или пропускать каждый второй такт - это будет коррекция хода +-50%. Несложно просчитать через сколько тактов надо пропустить/добавить чтобы ускорить или замедлить ход часов на необходимую величину.
Вообще, эти все "блохи" решаются просто - введи коррекцию хода часов. Каждое прерывание накапливай счетчик, когда он будет равен определенному значению - прибавь к времени ЕЩЕ ОДИН квант времени, или просто пропусти это прерывание. Прибавление кванта ускорит ход, вычитание замедлит. Чем больше значение счетчика при котором выполняется сие действие, тем ближе коррекция времени к нулю. Если будешь добавлять или пропускать каждый второй такт - это будет коррекция хода +-50%. Несложно просчитать через сколько тактов надо пропустить/добавить чтобы ускорить или замедлить ход часов на необходимую величину.
Еще один момент, при инициализации регистра компаратора нужно вычесть единицу, т.к. счетчик ноль тоже считает и тогда получается у нас не 62500, а 62501.
Код: Выделить всё
ldi Temp,high(62500-1) ;таймер считает от 0 до 62499
out OCR1AH,Temp
ldi Temp,low(62500-1)
out OCR1AL,Temp
Счетчик работает на деленной частоте, и увеличится он только после 256 машинных тактов, такты на вход в обработчик можно игнорировать.Alexeyslav писал(а):Вы немного не так считаете. Когда прерывание возникло, таймер уже обнулился сам. Пока мы войдем в прерывание пройдет 8 тактов!, прежде чем начнется выполнение обработчика - 4 такта на реакцию, и 4 такта на сохранение адреса возврата в стеке. потом только таймер начнет обнуляться за 3 такта еще раз.
А какая нам вообще разница сколько там тактов проходит после того как таймер досчитал до нужного значения. Всё это (реакция на переполнение, обработка прерывание, стек, индикация) дает лишь задержку при отображении на дисплей. Да и она не такая уж большая т. к. обрабатывается все на тактовой частоте. Главное что таймер отсчитал сколько нужно и начал заново, а за время пока он считает все процедуры обработаются.
А за 62500-1 спасибо - реальный косяк, исправил. Считай половину погрешности отрезали.
А за 62500-1 спасибо - реальный косяк, исправил. Считай половину погрешности отрезали.
- Реклама
Нельзя. Поскольку когда сбрасываешь счетчик, сбрасывается и предделитель. Если его сбросить в состоянии +11 тактов, следующее событие возникнет на 11 тактов позже. Причем такты - это такты контроллера, а не такты таймера после предделителя. Каждый такт таймера будет 256+11 тактов кварца.
Если не сбрасывать таймер в прерывании принудительно конечно же такой проблемы нет.
Если не сбрасывать таймер в прерывании принудительно конечно же такой проблемы нет.
Я уже убрал это принудительное обнуление в обработчике, так что по идее эти 8 тактов не влияют.Alexeyslav писал(а):Нельзя. Поскольку когда сбрасываешь счетчик, сбрасывается и предделитель. Если его сбросить в состоянии +11 тактов, следующее событие возникнет на 11 тактов позже. Причем такты - это такты контроллера, а не такты таймера после предделителя. Каждый такт таймера будет 256+11 тактов кварца.
Если не сбрасывать таймер в прерывании принудительно конечно же такой проблемы нет.
Не думаю, что предделитель тоже сбрасывается, не уверен.
Во-вторых в программе таймер в режиме СТС, счетчик сбрасывается при совпадении и обнулять его конечно же повторно нельзя.
Во-вторых в программе таймер в режиме СТС, счетчик сбрасывается при совпадении и обнулять его конечно же повторно нельзя.
когда устанавливаешь принудительное значение таймера - предделитель сбрасывается, это описано в даташите.
Ещё такой вопрос. Я там в проге целый регистр отвел для магающего двоеточия. Не слишком ли это жирно? Может есть другой способ узнавать о том что наступило прерывание?
- Сообщения: 129
- Зарегистрирован: Ср янв 18, 2012 19:37:10
Здравствуйте, возник вопрос по работе с EEPROM. Работаю в WinAvr. Сейчас я начальные значения в МК записываю так
Это, наверное, не есть правильно. Вопрос такой:
1. Правильно ли я делаю, или нужно по другому
2. А как начальные значения записать скажем в ячейку EEPROM F3? Городить массив как выше очень не хочется.
Так тоже не пойдет, потому что будет перезаписываться все время. А мне нужна только начальная установка, потом эта ячейка будет перезаписываться новыми значениями и запоминаться последнее состояние.
почитал здесь, http://radiokot.ru/forum/viewtopic.php?f=20&t=37981 но мало что понял. Тут советуют общаться не к ячейкам напрямую, а через EEMEM.
А как тогда записывать скажем в ячейку 3?
Спасибо
Код: Выделить всё
uchar eePrg[66] EEMEM = {
{0xFF},
{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00}
};1. Правильно ли я делаю, или нужно по другому
2. А как начальные значения записать скажем в ячейку EEPROM F3? Городить массив как выше очень не хочется.
Код: Выделить всё
EEPROM_write(EEPR_FRQ_ADDR,FreqNum);почитал здесь, http://radiokot.ru/forum/viewtopic.php?f=20&t=37981 но мало что понял. Тут советуют общаться не к ячейкам напрямую, а через EEMEM.
А как тогда записывать скажем в ячейку 3?
Спасибо
Там же приведен пример в этом посте.
Вообще если хотите записать только в одну ячейку к ней и обращайтесь.
Вроде так смещение делается.
Вообще если хотите записать только в одну ячейку к ней и обращайтесь.
Код: Выделить всё
eeprom_write_byte(&eePrg[3]); Проблемы ищите на ровном месте... на ассемблере это очень просто реализуется, даже в даташите есть пример с записью в EEPROM на ассемблере и на С.
- Сообщения: 129
- Зарегистрирован: Ср янв 18, 2012 19:37:10
Да я как бы написал и объяснил, почему мне стандартный вариант из даташита не подходит
А какой это метод записи в EEPROM, не соблюдает алгоритм записи стандартного? На вход подается адрес ячейки и данные для записи. Какое отличие может быть у нестандартного?
Собственно, если вам надо хранить какие-то данные которые часто меняются но их надо запоминать при обесточивании - храните их в RAM!!! EEPROM здесь вообще не при делах, она задействуется только при исчезновении питания и начальной загрузке.
Собственно, если вам надо хранить какие-то данные которые часто меняются но их надо запоминать при обесточивании - храните их в RAM!!! EEPROM здесь вообще не при делах, она задействуется только при исчезновении питания и начальной загрузке.
- Сообщения: 129
- Зарегистрирован: Ср янв 18, 2012 19:37:10
Ну так я и спрашиваю, правильно я делаю начальную загрузку или нет? А насчет хранения в RAM так она вроде как быстрее изнашивается чем EEPROM. Разве нет?
RAM? Изнашивается?
Это такое же ОЗУ (оперативная память), как у вас на компьютере.
Это такое же ОЗУ (оперативная память), как у вас на компьютере.
ЗдрастеAlexeyslav писал(а):Собственно, если вам надо хранить какие-то данные которые часто меняются но их надо запоминать при обесточивании - храните их в RAM!!! EEPROM здесь вообще не при делах, она задействуется только при исчезновении питания и начальной загрузке.
- Сообщения: 129
- Зарегистрирован: Ср янв 18, 2012 19:37:10
Друзья, ну ответьте, кто - нибудь. Правильно я делаю начальную инициализацию EEPROM или нет??? И еще, а как размазывать данные в ячейках памяти? Их же как-то отслеживать надо.


