Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Atxmega Внешний кварц
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
KIG
Добрый день!

Начал изучать Atxmega192A. Программирую в AVR Studio 4.18. Как я понял, необходимо в программе сначала определить какой будет использоваться кварц (у меня внешний). Для этого написал следующую функцию:

Код
void CLK_init()
{
CCP=0xD8;
CLK.CTRL=3;
CCP=0xD8;
OSC.XOSCCTRL=0x40;
CCP=0xD8;
OSC.CTRL=(1<<3);
}


Оптимизация кода включена O1. При отладке кода в AVR Studio вижу, что в ССP регистр записывается 1 вместо D8. СLK.CTRL вообще не обновляется. А при записи регистра OSC.CTRL в нем остается изначально установленный нулевой байт, разрешающий работу внутреного кварца. Подскажите, пожалуйста, что я делаю не так.
V_G
Сначала надо разрешить кварцевый генератор, потом подождать, пока он устаканится, потом выбрать его в качестве источника тактирования.
В ССP никогда не увидите записанной сигнатуры - большинство битов там только на запись, читайте описание.
Вот мой ассемблерный код, но я не жду, т.к. у меня внешний генератор, запускающийся раньше проца.
Код
    LDI        r16,OSC_XOSCEN_bm|OSC_RC2MEN_bm//|OSC_RC32MEN_bm
    STS        OSC_CTRL,r16
    LDI        r16,CLK_SCLKSEL0_bm|CLK_SCLKSEL1_bm
    LDI        r17,CCP_IOREG_gc
    OUT        CPU_CCP,r17            ;загрузили Protect IO Register signature
    STS        CLK_CTRL,r16            ;внешнее тактирование
asm_lock
Использовал ATxmega128A1....Подцепил внешний кварец на 16Мгц. Процедурка вышла простенькая и незатейливая, но пришлось пошаманить:

void setclk()
{

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 МГц

}

Только вот я заметил одну странность. В даташите написано что ток потребления при частоте 32 МГц от внешнего кварца (думаю что внешний кварец был 16МГц, и PLL *2) и Vcc=3.0 B не должен превышать 20мА. У меня при отключенной периферии и начальных настройках Icc= 40мА.
Fusion
ATxmega32A4 с отключенной перефирией, внутренний генератор, питание 3.3V:

2mHz - 3mA
32mHz - 19mA
asm_lock
у меня тоже периферия отключена. Подключен внешний кварцевый резонатор на 16 МГц. Включен PLL с множителем 2. И все.. Что так может жрать, не знаю. Если разрешаю выход сигнала CLKOUT, то ток потребления становится 50мА....не меньше.

Предполагаю, что в даташите допущена ошибка.....
rubic
вот так я запускал кварц 7.372800
Код
#include <avr/io.h>

void CCPWrite( volatile uint8_t * address, uint8_t value )
{
  volatile uint8_t * tmpAddr = address;
  asm volatile(
        "movw r30,  %0"          "\n\t"
        "ldi  r16,  %2"          "\n\t"
        "out   %3, r16"          "\n\t"
        "st     Z,  %1"       "\n\t"
        :
        : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP)
        : "r16", "r30", "r31"
        );
}

int main(void)
{  
    OSC.XOSCCTRL=0x4b;
              OSC.CTRL = 0x08;        
     while (!(OSC.STATUS &OSC_XOSCRDY_bm));
    CCPWrite(&CLK.CTRL,0x03);
    OSC.CTRL = 0x08;
   return 0;
}
Юрий_СВ
Кварц 4МГц + умножитель на 8 :
(у меня работает без вопросов)

OSC.XOSCCTRL=0x4b; // диапазон: 2-9 МГц, внешний резонатор, с временем запуска 16 000 циклов
OSC.CTRL=0x08; // включаем генератор на внешнем кварцевом резонаторе
while(!(OSC.STATUS&0x08)); // ждём готовности генератора на внешнем кварцевом резонаторе

OSC.PLLCTRL=0xc8; // внешний источник синхро, множитель=8
OSC.CTRL=0x18; // включаем синтезатор частоты
while(!(OSC.STATUS&0x10)); // ждём готовности синтезатора частоты

CPU_CCP=0xd8; // разрешить (сигнатурой) изменение важного регистра (следущая строка)
CLK.CTRL=0x04; // источник системной синхронизации - синтезатор частоты
CLK.PSCTRL=0x00; // Коэф. деления предделителей A, B и C = 1.
zumanah
Цитата(Юрий_СВ @ Jun 25 2011, 15:38) *
.


Вообще в Хmega по сравнению с Atmega выбор источника тактирования задается не фьюзами, что с одной стороны удобно что случайно не запоришь процессор, а с другой стороны увеличивает время запуска процессора на примерно 6мс, что не всегда желательно. Нормальная статья по выбору внешнего источника тактирования на Xmega
Pavel_Bor
Возможно ли на xmege запустить 2 кварца? например внешний и внутренний?
V_G
Там нет внутреннего кварца.
А источники тактирования можно оперативно переключать. С внутренних на внешние и обратно
Pavel_Bor
Цитата(V_G @ Jul 1 2011, 13:35) *
Там нет внутреннего кварца.
А источники тактирования можно оперативно переключать. С внутренних на внешние и обратно


а internal(RC) это разве не внутренний? от 32Кгц до 32Мгц. У меня atxmega128a3
ArtemKAD
Цитата
а internal(RC) это разве не внутренний?

Внутренний. Но не "кварц"...
zumanah
Цитата(Pavel_Bor @ Jul 1 2011, 14:45) *
а internal(RC) это разве не внутренний? от 32Кгц до 32Мгц. У меня atxmega128a3

internal(RC) - внутренний RC-генератор, достаточно удобная вещь однако ей нехватает точности кварца и может плавать с нагревом процессора хоть и не существенно, но для точный вычислений не всегда подходит
V_G
Точность внутренних генераторов в xmege существенно повышена в сравнении с просто мегой (введена термокомпенсация), но все равно до кварцевой не дотягивает.
uzig
Не проходит у меня снятие защиты в CCP:
Код
  CCP = 0xD8;        
  CLK.CTRL = 0x04;


в IOView видно что CLK.CTRL весь в нулях.

Скопипастил у rubic (спасибо ему ) его пример с замысловатым CCPWrite:
Код
void CCPWrite( volatile uint8_t * address, uint8_t value )
{
  volatile uint8_t * tmpAddr = address;
  asm volatile(
        "movw r30,  %0"          "\n\t"
        "ldi  r16,  %2"          "\n\t"
        "out   %3, r16"          "\n\t"
        "st     Z,  %1"       "\n\t"
        :
        : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP)
        : "r16", "r30", "r31"
        );
}


и сразу же все заработало.

Неужели без ассемблерных вставок код не успевает за 4 цикла прописать CLK.CTRL ?
Компилячу в AVR Studio 5 его gcc.




Юрий_СВ
Цитата(uzig @ Aug 1 2011, 20:39) *
Не проходит у меня снятие защиты в CCP:
Код
  CCP = 0xD8;        
  CLK.CTRL = 0x04;


Неужели без ассемблерных вставок код не успевает за 4 цикла прописать CLK.CTRL ?
Компилячу в AVR Studio 5 его gcc.


WinAVR делает так (кажись, 5 тактов) :
Код
CPU_CCP=0xd8;     // разрешить (сигнатурой) изменение важного регистра (следущая строка)
2b2:    88 ed           ldi    r24, 0xD8; 216
2b4:    84 bf           out    0x34, r24; 52
CLK.CTRL=0x04;    // источник системной синхронизации - синтезатор частоты
2b6:    e0 e4           ldi    r30, 0x40; 64
2b8:    f0 e0           ldi    r31, 0x00; 0
2ba:    84 e0           ldi    r24, 0x04; 4
2bc:    80 93 40 00     sts    0x0040, r24


Т.е. компилирует очень эффективно, но для данного случая просто нужен другой порядок тех же команд.

Но если немножко схитрить, то получается 2 такта... sm.gif)
Код
CLK.CTRL=0x04;    // источник системной синхронизации - синтезатор частоты
2b2:    e0 e4           ldi    r30, 0x40; 64
2b4:    f0 e0           ldi    r31, 0x00; 0
2b6:    94 e0           ldi    r25, 0x04; 4
2b8:    90 93 40 00     sts    0x0040, r25
CPU_CCP=0xd8;     // разрешить (сигнатурой) изменение важного регистра (следущая строка)
2bc:    88 ed           ldi    r24, 0xD8; 216
2be:    84 bf           out    0x34, r24; 52
CLK.CTRL=0x04;    // источник системной синхронизации - синтезатор частоты
2c0:    90 93 40 00     sts    0x0040, r25
uzig
Юрий_СВ
не проходит Ваш вариант sad.gif
Leonmezon
Вот мой код:
Код
// Функция установки тактирования от кварцевого генератора с умножением частоты в 2 раза
void clock_system (void)
{
//Настраиваем тактирование
//Кварц 14,7456МГц, умножение на 2
OSC.XOSCCTRL=0xcb; //Кварц(12-16),16К циклов (сb) или 256К -  (с3)
OSC.CTRL|=0x08; //Включаем кварцевый генератор
do{} while ((OSC.STATUS & 0x08)==0); //ожидаем готовности кв. генератора
OSC.PLLCTRL=0xc2;// PLL от кварца, К=2
OSC.CTRL|=0x10;//Включаем PLL
do{} while ((OSC.STATUS & 0x10)==0); //Ожидаем готовности PLL
//переключаемся на тактирование от PLL
asm ("ldi r16,0xd8");
asm ("ldi r17,0x04");
asm ("out 0x34,r16");
asm ("sts 64,r17");
OSC.CTRL=0x18; //выключаем все генераторы, кроме кварца и PLL
}

а без асемблера - вроде по даташиту неработает (необходимо очень быстро переключать источники тактирования.
uzig
Цитата(Leonmezon @ Aug 1 2011, 22:21) *
а без асемблера - вроде по даташиту неработает (необходимо очень быстро переключать источники тактирования.

Но выше приведен код без ассемблера (авторы asm_lock и Юрий_СВ). Видимо в их случае компилятор укладывал код более компактно.
Leonmezon
Цитата(uzig @ Aug 1 2011, 22:33) *
Но выше приведен код без ассемблера (авторы asm_lock и Юрий_СВ). Видимо в их случае компилятор укладывал код более компактно.

Тогда фактически все будет зависить от компилятора (переведет он в компактный код или нет) (хотя есть вариант что в последних версиях уже добавлен этот код (асемблер) для переключения (на уровне компиляции: т.е. пользователь не видит, пишет на "с", а на самом деле за него поддумали разработчики кода при оптимизации кода на "с" под xmega).
GarikBaza
IAR 5.51.0, без оптимизации, все работает.
Внешний кварц на 8.000 Мгц, тактовая 32.000МГц
CODE
void init_clk ( void )
{
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_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 );
}
Leonmezon
Тогда надо смотреть что из себя представляет функция CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc ); в IAR 5.51.0 (а именно после компиляции) и сравнивать с кодом Atmel (асмеблеровский из даташита)
(Веть IAR писала свои функции на основе информации Atmel и может все эти моменты учла?)


GarikBaza
CODE
/*! \brief This function selects the main system clock source.
*
* Hardware will disregard any attempts to select a clock source that is not
* enabled or not stable. If the change fails, make sure the source is ready
* and running and try again.
*
* \param clockSource Clock source to use as input for the system clock
* prescaler block.
*
* \return Non-zero if change was successful.
*/
uint8_t CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_t clockSource )
{
uint8_t clkCtrl = ( CLK.CTRL & ~CLK_SCLKSEL_gm ) | clockSource;
CCPWrite( &CLK.CTRL, clkCtrl );
clkCtrl = ( CLK.CTRL & clockSource );
return clkCtrl;
}


http://www.atmel.com/dyn/resources/prod_do...nts/AVR1003.zip

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