有时候项目中需要用到开机产生随机数,而软件产生随机数必须要一个随机种子。随机种子的产生通常有下面几种方式:
- 用一路AD采集温度或电源噪声,取后几位作为随机信号;
- 将用户的交互信号时间作为随机信号;
- 利用时钟芯片或RTC获取当前时间再经处理作为随机信号;
- 自己搭一个硬件电路用来产生随机信号;
有时候条件限制上面这几种方式都用不了,那还有没有其他方式能获得随机数呢。每个单片机都有一个唯一的ID,如果我们希望的是,每个单片机开机时产生的随机数和其他单片机产生的随机数不一样,那么就可以利用单片机的UID做为随机种子。由于每个单片机的码是不会变的,所以用UID码产生的随机种子每次开机都是一样的,每次产生的随机数也是一样的。所以用UID码产生随机数只适合于开机时不同单片机需要随机数不同的情况下。实现代码如下:
#define ID_BaseAddr 0x4865
unsigned char STM8S_ID[12]={0};
void Get_STM8S_UniqueID( void )
{
unsigned char i = 0;
for( i = 0; i < 12; i++ )
{
STM8S_ID[i] = *( unsigned char* )( ID_BaseAddr + i );
}
}
void main( void )
{
unsigned int seed = 0;
unsigned int t = 0;
SysClkInit();
__asm( "sim" ); //禁止中断
LED_GPIO_Init();
__asm( "rim" ); //开启中断
LED = 0;
Get_STM8S_UniqueID(); //读取UID
seed = STM8S_ID[9] * 100 + STM8S_ID[10] * 10 + STM8S_ID[11];
srand( seed ); //产生随机种子
t = rand() % 100;
while( 1 )
{
LED = 0;
delay_ms( t * 10 );
LED = 1;
delay_ms( t * 10 );
}
}
用 t = rand() % 100;这行代码产生的随机数在0–99范围内,如果希望有更大的范围将100改为其他值就可以了。
这样用上述方法产生的随机数,理论上可以认为100台设备同时开机后,LED灯闪烁的时间都不一样。