zl程序教程

您现在的位置是:首页 >  Java

当前栏目

(23)STM32——硬件随机数发生器

2023-02-18 15:49:55 时间

目录

学习目标

介绍

寄存器

RNG_CR

RNG_SR

RNG_DR

配置

代码

总结 


学习目标

        本节我们来介绍一下有关硬件随机数发生器的知识,这一节可以说是我遇到32中最简单的一节内容了,只要只用几个函数就好了,不需要繁琐的配置,和软件中的随机数一样舒服。

介绍

  1. STM32F4自带了硬件随机数发生器(RNG),RNG处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个32位的随机数。
  2. 两个连续的随机数的间隔为40个PLL48CLK时钟信号周期。
  3. 通过监控RNG熵来标识异常行为。
  4. 可以禁止来降低功耗。
  5. STM32F4的随机数发生器(RNG)采用模拟电路实现。此电路产生馈入线性反馈移位寄存器 (RNG_LFSR) 的种子,用于生成 32 位随机数。
  6. 该模拟电路由几个环形振荡器组成,振荡器的输出进行异或运算以产生种子。RNG_LFSR 由专用时钟 (PLL48CLK) 按恒定频率提供时钟信息,因此随机数质量与 HCLK 频率无关。当将大量种子引入RNG_LFSR后,RNG_LFSR 的内容会传入数据寄存器 (RNG_DR)。
  7. 同时,系统会监视模拟种子和专用时钟 PLL48CLK,当种子上出现异常序列,或PLL48CLK时钟频率过低时,可以由RNG_SR寄存器的对应位读取到,如果设置了中断,则在检测到错误时,还可以产生中断。

        这是一个简单的框图,介绍了一下工作原理,而且值得注意的是,接入的是AHB2总线。 

寄存器

        这章寄存器较少,就贴出来给大家看一下(水篇幅)。

RNG_CR

RNG_SR

RNG_DR

配置

1、使能随机数发生器时钟。

 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);//开启 RNG 时钟

2、使能随机数发生器。

 RNG_Cmd(ENABLE); //使能 RNG

3、判断 DRDY 位,读取随机数值。

FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);
//库函数中,判断数据是否有效的入口参数为 RNG_FLAG_DRDY,所以等待就绪的方法为:
while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET);
//判断数据有效后,然后我们读取随机数发生器产生的随机数即可,调用函数为:
uint32_t RNG_GetRandomNumber(void);
 

代码

#include "rng.h"
#include "delay.h"


//初始化RNG
u8 RNG_Init(void)
{
	u16 retry=0; 
	
	RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);//开启RNG时钟,来自PLL48CLK,AHB2总线
	
	RNG_Cmd(ENABLE);	//使能RNG
	
	while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET&&retry<10000)	//等待随机数就绪
	{
		retry++;
		delay_us(100);
	}
	if(retry>=10000)return 1;//随机数产生器工作不正常
	return 0;
}
//得到随机数
//返回值:获取到的随机数
u32 RNG_Get_RandomNum(void)
{	 
	while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET);	//等待随机数就绪  
	return RNG_GetRandomNumber();	
}

//生成[min,max]范围的随机数
int RNG_Get_RandomRange(int min,int max)
{ 
   return RNG_Get_RandomNum()%(max-min+1) +min;
}

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "rng.h"
#include "key.h"
    
int main(void)
{ 
	u32 random;
	u8 t=0,key;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);  //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	LED_Init();					//初始化LED
	KEY_Init();					//按键初始化;	 
	while(RNG_Init())	 		//初始化随机数发生器
	{
		printf("  RNG Error! \n");	 
		delay_ms(200);
		printf("RNG Trying...\n");	 
	}                                 
	printf("RNG Ready!   \n");	 
	printf("KEY0:Get Random Num\n");	 
	printf("Random Num:\n");	 
	printf("Random Num[0-9]:\n");	 	
  
	while(1) 
	{		
		delay_ms(10);
		key=KEY_Scan(0);
		if(key==KEY0_PRES)
		{
			random=RNG_Get_RandomNum(); //获得随机数
			printf("随机数:%d\n",random); //显示随机数

		} 
		if((t%20)==0)
		{ 
			LED0=!LED0;	//每200ms,翻转一次LED0 
			random=RNG_Get_RandomRange(0,9);//获取[0,9]区间的随机数
			printf("%d\n",random); //显示随机数
		 }
		delay_ms(10);
		t++;
	}	
}

总结 

        本节硬件随机数发生器的内容比较简单,我们就简单介绍一下,希望对大家有所帮助,谢谢大家了!