首先,要产生随机数,必须先给它提供一个名为“种子”的初始值。而且这个值最好是随机的,至少是伪随机的。在这里使用中频ADC采样随机的RF接收信号作为做种子。
注意到,播种的过程中,将16位的种子分两次写入RNDL,高字节将自动移入RNDH,此过程即完成播种。若往RNDH中写值时,会触发计算CRC16,所以在这里不能对RNDH赋值。
所以我认为《Zigbee技术实践教程》上给的程序有问题,其程序如下:
主函数如下:
void main(void){
BYTE randomChar;
UINT8 i,rand; // Random Sequence
initRandom();//初始化相应的组件
lcdUpdate((char*)"Random text:", (char*)"");
LED1 = LED3 = LED_OFF;
halInitRandomGenerator();//播种过程有问题?
while( 1 ){
// Read random register
for(i = 0; i < LINE_SIZE; i++) // line_size=14
{
GET_RANDOM_BYTE(rand);//得到一个随机数的高8位给rand(字节型)
// randChar is equal a random value between 'a' and 'z'
// in the ascii table
//randomChar = 'a' + (rand % ('z' - 'a'));//使用这条语句,随机数会以字母的形式表现
randomChar = rand;//随机数会以rand对应的ASCII码形式表现,由于0~31是控制字符,可能会出现乱码
lcdUpdateChar(LINE2, i, randomChar);
halWait(0x0F);
}
halWait(255);
halWait(255);
}
}
原播种函数:有问题?
void halInitRandomGenerator(void)
{
BYTE i;
// turning on power to analog part of radio
RFPWR = 0x04;//射频模块的模拟部分上电
// waiting for voltage regulator.
while( RFPWR & 0x10 );//等待电压调节
// Turning on 32 MHz crystal oscillator
SET_MAIN_CLOCK_SOURCE(CRYSTAL);//32M晶振
// Turning on receiver to get output from IF-ADC
ISRXON;//打开和校准频率合成器
halWait(1);
ENABLE_RANDOM_GENERATOR();//打开为普通模式,RCTRL[1:0]=00
for(i = 0 ; i < 32 ; i++)
{
RNDH = ADCTSTH;//将RF接收的随机信号采样之后,给RNDH会触发计算CRC16,应该是给RNDL
CLOCK_RANDOM_GENERATOR();//这里为什么要产生一个随机数,而且要进行32次?
}
return;
}
原函数的播种为什么要这么做,不明白,我认为它有问题,如果有高手能解释一下,感激不尽!
所以我将播种过程直接改成这样:
void halInitRandomGenerator(void)
{
BYTE i;
RFPWR = 0x04;
while( RFPWR & 0x10 );
Turning on 32 MHz crystal oscillator
SET_MAIN_CLOCK_SOURCE(CRYSTAL);
ISRXON;
halWait(1);
ENABLE_RANDOM_GENERATOR();
RNDL = ADCTSTH;
RNDL = ADCTSTL;
return;
}
这样RF接收的随机信号的16位采样值,写入到LFSR中,之后通过调用一次get_random_byte()即可获得一个8位随机数。