【正点原子STM32】RNG硬件随机数(随机数发生器、真随机和伪随机、应用场景、RNG结构和原理、RNG相关寄存器和HAL库驱动、RNG基本驱动步骤)

一、RNG简介
二、RNG框图介绍
三、RNG相关寄存器介绍
四、RNG相关HAL库驱动介绍
五、RNG基本驱动步骤
六、编程实战
七、总结

一、RNG简介

在这里插入图片描述
随机数发生器(RNG)在计算机科学和密码学中具有广泛的应用场景,包括但不限于以下几个方面:

  1. 验证码:在网络安全和用户验证中,随机数用于生成验证码,增加系统的安全性,防止机器人攻击和恶意访问。

  2. 密码学:随机数在密码学中扮演着重要角色,用于生成密钥、初始化向量(IV)和盐等,增加加密算法的安全性。

  3. 概率学和统计学:随机数被用于模拟概率分布和随机变量,进行蒙特卡罗模拟、蒙特卡罗积分等,用于解决统计学和概率学中的问题。

  4. 游戏:在游戏开发中,随机数被广泛用于生成游戏中的随机事件、随机地图、随机怪物属性等,增加游戏的趣味性和挑战性。

随机数的重要特性是无法预测的、无规律性的、独立分布的。真随机数由物理过程生成,具有完全随机的性质,而伪随机数则是通过确定性算法计算出来的,虽然看起来像是随机的,但是在一定条件下可能会被预测到。在安全性要求较高的场景中,通常会使用真随机数发生器。

二、RNG框图介绍

在这里插入图片描述
RNG(Random Number Generator)采用模拟电路实现,其基本原理如下:

  1. 模拟电路结构:RNG通常由几个环形振荡器组成。这些振荡器的输出经过异或运算,产生种子(seed),作为随机数生成的初始值。

  2. LFSR(线性反馈移位寄存器):LFSR类似于一个“生产车间”,接收大量的种子输入。种子通过LFSR处理后,其内容传送到RNG数据寄存器(RNG_DR),用于随机数的生成。

  3. 时钟检查器和故障检测器:类似于“质检”,时钟检查器和故障检测器负责检测种子是否出现异常序列以及fpll48clk是否过低。这些异常情况会在RNG_SR寄存器的相关位显示,并可以触发中断。

  4. 中断功能:RNG通常设置了中断功能,当种子出现异常序列或fpll48clk过低时,会产生中断信号,以便系统进行相应的处理或响应。

总体而言,RNG通过模拟电路实现,利用环形振荡器、LFSR和时钟检查器等组件,生成随机数种子,并在检测到异常情况时产生中断,确保随机数生成的安全性和可靠性。

三、RNG相关寄存器介绍

在这里插入图片描述
这是RNG模块的关键寄存器及其作用:

  1. RNG_CR(RNG控制寄存器)

    • 用途:控制随机数发生器的启用和中断的使能。
    • 作用:通过设置该寄存器的位来启用或禁用随机数发生器,并控制中断功能的使能。
  2. RNG_SR(RNG状态寄存器)

    • 用途:显示RNG当前的一些状态信息。
    • 作用:该寄存器的特定位用于显示RNG模块的状态,例如随机数生成完成、时钟故障等。
  3. RNG_DR(RNG数据寄存器)

    • 用途:存储生成的32位随机数值。
    • 作用:随机数生成器生成的随机数会被存储在该寄存器中,供后续程序使用。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、RNG相关HAL库驱动介绍

在这里插入图片描述
这是与RNG模块相关的驱动函数及其功能描述以及关联的寄存器:

  1. HAL_RNG_Init(…)

    • 关联寄存器:RNG_CR
    • 功能描述:用于初始化RNG模块,配置RNG控制寄存器,启用或禁用随机数发生器以及中断。
  2. HAL_RNG_MspInit(…)

    • 初始化回调
    • 功能描述:在初始化过程中调用,用于初始化RNG模块的外设、时钟和选择时钟源等。
  3. HAL_RCCEx_PeriphCLKConfig(…)

    • 关联寄存器:RCC_BDCR
    • 功能描述:设置RNG模块的时钟源,通常设置为PLL。
  4. HAL_RNG_GenerateRandomNumber(…)

    • 关联寄存器:RNG_DR
    • 功能描述:用于生成随机数,会检查DRDY位以确定是否有随机数可用,并读取随机数。
  5. __HAL_RCC_RNG_CLK_ENABLE(…)

    • 关联寄存器:AHB2ENR
    • 功能描述:使能RNG模块的时钟,确保RNG模块能够正常工作。
  6. __HAL_RNG_GET_FLAG(…)

    • 关联寄存器:RNG_SR
    • 功能描述:用于获取RNG模块相关的标记,例如随机数生成完成标志位等。

五、RNG基本驱动步骤

在这里插入图片描述
RNG基本驱动步骤:

  1. 使能RNG时钟:

    • 使用 __HAL_RCC_RNG_CLK_ENABLE() 函数来启用RNG模块的时钟。
  2. 初始化随机数发生器:

    • 使用 HAL_RNG_Init() 函数初始化RNG模块,配置RNG控制寄存器等。
    • 在初始化过程中,需要调用 HAL_RNG_MspInit() 函数来初始化RNG模块的外设、时钟以及选择时钟源等设置,可能需要使用 HAL_RCCEx_PeriphCLKConfig() 函数来配置RNG模块的时钟源。
  3. 读取随机数值:

    • 使用 HAL_RNG_GenerateRandomNumber() 函数来生成随机数。
    • 在生成随机数之前,通常会判断 DRDY 位,以确保随机数已经就绪可以读取。

六、编程实战

在这里插入图片描述

按键输入

rng.c

#include "./BSP/RNG/rng.h"
#include "./SYSTEM/delay/delay.h"RNG_HandleTypeDef g_rng_handle; /* RNG控制句柄 *//*** @brief       初始化RNG模块* @retval      返回值:0成功,1失败*/
uint8_t rng_init(void)
{uint16_t retry = 0; /* 重试计数器 */g_rng_handle.Instance = RNG; /* RNG实例 */HAL_RNG_Init(&g_rng_handle); /* 初始化RNG模块 *//* 等待RNG准备就绪 */while ((__HAL_RNG_GET_FLAG(&g_rng_handle, RNG_FLAG_DRDY) == RESET) && (retry < 10000)){retry++;delay_us(10); /* 延时等待 */}/* 检查RNG是否正常工作 */if (retry >= 10000){return 1; /* 随机数产生器工作不正常 */}return 0; /* 初始化成功 */
}/*** @brief       初始化RNG模块的外设、时钟并选择时钟源* @param       hrng: RNG句柄*/
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
{RCC_PeriphCLKInitTypeDef rcc_periphclk_init_struct; /* 外设时钟初始化结构体 *//* RNG时钟使能 */__HAL_RCC_RNG_CLK_ENABLE();/* 配置RNG时钟源为PLL */rcc_periphclk_init_struct.PeriphClockSelection = RCC_PERIPHCLK_RNG;rcc_periphclk_init_struct.RngClockSelection = RCC_RNGCLKSOURCE_PLL;HAL_RCCEx_PeriphCLKConfig(&rcc_periphclk_init_struct);
}/*** @brief       获取随机数* @retval      返回32位随机数*/
uint32_t rng_get_random_num(void)
{uint32_t random_num = 0; /* 随机数变量 */HAL_RNG_GenerateRandomNumber(&g_rng_handle, &random_num); /* 生成随机数 */return random_num; /* 返回随机数 */
}/*** @brief       获取指定范围内的随机数* @param       min: 最小值* @param       max: 最大值* @retval      返回在[min, max]范围内的随机数*/
uint32_t rng_get_random_range(int min, int max)
{uint32_t random_num = 0; /* 随机数变量 */HAL_RNG_GenerateRandomNumber(&g_rng_handle, &random_num); /* 生成随机数 */return random_num % (max - min + 1) + min; /* 返回指定范围内的随机数 */
}

rng.h

#ifndef __RNG_H
#define __RNG_H#include "./SYSTEM/sys/sys.h"uint8_t rng_init(void);								// 初始化RNG模块的外设、时钟并选择时钟源
uint32_t rng_get_random_num(void);					// 获取随机数
uint32_t rng_get_random_range(int min, int max);	// 获取指定范围内的随机数#endif

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/KEY/key.h"
#include "./BSP/RNG/rng.h"int main(void)
{uint8_t key;uint32_t value = 0;uint32_t value_range = 0;sys_cache_enable();                 /* 打开L1-Cache */HAL_Init();                         /* 初始化HAL库 */sys_stm32_clock_init(240, 2, 2, 4); /* 设置时钟, 480Mhz */delay_init(480);                    /* 延时初始化 */usart_init(115200);                 /* 初始化串口 */led_init();                         /* 初始化LED */key_init();                         /* 初始化按键 */LED0(0);                            /* 先点亮LED0 */rng_init();                         /* RNG初始化 */while (1){key = key_scan(0);              /* 得到键值 */if (key){switch (key){case WKUP_PRES:         /* 控制LED0(RED)翻转 */value = rng_get_random_num();printf("value:%d \r\n", value);LED0_TOGGLE();      /* LED0状态取反 */break;case KEY1_PRES:         /* 控制LED1(GREEN)翻转 */value_range = rng_get_random_range(0, 9);printf("value_range:%d \r\n", value_range);LED1_TOGGLE();      /* LED1状态取反 */break;case KEY0_PRES:         /* 控制LED2(BLUE)翻转 */LED2_TOGGLE();      /* LED2状态取反 */break;} }else{delay_ms(10);}}
}

在这里插入图片描述
在这里插入图片描述

源码

rng.c

#include "./BSP/RNG/rng.h"         // 引入RNG头文件
#include "./SYSTEM/delay/delay.h"   // 引入延时函数头文件RNG_HandleTypeDef rng_handle;      // 声明RNG句柄变量/*** @brief       初始化RNG* @param       无* @retval      0,成功;1,失败*/
uint8_t rng_init(void)
{uint16_t retry = 0;rng_handle.Instance = RNG;                        // 设置RNG句柄的实例HAL_RNG_DeInit(&rng_handle);                      // 重新初始化RNGHAL_RNG_Init(&rng_handle);                         // 初始化RNG// 等待RNG准备就绪while ((__HAL_RNG_GET_FLAG(&rng_handle, RNG_FLAG_DRDY) == RESET) && (retry < 10000)){retry++;                                      // 尝试次数加1delay_us(10);                                 // 延时10微秒}if (retry >= 10000){return 1;                                      // 随机数产生器工作不正常,返回1}return 0;                                          // 返回0表示初始化成功
}/*** @brief       RNG底层驱动,时钟源设置和使能* @note        此函数会被HAL_RNG_Init()调用* @param       hrng:RNG句柄* @retval      无*/
void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
{RCC_PeriphCLKInitTypeDef RNGClkInitStruct;// 设置RNG时钟源,选择PLL,时钟为480MHzRNGClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RNG;   // 设置RNG时钟源为PLLRNGClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLL;   // RNG时钟源选择PLLHAL_RCCEx_PeriphCLKConfig(&RNGClkInitStruct);               // 配置RNG时钟源__HAL_RCC_RNG_CLK_ENABLE();                                 // 使能RNG时钟
}/*** @brief       得到随机数* @param       无* @retval      获取到的随机数(32bit)*/
uint32_t rng_get_random_num(void)
{uint32_t randomnum;HAL_RNG_GenerateRandomNumber(&rng_handle, &randomnum);       // 生成随机数return randomnum;                                            // 返回随机数
}/*** @brief       得到某个范围内的随机数* @param       min,max: 最小,最大值.* @retval      得到的随机数(rval),满足:min<=rval<=max*/
int rng_get_random_range(int min, int max)
{ uint32_t randomnum;HAL_RNG_GenerateRandomNumber(&rng_handle, &randomnum);       // 生成随机数return randomnum % (max - min + 1) + min;                   // 返回在[min, max]范围内的随机数
}

rng.h

#ifndef __RNG_H
#define __RNG_H #include "./SYSTEM/sys/sys.h"uint8_t rng_init(void);             /* RNG初始化 */
uint32_t rng_get_random_num(void);  /* 得到随机数 */
int rng_get_random_range(int min,int max);  /* 得到属于某个范围内的随机数 */#endif

main.c

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./USMART/usmart.h"
#include "./BSP/MPU/mpu.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/RNG/rng.h"int main(void)
{uint32_t random;    // 存储随机数的变量uint8_t t = 0, key; // t用于定时计数,key存储按键状态sys_cache_enable();                 // 打开L1-CacheHAL_Init();                         // 初始化HAL库sys_stm32_clock_init(240, 2, 2, 4); // 设置时钟, 480Mhzdelay_init(480);                    // 延时初始化usart_init(115200);                 // 串口初始化为115200usmart_dev.init(240);               // 初始化USMARTmpu_memory_protection();            // 保护相关存储区域led_init();                         // 初始化LEDlcd_init();                         // 初始化LCDkey_init();                         // 初始化按键// 在LCD上显示欢迎信息lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);lcd_show_string(30, 70, 200, 16, 16, "RNG TEST", RED);lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);// 初始化随机数发生器while (rng_init())  {lcd_show_string(30, 110, 200, 16, 16, "  RNG Error! ", RED);delay_ms(200);lcd_show_string(30, 110, 200, 16, 16, "RNG Trying...", RED);}lcd_show_string(30, 110, 200, 16, 16, "RNG Ready!   ", RED);lcd_show_string(30, 130, 200, 16, 16, "KEY0:Get Random Num", RED);lcd_show_string(30, 150, 200, 16, 16, "Random Num:", RED);lcd_show_string(30, 180, 200, 16, 16, "Random Num[0-9]:", RED); while (1){key = key_scan(0);  // 检测按键状态// 如果按键KEY0被按下,获取一个随机数并在LCD上显示if (key == KEY0_PRES){random = rng_get_random_num();lcd_show_num(30 + 8 * 11, 150, random, 10, 16, BLUE);}// 每200ms翻转一次LED0,并显示[0,9]范围内的随机数if ((t % 20) == 0){LED0_TOGGLE();                       // 每200ms,翻转一次LED0random = rng_get_random_range(0, 9); // 获取[0,9]范围内的随机数lcd_show_num(30 + 8 * 16, 180, random, 1, 16, BLUE); // 在LCD上显示随机数}delay_ms(10);  // 延时10mst++;           // 定时计数器递增}
}

七、总结

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/713539.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QML中动态表格修改数据

1.qml文件中的实现代码 import QtQuick 2.15 import QtQuick.Window 2.15import QtQuick.Controls 2.0 import Qt.labs.qmlmodels 1.0 import QtQuick.Layouts 1.15Window {width: 640height: 480visible: truetitle: qsTr("Hello World")TableModel{id:table_model…

深入剖析k8s-控制器思想

引言 本文是《深入剖析Kubernetes》学习笔记——《深入剖析Kubernetes》 正文 控制器都遵循K8s的项目中一个通用的编排模式——控制循环 for {实际状态 : 获取集群中对象X的实际状态期望状态 : 获取集群中对象X的期望状态if 实际状态 期望状态 {// do nothing} else {执行…

buuctf misc做题笔记

喵喵喵 使用stegsolve.jar&#xff0c;按BGR顺序提取出一个png图片&#xff0c;是一个一半得二维码&#xff0c;修改图片高度后&#xff0c;解析出一个百度网盘地址&#xff0c;https://pan.baidu.com/s/1pLT2J4f 下载得到压缩包flag.rar。解压成功&#xff0c;但是报一个出错…

LangChain---大型语言模型(LLM)的标准接口和编程框架

1.背景说明 公司在新的一年规划中突然提出要搞生成式AI(GenAI)的相关东西&#xff0c;在公司分享的参考资料中了解到了一些相关的信息&#xff0c;之所以想到使用LangChain&#xff0c;是因为在应用中遇到了瓶颈问题&#xff0c;除了已经了解和研究过的OpenAI的ChatGpt&#xf…

蓝桥杯Java B组历年真题(2013年-2019年)

一、2013年真题 1、世纪末的星期 使用日期类判断就行&#xff0c;这里使用LocalDate&#xff0c;也可以使用Calendar类 答案 2099 使用LocalDate import java.time.LocalDate; import java.time.format.DateTimeFormatter; // 1:无需package // 2: 类名必须Main, 不可修改p…

1小时网络安全事件报告要求,持安零信任如何帮助用户应急响应?

12月8日&#xff0c;国家网信办起草发布了《网络安全事件报告管理办法&#xff08;征求意见稿&#xff09;》&#xff08;以下简称“办法”&#xff09;。拟规定运营者在发生网络安全事件时应当及时启动应急预案进行处置。 1小时报告 按照《网络安全事件分级指南》&#xff0c…

Find My扫地机器人|苹果Find My技术与机器人结合,智能防丢,全球定位

扫地机器人又称自动打扫机、智能吸尘、机器人吸尘器等&#xff0c;是智能家电的一种&#xff0c;能凭借人工智能&#xff0c;自动在房间内完成地板清理工作。一般采用刷扫和真空方式&#xff0c;将地面杂物先吸纳进入自身的垃圾收纳盒&#xff0c;从而完成地面清理的功能。现今…

[AutoSar]BSW_Com07 CAN报文接收流程的函数调用

目录 关键词平台说明一、背景二、顺序总览三、函数说明3.1 Com_RxIndication&#xff08;&#xff09; 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c;芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)…

贝叶斯定理与条件独立假设:朴素贝叶斯分类方法深度解读

今天给大家分享的是朴素贝叶斯算法&#xff0c;这个算法在实际使用中不是很多&#xff0c;因为现在很多算法已经发展的很好&#xff0c;性能上也比朴素贝叶斯算法的好很多&#xff0c;因此在实际中我们其实看到在实际应用中朴素贝叶斯算法的使用已经比较少&#xff0c;即使出现…

HotFix原理学习 IL2CPP 学习

原文链接&#xff1a;Unity 游戏用XLua的HotFix实现热更原理揭秘-CSDN博客 本文通过对XLua的HoxFix使用原理的研究揭示出来这样的一套方法。这个方法的 第一步&#xff1a;通过对C#的类与函数设置Hotfix标签。来标识需要支持热更的类和函数。第二步&#xff1a;生成函数连接器…

好视通视频会议系统存在任意文件读取漏洞复现 [附POC]

漏洞简介 好视通视频会议是由深圳市华视瑞通信息技术有限公司开发&#xff0c;其在国内率先推出了3G互联网视频会议&#xff0c;并成功应用于SAAS领域。 资产 FOFA:app"好视通-视频会议" POC GET /register/toDownload.do?fileName../../../../../../../../../.…

代码随想录-回溯算法

组合 //未剪枝 class Solution {List<List<Integer>> ans new ArrayList<>();Deque<Integer> path new LinkedList<>();public List<List<Integer>> combine(int n, int k) {backtracking(n, k, 1);return ans;}public void back…

MySql安全加固:可信IP地址访问控制 设置密码复杂度

MySql安全加固&#xff1a;可信IP地址访问控制 & 设置密码复杂度 1.1 可信IP地址访问控制1.2 设置密码复杂度 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1.1 可信IP地址访问控制 当您在创建用户时使用’%作为主机部分&#xff0c;…

java数据结构与算法刷题-----LeetCode437. 路径总和 III(前缀和必须掌握)

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 深度优先2. 前缀和 1. 深度优先 解题思路&#xff1a;时间复…

kibana7.17.7 将数据导出csv文件

配置kibana文件 首先先配置kibana.yaml内容如下&#xff0c;这里假设我的服务器ip地址为192.168.130.128&#xff0c;elasticsearch的ip地址为&#xff1a;192.168.130.129:9200&#xff0c;192.168.130.130:9200&#xff1a; server.host: "192.168.130.128" serv…

Mac 以SH脚本安装Arthas

SH脚本安装Aethas curl -L https://alibaba.github.io/arthas/install.sh | sh安装脚本说明 示例源文件&#xff1a; #! /bin/bash# temp file of as.sh TEMP_ARTHAS_FILE"./as.sh.$$"# target file of as.sh TARGET_ARTHAS_FILE"./as.sh"# update timeo…

Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius,Kotlin

Android挖取原图手指触点区域RectF(并框线标记)放大到ImageView宽高与矩阵mapRadius&#xff0c;Kotlin 这里 Android挖取原图中心区域RectF(并框线标记)放大到ImageView宽高&#xff0c;Kotlin-CSDN博客 实现的是把原图中心区域的一片小图挖取出来放大放到下面的ImageView里面…

if语句用法

if语句是单条件分支语句 定义&#xff1a;根据一个条件来控制程序执行流程(如图3.2)。 语法格式&#xff1a; if&#xff08;表达式&#xff09;{ 若干语句 } ★注意★&#xff1a; ① 表达式的值必须是boolean 型&#xff1b; ② 不能用0代表false&#xff1b;用1代表 true&am…

德人合科技 | —数据泄露可能会对公司造成哪些影响?

数据泄露可能会对公司造成多方面的影响&#xff0c;以下是一些可能的影响&#xff1a; 财务损失&#xff1a;数据泄露可能导致公司遭受财务损失。攻击者可能会盗取公司的敏感信息&#xff0c;如客户信息、银行账户信息、商业机密等&#xff0c;并利用这些信息进行欺诈、盗窃等非…

本地maven库缓存导入私库

为了加速编译代码&#xff0c;想将本地maven缓存导入内网私库使用。 脚本网上搜的 #!/bin/bash # copy and run this script to the root of the repository directory containing files # this script attempts to exclude uploading itself explicitly so the script name …