天天看点

硬件随机数发生器

文章目录

      • RNG-硬件随机数发生器
      • RNG寄存器
        • 控制寄存器 RNG_CR
        • 状态寄存器 RNG_SR
        • 数据寄存器RNG_DR
        • RNG库函数
        • 实验代码

RNG-硬件随机数发生器

硬件随机数发生器(RNG),以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个32位的随机数。

两个连续的随机数的间隔为40个PLL48CLK时钟信号周期

通过监控RNG熵来标识异常行为

硬件随机数发生器

由模拟种子产生随机数保存在LFSR里面,数据再一次性发送到RNG_DR寄存器中。

① STM32F4的随机数发生器(RNG)采用模拟电路实现,此电路产生馈入线性反馈移位寄存器(RNG_LFSR)的种子,生成32位随机数

②模拟电路由几个环形振荡器组成,振荡器的输出进行抑或运算产生种子。RNG_LFSR由专用时钟(PLL48CLK)按恒定频率计算时钟信息,so随机数质量与HCLK频率无关。大量的种子引入RNG——LFSR后,RNG_LFSR的内容会传入数据寄存器(RNG_DR).

③系统会监视模拟种子和专用时钟PLL48CLK,当种子出现异常序列,或PLL48CLK时钟频率过低时,可以由RNG_SR寄存器的对应位读取到,如果设置了中断,则在检测到错误时,还可以产生中断。

RNG寄存器

控制寄存器 RNG_CR

硬件随机数发生器

位31:4保留,必须保持复位值

位3 IE:中断使能(Interrupt enable)

0:禁止RNG中断。

1:使能 RNG中断。只要 RNG_SR寄存器中 DRDY=1或 SEIS=1或CEIS=1,就会引起中断。

位2 RNGEN:随机数发生器使能

0:禁止随机数发生器。

1:使能随机数发生器。

位1:0保留,必须保持复位值

状态寄存器 RNG_SR

硬件随机数发生器

位6 SEIS:种子错误中断状态

0:未检测到错误序列

1:检测到以下错误序列之一:

位5 CEIS:时钟错误中断状态(Clock error interrupt status)

0:正确检测到PLL48CLK时钟1:未正确检测到PLL48CLK时钟

位2 SECS:种子错误当前状态(Seed error current status)

0:目前未检测到错误序列。1:检测到以下错误序列

位1CECS:时钟错误当前状态(Clock error curent status)

0:正确检测到PLL48CLK时钟。1:来正确检测到PLL48CLK时钟

位0 DRDY:数据就绪(Data ready)

0:RNG_DR寄存器尚未有效,无可用随机数据1: RNG_DR寄存器包含有可用随机数

数据寄存器RNG_DR

硬件随机数发生器

位31:0 RNDATA:随机数据

32位随机数据

RNG库函数

void RNG_DeInit(void)//复位
{
  RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE);
  RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, DISABLE);
}
void RNG_Cmd(FunctionalState NewState)//使能
{
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)
  {
    /* Enable the RNG */
    RNG->CR |= RNG_CR_RNGEN;
  }
  else
  {
    /* Disable the RNG */
    RNG->CR &= ~RNG_CR_RNGEN;
  }
}
uint32_t RNG_GetRandomNumber(void)//获取硬件随机数
{
  /* Return the 32 bit random number from the DR register */
  return RNG->DR;
}

void RNG_ITConfig(FunctionalState NewState)
FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG)
void RNG_ClearFlag(uint8_t RNG_FLAG)
ITStatus RNG_GetITStatus(uint8_t RNG_IT)
void RNG_ClearITPendingBit(uint8_t RNG_IT)//标志位
           

实验代码

int main(void)
{ 
	u32 random;
	u8 t=0,key;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	delay_init(168);  
	uart_init(115200);		
	LED_Init();					
	KEY_Init();			
 	LCD_Init();         //初始化
	POINT_COLOR=RED;
	LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");	
	LCD_ShowString(30,70,200,16,16,"RNG TEST");	
	LCD_ShowString(30,90,200,16,16,"[email protected]");
	LCD_ShowString(30,110,200,16,16,"2014/5/5");	 
	while(RNG_Init())	 		//初始化随机数发生器
	{
		LCD_ShowString(30,130,200,16,16,"  RNG Error! ");	 
		delay_ms(200);
		LCD_ShowString(30,130,200,16,16,"RNG Trying...");	 
	}                                 
	LCD_ShowString(30,130,200,16,16,"RNG Ready!   ");	 
	LCD_ShowString(30,150,200,16,16,"KEY0:Get Random Num");	 
	LCD_ShowString(30,180,200,16,16,"Random Num:");	 
	LCD_ShowString(30,210,200,16,16,"Random Num[0-9]:");	 	
  
	POINT_COLOR=BLUE;
	while(1) 
	{		
		delay_ms(10);
		key=KEY_Scan(0);
		if(key==KEY0_PRES)
		{
			random=RNG_Get_RandomNum(); //获取随机数
			LCD_ShowNum(30+8*11,180,random,10,16); //显示随机数

		} 
		if((t%20)==0)
		{ 
			LED0=!LED0;	//每200ms翻转一次
			random=RNG_Get_RandomRange(0,9);//获取[0,9]内的随机数
			LCD_ShowNum(30+8*16,210,random,1,16); //显示
		 }
		delay_ms(10);
		t++;
	}	
}