文章目录
-
-
- 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++;
}
}