shluzzzoid 0 24 октября, 2013 Опубликовано 24 октября, 2013 · Жалоба Добавил либу для ds1306+ работа с расширителем портов pcf8574 индикатор от Nokia5110 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
BaN 0 1 октября, 2014 Опубликовано 1 октября, 2014 (изменено) · Жалоба Генерация псеводослучайных чисел, в качестве зерна используется сильная зависимость частоты генератора VLO от внешних воздействий. Запускается 2 таймера: первый отсчитывает N периодов VLO, второй инкрементирует на максимальной частоте (256МГц) регистр счета. После отсчета N тиков VLO в регистре счета будет случайное значение (диапазон изменения этого числа зависит от количества N тиков VLO), которое потом используется в качестве зерна в стандартной функции stdlib rand(). #include <stdlib.h> #include "intrinsics.h" #include "io430f5172.h" void SetVcoreUp (unsigned int level) { // Open PMM registers for write PMMCTL0_H = PMMPW_H; // Set SVS/SVM high side new level SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level; // Set SVM low side to new level SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level; // Wait till SVM is settled while ((PMMIFG & SVSMLDLYIFG) == 0); // Clear already set flags PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); // Set VCore to new level PMMCTL0_L = PMMCOREV0 * level; // Wait till new level reached if ((PMMIFG & SVMLIFG)) while ((PMMIFG & SVMLVLRIFG) == 0); // Set SVS/SVM low side to new level SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level; // Lock PMM registers for write access PMMCTL0_H = 0x00; } void MC_Init(void) { __bic_SR_register(GIE); // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; // Настраиваем рабочую частоту для генерирации зерна для гнератора псевдослучайных чисел. // Генерировать будем путем подсчета числа тактов Hi-res таймера, // работающего на частоте 256МГц от LFCLK кварца, за N периодов VCO генератора. // Для этого нам нужно настроить тактовую частоту на 16МГц и потом воспользоваться умножителем Hi-res таймера TimerD. // Increase Vcore setting to level2 to support fsystem=16MHz // NOTE: Change core voltage one level at a time.. SetVcoreUp(0x01); SetVcoreUp(0x02); UCSCTL8 &= ~(ACLKREQEN | MCLKREQEN | SMCLKREQEN); // Если не сбросить эти биты, то (ACLKREQEN | MCLKREQEN | SMCLKREQEN) // ACLK, SMCLK, MCLK могут останться активными в LPM3 // Настройка системы тактирования PJSEL |= BIT4+BIT5; // Port select XT1 UCSCTL6 &= ~(XT1OFF); // XT1 On UCSCTL6 |= XCAP_1; UCSCTL3 = 0; // FLL Reference Clock = XT1 // Loop until XT1 fault flag is cleared do { UCSCTL7 &= ~XT1LFOFFG; // Clear XT1 fault flags }while (UCSCTL7&XT1LFOFFG); // Test XT1 fault flag // Initialize DCO to 16MHz __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_6; // Select DCO range 20MHz-40MHz operation UCSCTL2 = FLLD_1 + 487; // Set DCO Multiplier for 16MHz // (N + 1) * FLLRef = Fdco // (487 + 1) * 32768 = 16MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 25 MHz / 32,768 Hz = 500000 = MCLK cycles for DCO to settle __delay_cycles(500000); // Loop until XT1 & DCO fault flag is cleared do { UCSCTL7 &= ~(XT1LFOFFG + XT1HFOFFG + DCOFFG); // Clear XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag UCSCTL6 &= ~(XT1DRIVE_3); // Xtal is now stable, reduce drive strength // Генерируем зерна для гнератора псевдослучайных чисел UCSCTL4 &= ~(SELA2|SELA1|SELA0); UCSCTL4 |= SELA__VLOCLK; TD0R = 0; TD1R = 0; // Настраиваем счетчик SMCLK (DCO) with Hi-res mode it's 256MHz // Configure TimerD in Hi-Res Regulated Mode TD1CTL0 = TDSSEL_2; // TDCLK=SMCLK=16MHz=Hi-Res input clk select TD1CTL1 |= TDCLKM_1; // Select Hi-res local clock TD1HCTL0 = TDHM_1 + TDHCALEN + TDHEN; // Hi-res clock 16x TDCLK, // Calibration and Hi-res mode enable TD1CTL0 = TDSSEL_2 + CNTL_0 + MC_2 + ID_0; // SMCLK, Continous up, input divider /1 while((TD1HINT & TDHLKIFG) == 0); // Wait for Hi-res freq lock TD1HINT |= TDHLKIFG; // Clear lock flag // Настраиваем счетчик ACLK (VLO) TD0CCR0 = 9; // Считаем 10 тиков VLO. При 1000 тиков в TD1R будет полностью случайное значение (все 16 бит). //При 10/100 тиках значение будет изменяться в меньшем диапазоне бит. TD0CTL0 = TDSSEL_1 + CNTL_0 + MC_2 + ID_0; // ACLK, count to TDCL0, input divider /1 //TD1CTL0 |= TDCLR; // Don't clear TD1 timer - it'll add additional random because of variable freq lock time // Ожидаем, когда счетчик отсчитает заданное число тиков VLO while((TD0CCTL0 & CCIFG) == 0); srand(TD1R); // Устанавливаем зерно для генератора псевдослучайных чисел TD1CTL0 = 0; TD0CTL0 = 0; TD0HCTL0 = 0; UCSCTL4 &= ~(SELA2|SELA1|SELA0); UCSCTL4 |= SELA__XT1CLK; // Генерация зерна для генератора псевдослучайных чисел закончена, теперь можно настраивать рабочую частоту на необходимую SetVcoreUp(0x00); // Initialize DCO to 2.45MHz __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_3; // Set RSELx for DCO = 2.45 MHz UCSCTL2 = FLLD_1 + 74; // Set DCO Multiplier for 2.45MHz // (N + 1) * FLLRef = Fdco // (74 + 1) * 32768 = 2.45MHz // Set FLL Div = fDCOCLK/2 __bic_SR_register(SCG0); // re-enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 2.45 MHz / 32,768 Hz = 76563 = MCLK cycles for DCO to settle __delay_cycles(76563); // Loop until DCO fault flag is cleared do { UCSCTL7 &= ~(DCOFFG); // Clear XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag } void main( void ) { int random_num; MC_Init(); random_num = rand(); /* // Измерение времени генерации случайного числа при помощи rand() // При SMCLK = 2.45MHz время равно (78 * 1/2.45MHz) = 32мкс TD0R = 0; TD0CTL0 = TDSSEL_2 + CNTL_0 + MC_2 + ID_0 + TDCLR; // SMCLK, Continous up, input divider /1, clear TDR rand_num = rand(); TD0CTL0 = 0; rand_time = TD0R; */ while(1); } Изменено 1 октября, 2014 пользователем BaN Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться