Перейти к содержанию
    

Вопрос по калибровке внутрен. генератора с помощью 32768 кварца

Разбираюсь с вопросом по калибровке внутреннего генератора с помощью 32768 кварца

вот код из книги Шпака "Прграммирование на язеке С для микр. AVR и PIC"

чип ATmega169, частота Taimer1 8Mгц

void Calibration(void)
{
  unsigned char calibrate = 0;
  int temp;
  unsigned char tempL;
  CLKPR = _BV(CLKPCE); /* Устанавливаем разряд разрешения
                                        изменения кооэффициента масштабирования
                                        частоты генератора в регистре CLKPR
                                        микроконтр. Это специальные регистры ATmega169 */
  CLKPR = _BV(CLKPS1) | _BV(CLKPS0);  // Коэффициент деления 8
                                      // Внутрений RC 8Mгц / 8 = 1Мгц

  TIMSK2 = 0;       //сбрасываем разряды OCIE2A и TOIE2
  ASSR = _BV(AS2);  // Использование внешнегом кварца 32768 кГц для T/C2
  OCR2A = 200;      //Использование регистра сравнения А T/C2
  TIMSK0 = 0;       // Удаляем все источники прерывания
  TCCR1B = _BV(CS10); // Запускаем T/C1 без предделителя 
  TCCR2A = _BV(CS20);  // Запускаем T/C2 без предделителя
  while((ASSR & 0x01) | (ASSR & 0x04)); // Ожидание сброса  рязрядов TCN2UB и TCR2UB
  for(int i = 0; i < 10; i++)
    _delay_loop_2(30000);   // Ожидание стабилизации внешнего генератора
  while(!calibrate)
  {
//////////////////////// этот блок написан как рекомндует ATMEL///////////
    cli();                                                              // 
    TIFR1 = 0xFF;    // Удаление флагов                                 // 
    TIFR2 = 0xFF;                                                       //
    TCNT1H = 0;   // Обнуляем счетный регистр
    TCNT1L = 0;
    TCNT2 = 0;    // Обнуляем счетный регистр
    while ( !(TIFR2 && (1<<OCF2A)) ); // 
    TCCR1B = 0;                                                           //
    sei();                                                                //
////////////////////////////////////////////////////////////////////////////
    if ( (TIFR1 && (1<<TOV1)) ) // Если переполнение счетчика
    {
      temp = 0xFFFF;
    }
    else   // Если переполнения нет то считываем 
    { 
      tempL = TCNT1L;
      temp = TCNT1H;
      temp = (temp << 8);
      temp += tempL;
    }
    if (temp > 6250) //если внутренний генератор "спешит" ...
    {
      OSCCAL--;  //уменьшаем значение регистра калибровки 
    }
    else if (temp < 6120) // если отстает
    {
      OSCCAL++;  //увеличиваем
    }
    else
      calibrate = 1; // частота коректна
    TCCR1B = _BV(CS10);
  }
}

обьясните пожалуйста почему такая большая пауза для стабилизации внешнего кварца, нигде не нашел ответа,

и почему значение выбранное для коректировки генератора лежит в пределах 6120 - 6250 какак я понял 32768/200= 163,84 тогда получается 8000000/8/163,84 = 6103,5

и еще как синхронизировать внутрений генератор с помощью часового кварца если нет специальных регистров для коректировки

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А попроще сделать нельзя? Заводим 2 обработчика прерывания. 1 от внешнего кварца (RTC) с периодом 1s, второе от системного таймера с расчетным периодом 1ms (на "Target" частоте). В прерывании от системного таймера увеличиваем счетчик ms, в прерывании от RTC - смотрим сколько ms насчитали и корректируем OSCCAL.

 

int ms_cnt = 0;

ISR32768_1s()
{
    if (ms_cnt > 1000)
       OSCCAL -= 1;
    else if (ms_cnt < 1000)
       OSCCAL += 1;
    ms_cnt = 0;
}


ISR_1ms()
{
     ms_cnt++;
}

Остается только запустить два таймера и настроить прервывания от них соотв. образом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

обьясните пожалуйста почему такая большая пауза для стабилизации внешнего кварца, нигде не нашел ответа,

предполагается что калибровка начнется вскоре после старта системы, поэтому должно пройти время для возникновения и нарастания амплитуды колебаний кварцевого генератора 32768.

Добротность часового кварца очень высокая, а частота низкая. Примем Q=10000 , тогда амплитуда колебаний часового кварца дорастет до 67% за 0,3 секунды примерно.

а сколько секунд в _delay_loop_2(30000) ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

еще как синхронизировать внутрений генератор с помощью часового кварца если нет специальных регистров для коректировки
А что тогда OSCCAL для красоты?

http://sub.chipdoc.ru/html.cgi/txt/app/mic...R053.htm?fid=16

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

//////////////////////// этот блок написан как рекомндует ATMEL///////////
    cli();                                                              // 
    TIFR1 = 0xFF;    // Удаление флагов                                 // 
    TIFR2 = 0xFF;                                                       //
    TCNT1H = 0;   // Обнуляем счетный регистр
    TCNT1L = 0;
    TCNT2 = 0;    // Обнуляем счетный регистр
    while ( !(TIFR2 && (1<<OCF2A)) ); // 
    TCCR1B = 0;                                                           //
    sei();                                                                //
////////////////////////////////////////////////////////////////////////////

жуть какая-то, интересно где атмел так рекомендует ?

 

 

и почему значение выбранное для коректировки генератора лежит в пределах 6120 - 6250 какак я понял 32768/200= 163,84 тогда получается 8000000/8/163,84 = 6103,5
Видимо это поправка на "ветер" в связи с очень "синхронным" запуском таймеров :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

и почему значение выбранное для коректировки генератора лежит в пределах 6120 - 6250 какак я понял 32768/200= 163,84 тогда получается 8000000/8/163,84 = 6103,5

 

 

А я, так понимаю, это потому, что изменение OSCCAL на 1 дает изменение частоты около 2-х %: "Incrementing CAL6..0 by 1 will give a frequency increment of less than 2% in the frequency range 7.3 - 8.1 MHz."- из документации. Т.е. шаг изменения частоты примерно = 2%. 6250 - 6120 = 130, что примерно составляет 2%, и если вы попали в этот диапазон, то можно считать, что внутренний генератор откалиброван, т.к. точней установить частоту не получится.

 

Насчет кварца - ответ про добротность поддерживаю на 100%. :beer:

 

А вообще - не благодарное это дело калиброваться от 32768. Если нет сильной необходимости - не рекомендую, проблем потом можно поймать много.

Изменено пользователем interrupt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вообще - не благодарное это дело калиброваться от 32768. Если нет сильной необходимости - не рекомендую, проблем потом можно поймать много.

Неблагодарное - это да. Размер кода то растет :)

 

А вот про проблемы - утверждение голословное. Обоснуйте, раз уж так категорично высказываетесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

to singlskv

 

жуть какая-то, интересно где атмел так рекомендует ?

 

рекомендует в своей документации, РЕЖИМ РАБОТЫ Т\Cn В АСИНХРОНОМ РЕЖИМЕ

это я нашел в книге "Микроконтроллеры AVR семейств Tiny и Mega фирмы "ATMEL""

 

Всем спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

рекомендует в своей документации, РЕЖИМ РАБОТЫ Т\Cn В АСИНХРОНОМ РЕЖИМЕ

это я нашел в книге "Микроконтроллеры AVR семейств Tiny и Mega фирмы "ATMEL""

TCNT1H = 0; // Обнуляем счетный регистр

TCNT1L = 0;

TCNT2 = 0; // Обнуляем счетный регистр

 

Просто ответьте сами себе на вопрос, чему будет равен TCNT1 когда TCNT2 станет == 1 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

код не мой, это книга Шпака, но в документации Atmel именно такая последовательность рекомендуется

Изменено пользователем vpadm

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...но в документации Atmel именно такая последовательность рекомендуется
дайте ссылку где так рекомендуют

код не мой, это книга Шпака,
Понятно, но Вы вроде разобраться как это работает собирались ?

Подсказываю, сразу после:

TCNT2 = 0; // Обнуляем счетный регистр

буквально на следующем такте может оказаться:

TCNT == 1

 

т.о., в этом примере "сознательно" вносится погрешность в настройке генератора в 1/201(%),

те ~0,5%

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...