实验13:随机数发生器实验

一、简介

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

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

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

    可以禁止RNG来降低功耗。

二、功能框图

实验13:随机数发生器实验_第1张图片

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

    该模拟电路由几个环形振荡器组成,振荡器的输出进行异或运算以产生种子。RNG_LFSR 由专用时钟 (PLL48CLK) 按恒定频率提供时钟信息,因此随机数质量与 HCLK 频率无关。当将大量种子引入RNG_LFSR后,RNG_LFSR 的内容会传入数据寄存器 (RNG_DR)。

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

三、寄存器介绍

    (1)控制寄存器

实验13:随机数发生器实验_第2张图片

    (2)状态寄存器

实验13:随机数发生器实验_第3张图片

    (3)数据寄存器

实验13:随机数发生器实验_第4张图片

四、常用固件库函数

    (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);      //清除状态标志位

五、程序

rng.h文件

#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
 

rng.c文件

#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); 
}

main.c文件

#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)
    {
        
    }
}

你可能感兴趣的:(STM32)