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

Не проходит у меня снятие защиты в 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 такта... :))

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

Изменено пользователем Юрий_СВ

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


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

Вот мой код:

// Функция установки тактирования от кварцевого генератора с умножением частоты в 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
}

а без асемблера - вроде по даташиту неработает (необходимо очень быстро переключать источники тактирования.

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


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

а без асемблера - вроде по даташиту неработает (необходимо очень быстро переключать источники тактирования.

Но выше приведен код без ассемблера (авторы asm_lock и Юрий_СВ). Видимо в их случае компилятор укладывал код более компактно.

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


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

Но выше приведен код без ассемблера (авторы asm_lock и Юрий_СВ). Видимо в их случае компилятор укладывал код более компактно.

Тогда фактически все будет зависить от компилятора (переведет он в компактный код или нет) (хотя есть вариант что в последних версиях уже добавлен этот код (асемблер) для переключения (на уровне компиляции: т.е. пользователь не видит, пишет на "с", а на самом деле за него поддумали разработчики кода при оптимизации кода на "с" под xmega).

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


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

IAR 5.51.0, без оптимизации, все работает.

Внешний кварц на 8.000 Мгц, тактовая 32.000МГц

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 );
}

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

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


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

Тогда надо смотреть что из себя представляет функция CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc ); в IAR 5.51.0 (а именно после компиляции) и сравнивать с кодом Atmel (асмеблеровский из даташита)

(Веть IAR писала свои функции на основе информации Atmel и может все эти моменты учла?)

 

 

 

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


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

/*! \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

 

Можно подсмотреть как

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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