реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Исходники программ и библиотек
Евгенич
сообщение Oct 24 2013, 19:04
Сообщение #16





Группа: Новичок
Сообщений: 4
Регистрация: 27-06-13
Пользователь №: 77 303



Добавил либу для ds1306+
работа с расширителем портов pcf8574
индикатор от Nokia5110
Go to the top of the page
 
+Quote Post
BaN
сообщение Oct 1 2014, 19:36
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 144
Регистрация: 28-08-07
Пользователь №: 30 111



Генерация псеводослучайных чисел, в качестве зерна используется сильная зависимость частоты генератора VLO от внешних воздействий. Запускается 2 таймера: первый отсчитывает N периодов VLO, второй инкрементирует на максимальной частоте (256МГц) регистр счета. После отсчета N тиков VLO в регистре счета будет случайное значение (диапазон изменения этого числа зависит от количества N тиков VLO), которое потом используется в качестве зерна в стандартной функции stdlib rand().
CODE
#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);
}


Сообщение отредактировал BaN - Oct 1 2014, 19:39
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd May 2017 - 23:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.02459 секунд с 7
ELECTRONIX ©2004-2016