STM32F4硬件随机数发生器(RNG)的使用

更多交流欢迎关注作者抖音号:81849645041

目的

        了解RNG随机数发生器,实现对硬件随机数的获取。

原理

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

        随机数发生器框图:

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

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

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

随机数发生器(RNG)寄存器

        RNG 控制寄存器(RNG_CR):

        该寄存器只有 bit2 和 bit3 有效,用于使能随机数发生器和中断。我们一般不用中断,所以只需要设置 bit2 为 1,使能随机数发生器即可。

        RNG 状态寄存器(RNG_SR):

         该寄存器我们仅关心最低位(DRDY 位),该位用于表示 RNG_DR 寄存器包含的随机数数 据是否有效,如果该位为 1,则说明 RNG_DR 的数据是有效的,可以读取出来了。读 RNG_DR 后,该位自动清零。

        RNG 数据寄存器(RNG_DR)

         在 RNG_SR 的 DRDY 位置位后,我们就可以读取该寄存器获得 32 位随机数值。此寄存器在最多 40 个 PLL48CK 时钟周期后,又可以提供新的随机数值。

准备

        MDK5 开发环境。

        STM32F4xx HAL库。

        STM32F407 开发板。

        STM32F4xx 参考手册。

        STM32F4xx 数据手册。

        STM32F407 开发板电路原理图。

步骤

  • 创建头文件bsp_rng.h并定义函数
#ifndef __BSP_RNG_H
#define __BSP_RNG_H

#include "stm32f4xx.h"

void RNG_Init(void);
uint32_t RNG_Get_RandomNum(void);
uint32_t RNG_Get_RandomRange(uint32_t min, uint32_t max);

#endif
  • 创建源文件bsp_rng.c并实现操作函数
#include "bsp_rng.h"

RNG_HandleTypeDef rng_Handle;

// RNG初始化
void RNG_Init(void)
{

	rng_Handle.Instance = RNG;
	HAL_RNG_Init(&rng_Handle);

}

// 底层初始化
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
{
	__HAL_RCC_RNG_CLK_ENABLE(); // 使能RNG时钟

}

// 获取随机数
uint32_t RNG_Get_RandomNum(void)
{
	return	HAL_RNG_GetRandomNumber(&rng_Handle);
}

// 获取指定范围内随机数
uint32_t RNG_Get_RandomRange(uint32_t min, uint32_t max)
{
	uint32_t Range = HAL_RNG_GetRandomNumber(&rng_Handle)%(max-min+1)+min;
	return Range;
}
  • main.c中通过按键显示随机数
#include "bsp_clock.h"
#include "bsp_uart.h"
#include "bsp_key.h"
#include "bsp_rng.h" 
#include "bsp_led.h"

int main(void)
{
	uint32_t min = 1;
	uint32_t max = 10;
	
	CLOCLK_Init(); // 初始化系统时钟
	UART_Init(); // 串口初始化
	KEY_Init(); // 按键初始化
	LED_Init(); // LED初始化
	RNG_Init(); // RNG初始化
	
	while(1)
	{
		uint8_t key = KEY_Scan(0); 
		 if(key == 1) // KEY0按下
		 { 
			 LED1_Toggle; // 点亮LED1
			 uint32_t num = RNG_Get_RandomNum(); // 获取随机数
			 printf("RNG Num: %d \n",num);	
		 }
		 
		 if(key == 2) // KEY1按下
		 { 
			 LED2_Toggle; // 点亮LED2
			 uint32_t RangeNum = RNG_Get_RandomRange(min, max);// 获取范围随机数
			 printf("RNG Num[%d~%d]: %d \n",min,max,RangeNum);
		 }
		 HAL_Delay(50);
	}
}

现象

        把编译好的程序下载到开发板,按下key0获取随机数。

         按下key1获取指定范围内随机数。

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奚海蛟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值