一、简介
STM32F4自带了硬件随机数发生器(RNG),RNG处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个32位的随机数。
两个连续的随机数的间隔为40个PLL48CLK时钟信号周期。
通过监控RNG熵来标识异常行为。
可以禁止RNG来降低功耗。
二、功能框图
STM32F4的随机数发生器(RNG)采用模拟电路实现。此电路产生馈入线性反馈移位寄存器 (RNG_LFSR) 的种子,用于生成 32 位随机数。
该模拟电路由几个环形振荡器组成,振荡器的输出进行异或运算以产生种子。RNG_LFSR 由专用时钟 (PLL48CLK) 按恒定频率提供时钟信息,因此随机数质量与 HCLK 频率无关。当将大量种子引入RNG_LFSR后,RNG_LFSR 的内容会传入数据寄存器 (RNG_DR)。
同时,系统会监视模拟种子和专用时钟 PLL48CLK,当种子上出现异常序列,或PLL48CLK时钟频率过低时,可以由RNG_SR寄存器的对应位读取到,如果设置了中断,则在检测到错误时,还可以产生中断。
三、寄存器介绍
(1)控制寄存器
(2)状态寄存器
(3)数据寄存器
四、常用固件库函数
(1)复位RNG
void RNG_DeInit(void);
(2)使能RNG
void RNG_Cmd(FunctionalState NewState);
(3)获取随机数
uint32_t RNG_GetRandomNumber(void);
(4)中断相关的函数
void RNG_ITConfig(FunctionalState NewState); //配置中断
ITStatus RNG_GetITStatus(uint8_t RNG_IT); //获取中断标志位
void RNG_ClearITPendingBit(uint8_t RNG_IT); //清除中断标志位
(5)标志位相关的函数
FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG); //获取状态标志位
void RNG_ClearFlag(uint8_t RNG_FLAG); //清除状态标志位
五、程序
#ifndef __RNG_H__
#define __RNG_H__
#include "stm32f4xx_conf.h"
void RNG_Config(void);
uint32_t RNG_Get_RandomNum(void);
uint32_t RNG_Get_RandomRange(uint16_t min,uint16_t max);
#endif
#include "./RNG/rng.h"
#include "delay.h"
/************************
功能:配置RNG
参数:无
返回值:无
*************************/
void RNG_Config(void)
{
uint16_t retry;
/*1、打开RNG的时钟*/
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG,ENABLE);
/*2、使能RNG*/
RNG_Cmd(ENABLE);
/*3、等待随机数就绪*/
while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET & retry < 10000)
{
retry++;
delay_us(100);
}
if(retry >= 10000)//随机数产生器不正常
{
return;
}
}
/************************
功能:获取随机数
参数:无
返回值:获取到的随机数
*************************/
uint32_t RNG_Get_RandomNum(void)
{
//等待随机数就绪
while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET);
//返回获取到的随机数
return RNG_GetRandomNumber();
}
/**********************************
功能:获取[min,max]范围的随机数
参数:
min-->最小值
max-->最大值
返回值:获取到的随机数
***********************************/
uint32_t RNG_Get_RandomRange(uint16_t min,uint16_t max)
{
return ((RNG_Get_RandomNum() % (max-min+1)) + min);
}
#include "delay.h"
#include "stdio.h"
#include "./LED/led.h"
#include "./BEEP/beep.h"
#include "./KEY/key.h"
#include "./USART/usart.h"
#include "./EXTI/exti.h"
#include "./IWDG/iwdg.h"
#include "./TIMER/timer.h"
#include "./TIMER_PWM/pwm.h"
#include "./RTC/rtc.h"
#include "./RNG/rng.h"
int main(void)
{
uint32_t random;
//初始化延时函数
delay_init(168);
//初始化串口
USART_Config();
//初始化LED
LED_Config();
//初始化KEY
KEY_Config();
//初始化RNG
RNG_Config();
//产生随机数
random = RNG_Get_RandomNum();
printf(" random = %d \r\n",random);
//产生[0,9]区间的随机数
random = RNG_Get_RandomRange(0,9);
printf("random[0,9] = %d \r\n",random);
while(1)
{
}
}