Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Xmega не запускается от кварцевого резонатора.
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
misyachniy
Собрал первую плату на Xmega.
Программирование и переключение на внутренний 32 МГц генератор работает.
Переключение на кварцевый генератор никак.

В начале проверил/перепроверил аппаратуру.
Прозвонил все выводы XTAL, специально приобрел конденсаторы 15пФ.
Перепробовал три разных кварца из разных партий.
Все равно генерации нет, на одном выводе логический ноль (~0,1В), на втором единица(~3,3В)

Перечитал документацию, нашел особенность, защиты тактирования.
Взял примеры с этого сайта и с других.
Не менее 6 разных вариантов.
CODE
/* От RC генератора работает

CLKSYS_Enable( OSC_RC32MEN_bm );
CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_2_gc );
do {} while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 );
CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc );

*/

/*
// симулятор останавливается на третьем операторе - тактирования нет

CLKSYS_XOSC_Config( OSC_FRQRANGE_9TO12_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );
CLKSYS_Enable( OSC_XOSCEN_bm );
while( CLKSYS_IsReady( OSC_XOSCRDY_bm ) == 0 );

CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_XOSC_gc );
*/


// симулятор останавливается на третьем операторе - тактирования нет
/*
OSC.XOSCCTRL = 0xCB; // выбор внешнего генератора с временем запуска 16 тыс. CLK и частотой 12-16 МГц
OSC.CTRL = 0x08; // разрешение работы внешнего генератора
while((OSC.STATUS & 0x08) == 0 ); // ожидание появления в регистре статуса бита включения синхронизации от внешнего генератора

OSC.PLLCTRL = 0xC3; // настройка блока PLL на синхронизацию от внешнего источника и 3-х кратоное умножение
OSC.CTRL = OSC.CTRL | 0x10; // разрешение работы блока PLL
while((OSC.STATUS & 0x10) == 0 ); // ожидание появления в регистре статуса бита включения блока PLL
CCP = 0xD8; // включение защиты от изменения регистров ввода-вывода на время изменения синхронизации
CLK.CTRL = 0x04; // настройка системной синхронизации от блока PLL
OSC.CTRL = OSC.CTRL & 0xFE; // отключение системной синхронизации от внутреннего RC-генератора частотой 2 МГц
*/

/*
// симулятор останавливается на четвертом операторе - тактирования нет
CCP = 0xD8;
OSC.XOSCCTRL = 0xCB;
OSC.PLLCTRL = 0xC3;
OSC.CTRL = 0x08;
while((OSC.STATUS & 0x08) == 0);
OSC.CTRL = OSC.CTRL | 0x10;
while((OSC.STATUS & 0x10) == 0 );
CLK.CTRL=0x04;
OSC.CTRL = OSC.CTRL & 0xFE;
*/

// симулятор останавливается на третьем операторе - тактирования нет
/*
OSC.XOSCCTRL=0xCB; // 16MHz, start time 16000 clk
OSC.CTRL= 0x08; // enable external clock
while((OSC.STATUS & 0x08) == 0 ); // ожидание появления в регистре статуса бита включения синхронизации от внешнего генератора
OSC.PLLCTRL = 0xC2; // настройка блока PLL на синхронизацию от внешнего источника и 2-х кратоное умножение
OSC.CTRL = OSC.CTRL | 0x10; // разрешение работы блока PLL
while((OSC.STATUS & 0x10) == 0 ); // ожидание появления в регистре статуса бита включения блока PLL
CCP=0xD8; // load protect IO
CLK.CTRL = 0x04; // настройка системной синхронизации от блока PLL
OSC.CTRL = OSC.CTRL & 0xFE; // отключение системной синхронизации от внутреннего RC-генератора частотой 2 МГц
*/

/*

// симулятор останавливается на третьем операторе - тактирования нет
OSC.XOSCCTRL =0x4b;
OSC.CTRL = 0x08;
while (!(OSC.STATUS &OSC_XOSCRDY_bm));
CCPWrite(&CLK.CTRL,0x03);
OSC.CTRL = 0x08;
*/

/*
// симулятор останавливается на третьем операторе - тактирования нет

CLKSYS_XOSC_Config( OSC_FRQRANGE_2TO9_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );
CLKSYS_Enable( OSC_XOSCEN_bm );
do {} while ( CLKSYS_IsReady( OSC_FRQRANGE_9TO12_gc ) == 0 );
CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_XOSC_gc );
CLKSYS_Disable( OSC_RC2MEN_bm );
CLKSYS_PLL_Config ( OSC_PLLSRC_XOSC_gc, 4);
CLKSYS_Enable( OSC_PLLEN_bm );
CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );
CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );
*/

Пробовал менять оптимизацию по скорости и размеру (IAR 6.10) толку никакого.
Наверное не там копаю.
ZASADA
при программировании нужные птички в фузах поставили?
zombi
Мой код для иксмег (ASM). Резонатор 8MHz+PLLx4. На xmega128A1 работает.

CODE
;============== INIT SYSCLK (EXT TOSC)
CLK_init:
ldi RTMPA,0b01001011
sts (OSC_XOSCCTRL),RTMPA ; extCLK set

lds RTMPA,(OSC_CTRL)
ori RTMPA,OSC_XOSCEN_bm
sts (OSC_CTRL),RTMPA ; enable extCLK

lds RTMPA,(OSC_STATUS) ; wait extCLK ok
sbrs RTMPA,OSC_XOSCRDY_bp
rjmp PC-3

ldi RTMPA,OSC_PLLSRC_XOSC_gc|4
sts (OSC_PLLCTRL),RTMPA ; PLL set (8MHz extCLK x 4)=32MHz

lds RTMPA,(OSC_CTRL)
ori RTMPA,OSC_PLLEN_bm
sts (OSC_CTRL),RTMPA ; enable PLL

lds RTMPA,(OSC_STATUS) ; wait PLL ok
sbrs RTMPA,OSC_PLLRDY_bp
rjmp PC-3

ldi RTMPA,CCP_IOREG_gc
sts (CPU_CCP),RTMPA ; enable change SYSclk
ldi RTMPA,CLK_SCLKSEL_PLL_gc
sts (CLK_CTRL),RTMPA ; set SYSclk
ret
;

Прерывания запрещены.
_Артём_
Цитата(misyachniy @ Aug 6 2013, 18:36) *
В начале проверил/перепроверил аппаратуру.
Прозвонил все выводы XTAL, специально приобрел конденсаторы 15пФ.


Почему именно 15пФ? Кварц какой?

Цитата(misyachniy @ Aug 6 2013, 18:36) *
Код
/* От RC генератора работает
        */        
        
/*      
// симулятор останавливается на третьем операторе - тактирования нет
        
        CLKSYS_XOSC_Config( OSC_FRQRANGE_9TO12_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );
        CLKSYS_Enable( OSC_XOSCEN_bm );
        while( CLKSYS_IsReady( OSC_XOSCRDY_bm ) == 0 );[/quote]


                Что-то странное - симулятору-то что? Он просто циклы отрабатывает. Может тип МК неправильно выбран? Какой МК, кстати?
[quote name='misyachniy' date='Aug 6 2013, 18:36' post='1182860']

CLKSYS_XOSC_Config( OSC_FRQRANGE_2TO9_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );


        CLKSYS_Enable( OSC_XOSCEN_bm );
    do {} while ( CLKSYS_IsReady( [b]OSC_FRQRANGE_9TO12_gc[/b] ) == 0 );
*/


В этом примере маска не та, что нужно.

Такой код у меня работает (взят из апноты от Атмела):

Код
CLKSYS_XOSC_Config( OSC_FRQRANGE_2TO9_gc,
            false,
            OSC_XOSCSEL_XTAL_16KCLK_gc);
        CLKSYS_Enable( OSC_XOSCEN_bm );
        do {} while ( CLKSYS_IsReady( OSC_XOSCRDY_bm ) == 0 );
        CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc);

        CLKSYS_PLL_Config( OSC_PLLSRC_XOSC_gc, 8);
        CLKSYS_Enable( OSC_PLLEN_bm );
        CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );
        do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );
        CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );
        CLKSYS_Disable( OSC_RC32MEN_bm );
        CLKSYS_Disable( OSC_RC2MEN_bm );




Цитата(misyachniy @ Aug 6 2013, 18:36) *
Пробовал менять оптимизацию по скорости и размеру (IAR 6.10) толку никакого.
Наверное не там копаю.


Наверное не туда, оптимизация врядли виновата. Скорей всего в плате проблема.


Фузы врядли влияют, разве только TOSCSEL может быть может повлиять на работу кварца (если он есть в вашем МК).

Xenia
Цитата(zombi @ Aug 6 2013, 22:42) *
Мой код для иксмег (ASM). Резонатор 8MHz+PLLx4. На xmega128A1 работает.

zombi - уникум, который программирует X-Мегу на ассемблере. sm.gif

А это мой код, для тех, кто программирует на C/C++. Резонатор 8 МГц "разогоняется" до 32 МГц.

Код
// Clock Source Select
  CCP = CCP_IOREG_gc;                       // 0xD8 - protected IO register
  CLK.PSCTRL = 0x00;                        // Select prescaler A division ratio "1", no division

  OSC.XOSCCTRL = 0x4B;                      // FRQRANGE[1:0] set to (2 MHz - 9 MHz), XOSCSEL[3:0] set to (0.4 - 16 MHz XTAL, 16K CLK)
  OSC.CTRL = OSC_XOSCEN_bm;                 // 0x08 - external oscillator enable
  OSC.XOSCFAIL = OSC_XOSCFDIF_bm | OSC_XOSCFDEN_bm;  // 0x03 - failure detection interrupt flag and set XOSCFDEN: failure detection enable
  while( !(OSC.STATUS & OSC_XOSCRDY_bm));   // 0x08 - wait until external clock source is stable and then select it for PLL clock input

  CCP = CCP_IOREG_gc;                       // 0xD8 - protected IO register
  CLK.CTRL = CLK_SCLKSEL_XOSC_gc;           // 0x03 - XOSC - external oscillator or clock

  OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 4;     // external clock source + multiplication factor 4 (4 x 8MHz = 32MHz)
  while( !(OSC.STATUS & OSC_XOSCRDY_bm));   // 0x08 - wait until the clock reference source (XTAL clock) is stable: PLLRDY: PLL ready to be set
  OSC.CTRL |= OSC_PLLEN_bm;                 // 0x10 - enable the PLL: Set PLLEN: PLL Enable
  while( !(OSC.STATUS & OSC_PLLRDY_bm));    // 0x10 - wait until the PLL clock is stable: PLLRDY: PLL ready to be set

  CCP = CCP_IOREG_gc;                       // 0xD8 - protected IO register
  CLK.CTRL = CLK_SCLKSEL_PLL_gc;            // 0x04 - Phase Locked Loop
Navovvol
А я делаю вот так :
Код
void system_clocks_EXTERNAL8x4(void)
{
    OSC_XOSCCTRL=0xCB;//OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;// внешний 8000_000 kHz кварц
    OSC_CTRL=0x08;//OSC_CTRL|=OSC_XOSCEN_bm;// Вкл. внешний кварц
    while ((OSC_STATUS & OSC_XOSCRDY_bm)==0);// ожидание инициализация
    OSC_PLLCTRL=OSC_PLLSRC_gm|PLL_multiplay;////OSC_PLLSRC_gm=0xC0-внешний источник тактир-ия. PLL_multiplay- множитель 4
    OSC_CTRL=0x19;//OSC_CTRL|=OSC_PLLEN_bm;// включение блока PLL
    while ((OSC_STATUS & OSC_PLLRDY_bm)==0);// // ожидание инициализация PLL
    asm ("ldi r16,0xd8");
    asm ("ldi r17,0x04");
    asm ("out 0x34,r16");
    asm ("sts 64,r17");
    OSC_CTRL=0x18;
}

Кварц туда втыкаете ? может он ваще не на тех пинах тактирует.
ILYAUL
Цитата
zombi - уникум, который программирует X-Мегу на ассемблере


Код zomdi будет работать всегда и везде , независимо от компиляторов и их ключей
zat
Для AVR Studio 6.1 + ASF делал вот так:

Код
#define CPU_CLOCK    8000000UL
#define F_CPU (CPU_CLOCK * CONFIG_PLL0_MUL)

#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLL
#define CONFIG_PLL0_SOURCE          PLL_SRC_XOSC          /*для внешнего генератора*/

#define CONFIG_PLL0_MUL             10
#define CONFIG_PLL0_DIV             1


И от внешнего и от внутреннего вроде работает.
zombi
Цитата(Xenia @ Aug 6 2013, 22:16) *
zombi - уникум, который программирует X-Мегу на ассемблере. sm.gif
Цитата(ILYAUL @ Aug 7 2013, 09:24) *
Код zomdi будет работать всегда и везде , независимо от компиляторов и их ключей

Да, есть такое дело. biggrin.gif

2 misyachniy, ну что запустил?
misyachniy
Программисты в очередной раз побили "железятников".

Я прозванивал цепи "патентованной" звонилкой с выходным напряжением не более 200 милливольт.
И она молчала.
Померял тестером - вывод XTAL1 имеет сопротивление 30 Ом относительно общего провода в обеих направлениях.
"Скрайбирование" между выводами не помогло.
Пусть работает от внутреннего генератора.

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

Дмитрий_Мигачев
А вот я использую для програмиирования среду Atmel Studio 6. Очень долго не мог заставить работать внешний кварц. В симуляторе и по отладке через JTAG наблюдал, что перед тем как регистр CLK.CTRL изменится на тактирование от PLL происходил сброс в 0 в CCP[0]. Долго не мог понять почему так, на AVRFreaks вычитал что необходимо ставить оптимизацию -Os и это помогло. Я так понимаю, теперь чтобы выбрать другую оптимизацию мне нужно этот участок кода писать на ассемблере?
Сам код:
Код
OSC.XOSCCTRL = xoscctrl_reg;
OSC.CTRL = OSC_XOSCEN_bm;
while( !( OSC.STATUS & OSC_XOSCRDY_bm ) );
OSC.PLLCTRL = pllctrl_reg;
OSC.CTRL |= OSC_PLLEN_bm;
while ( !( OSC.STATUS & OSC_PLLRDY_bm ) );
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc;
OSC.CTRL = OSC.CTRL & 0xFE;


Далее решил проверить, написал простенький код:
Код
ISR(TCC0_OVF_vect)
{
    TCC0.CTRLA = 0;
    PORTF.OUTTGL = PIN6_bm;
}

int main(void)
{
    PMIC.CTRL = PMIC_LOLVLEN_bm;
    PORTF.DIRSET = PIN6_bm;
    PORTF.OUTSET = PIN6_bm;
    while (1)
    {
        asm("sei");
        TCC0.CNT = 0;
        TCC0.PER = 1;
        TCC0.INTCTRLA = 1;
        TCC0.CTRLA = 1;
        while ( TCC0.CTRLA & 1 );
    }
}

И наблюдаю на осциле частоту ногодрыгания 250 кГц. Я конечно читал про виртуальные порты, точно не помню насколько будет прирост (сейчас буду считать), но думаю не более 1 МГц станет?

P.S. Да кстати, частота работы ЦПУ - 32 МГц
_Артём_
Цитата(Дмитрий_Мигачев @ Sep 2 2013, 11:57) *
Долго не мог понять почему так, на AVRFreaks вычитал что необходимо ставить оптимизацию -Os и это помогло. Я так понимаю, теперь чтобы выбрать другую оптимизацию мне нужно этот участок кода писать на ассемблере?

Код
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc;
OSC.CTRL = OSC.CTRL & 0xFE;


Тут может быть проблема в двух местах:

1) при записи в регистр CLK.CTRL

2) при записи в регистр OSC.CTRL

В первом случае код может не уложится в 4 цикла отведённые на запись в регистр CLK.CTRL. Поэтоиу запись в защищённые регистры вынести в ассемблерную функцию, которой передавать адрес и новое значение регистра CLK.CTRL. Тогда можно выбирать любую оптимизация для проекта.

Во втором случае код может оказаться слишком быстрым, а для переключения на другой источник тактовоя тоже нужно время (4 такта кажется). Попробуйте вставить после записи в CLK.CTRL 3-4 nop-а и только после запрещать уже не нужный генератор.

Код
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc;

nop();

nop();

nop();

nop();
OSC.CTRL = OSC.CTRL & 0xFE;





или ожидайте пока не переключится на нужный источник:

Код
CCP = CCP_IOREG_gc;
CLK.CTRL = CLK_SCLKSEL_PLL_gc;

while ( CLK.CTRL!= CLK_SCLKSEL_PLL_gc);
OSC.CTRL = OSC.CTRL & 0xFE;







Цитата(Дмитрий_Мигачев @ Sep 2 2013, 11:57) *
Далее решил проверить, написал простенький код:

И наблюдаю на осциле частоту ногодрыгания 250 кГц.
P.S. Да кстати, частота работы ЦПУ - 32 МГц

Ну, видимо работает от RC 2MHz. Смотрите Jtag-ом значение регистра CLK.CTRL, там скорей всего 0.
Дмитрий_Мигачев
Цитата(_Артём_ @ Sep 2 2013, 20:33) *
Ну, видимо работает от RC 2MHz. Смотрите Jtag-ом значение регистра CLK.CTRL, там скорей всего 0.

Спасибо за ответ. До изменения оптимизации, мне не удавалось получить ногодрыгание превышающее 8 кГц. Возможно просто PLL не работал.

Цитата
Попробуйте вставить после записи в CLK.CTRL 3-4 nop-а и только после запрещать уже не нужный генератор.

Ничего не изменилось, так же как и ожидание по while. Но судя по отладчику через JTAG бит устанавливается сразу.

Цитата
Смотрите Jtag-ом значение регистра CLK.CTRL, там скорей всего 0.

Отладчик показывает что после команды: CLK.CTRL = CLK_SCLKSEL_PLL_gc
бит 2 в CLK.CTRL установлен.
В OSC.CTRL установлены 3 и 4 биты.
В OSC.PLLCTR установлены 1, 6 и 7 биты.
Цитата
Поэтоиу запись в защищённые регистры вынести в ассемблерную функцию, которой передавать адрес и новое значение регистра CLK.CTRL.

Не подскажите код, к сожалению ассемблер изучал давно и не правда.

Переписал код,
Такой код:
Код
int main(void)
{
    //PMIC.CTRL = PMIC_LOLVLEN_bm;
    //TCC0.PER = 1;
    PORTF.DIRSET = PIN6_bm;
    while (1)
    {
        PORTF.OUTTGL = PIN6_bm;
    }
}

дает частоту ногодрыгания 4 МГц

Такой код:
Код
int main(void)
{
    PORTCFG_VPCTRLA = 5;
        VPORT0_DIR = PIN6_bm;
    while (1)
    {
          VPORT0_OUT = PIN6_bm;
              VPORT0_OUT = 0;
    }
}

дает частоту ногодрыгания порядка 8-9 МГц

P.S. Думаю что теперь все правильно
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.