Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вопрос по калибровке внутрен. генератора с помощью 32768 кварца
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
vpadm
Разбираюсь с вопросом по калибровке внутреннего генератора с помощью 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
и еще как синхронизировать внутрений генератор с помощью часового кварца если нет специальных регистров для коректировки
vpadm
то-ли вопрос непонятен, то-ли некому ответить 1111493779.gif
defunct
А попроще сделать нельзя? Заводим 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) ?
demiurg_spb
Цитата(vpadm @ Dec 28 2008, 18:28) *
еще как синхронизировать внутрений генератор с помощью часового кварца если нет специальных регистров для коректировки
А что тогда OSCCAL для красоты?
http://sub.chipdoc.ru/html.cgi/txt/app/mic...R053.htm?fid=16
singlskv
Цитата(vpadm @ Dec 28 2008, 18:28) *
Код
//////////////////////// этот блок написан как рекомндует ATMEL///////////
    cli();                                                              //
    TIFR1 = 0xFF;    // Удаление флагов                                 //
    TIFR2 = 0xFF;                                                       //
    TCNT1H = 0;   // Обнуляем счетный регистр
    TCNT1L = 0;
    TCNT2 = 0;    // Обнуляем счетный регистр
    while ( !(TIFR2 && (1<<OCF2A)) ); //
    TCCR1B = 0;                                                           //
    sei();                                                                //
////////////////////////////////////////////////////////////////////////////
жуть какая-то, интересно где атмел так рекомендует ?


Цитата(vpadm @ Dec 28 2008, 18:28) *
и почему значение выбранное для коректировки генератора лежит в пределах 6120 - 6250 какак я понял 32768/200= 163,84 тогда получается 8000000/8/163,84 = 6103,5
Видимо это поправка на "ветер" в связи с очень "синхронным" запуском таймеров smile.gif
interrupt
Цитата(vpadm @ Dec 28 2008, 18:28) *
и почему значение выбранное для коректировки генератора лежит в пределах 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.gif

А вообще - не благодарное это дело калиброваться от 32768. Если нет сильной необходимости - не рекомендую, проблем потом можно поймать много.
Rst7
Цитата(interrupt @ Dec 29 2008, 01:12) *
А вообще - не благодарное это дело калиброваться от 32768. Если нет сильной необходимости - не рекомендую, проблем потом можно поймать много.

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

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

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

рекомендует в своей документации, РЕЖИМ РАБОТЫ Т\Cn В АСИНХРОНОМ РЕЖИМЕ
это я нашел в книге "Микроконтроллеры AVR семейств Tiny и Mega фирмы "ATMEL""

Всем спасибо!
singlskv
Цитата(vpadm @ Dec 29 2008, 15:26) *
рекомендует в своей документации, РЕЖИМ РАБОТЫ Т\Cn В АСИНХРОНОМ РЕЖИМЕ
это я нашел в книге "Микроконтроллеры AVR семейств Tiny и Mega фирмы "ATMEL""

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

Просто ответьте сами себе на вопрос, чему будет равен TCNT1 когда TCNT2 станет == 1 ?
vpadm
код не мой, это книга Шпака, но в документации Atmel именно такая последовательность рекомендуется
singlskv
Цитата(vpadm @ Dec 29 2008, 15:40) *
...но в документации Atmel именно такая последовательность рекомендуется
дайте ссылку где так рекомендуют
Цитата
код не мой, это книга Шпака,
Понятно, но Вы вроде разобраться как это работает собирались ?
Подсказываю, сразу после:
TCNT2 = 0; // Обнуляем счетный регистр
буквально на следующем такте может оказаться:
TCNT == 1

т.о., в этом примере "сознательно" вносится погрешность в настройке генератора в 1/201(%),
те ~0,5%
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.