Буян 0 1 августа, 2011 Опубликовано 1 августа, 2011 (изменено) · Жалоба Не проходит у меня снятие защиты в 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 Изменено 1 августа, 2011 пользователем Юрий_СВ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uzig 0 1 августа, 2011 Опубликовано 1 августа, 2011 · Жалоба Юрий_СВ не проходит Ваш вариант :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leonmezon 0 1 августа, 2011 Опубликовано 1 августа, 2011 · Жалоба Вот мой код: // Функция установки тактирования от кварцевого генератора с умножением частоты в 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 0 1 августа, 2011 Опубликовано 1 августа, 2011 · Жалоба а без асемблера - вроде по даташиту неработает (необходимо очень быстро переключать источники тактирования. Но выше приведен код без ассемблера (авторы asm_lock и Юрий_СВ). Видимо в их случае компилятор укладывал код более компактно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leonmezon 0 1 августа, 2011 Опубликовано 1 августа, 2011 · Жалоба Но выше приведен код без ассемблера (авторы asm_lock и Юрий_СВ). Видимо в их случае компилятор укладывал код более компактно. Тогда фактически все будет зависить от компилятора (переведет он в компактный код или нет) (хотя есть вариант что в последних версиях уже добавлен этот код (асемблер) для переключения (на уровне компиляции: т.е. пользователь не видит, пишет на "с", а на самом деле за него поддумали разработчики кода при оптимизации кода на "с" под xmega). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GarikBaza 0 1 августа, 2011 Опубликовано 1 августа, 2011 (изменено) · Жалоба 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 ); } Изменено 1 августа, 2011 пользователем GarikBaza Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Leonmezon 0 2 августа, 2011 Опубликовано 2 августа, 2011 · Жалоба Тогда надо смотреть что из себя представляет функция CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc ); в IAR 5.51.0 (а именно после компиляции) и сравнивать с кодом Atmel (асмеблеровский из даташита) (Веть IAR писала свои функции на основе информации Atmel и может все эти моменты учла?) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GarikBaza 0 2 августа, 2011 Опубликовано 2 августа, 2011 · Жалоба /*! \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 Можно подсмотреть как Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться