【正點原子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.pswp.cn/news/713539.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/713539.shtml
英文地址,請注明出處:http://en.pswp.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…

Python內置函數11——globals()、locals()

文章目錄 概要基礎用法 概要 globals()和locals()都是內置函數&#xff0c;用于獲取當前命名空間中的變量。 globals()函數返回全局命名空間的字典&#xff0c;包括全局變量、函數和模塊。它返回一個表示全局命名空間的字典。你可以使用該函數來查看和修改全局命名空間中的變量…

深入剖析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;但是報一個出錯…

4 在QEMU硬件模擬器中運行開源鴻蒙OpenHarmony4.1的操作系統,無需實體開發板

在QEMU硬件模擬器中運行開源鴻蒙OpenHarmony4.1的操作系統&#xff0c;無需實體開發板 作者將狼才鯨日期2024-03-01 先下載源碼和編譯程序&#xff1a; 查看 開源鴻蒙OpenHarmony4.1源碼下載、編譯&#xff0c;生成OHOS_Image可執行文件的最簡易流程 我準備在QEMU模擬器中運行…

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…

速盾:動態網站用cdn更慢嗎

當談到網站速度時&#xff0c;內容傳遞網絡&#xff08;Content Delivery Network&#xff0c;CDN&#xff09;是不可忽視的一個因素。很多人可能有疑惑&#xff0c;動態網站使用CDN是否會導致加載速度變慢。為了解決這個問題&#xff0c;我們需要了解動態網站和CDN的工作原理&…

mybatis動態加載mapper.xml

mybatis動態加載mapper.xml mybatis動態加載mapper.xml、springboot mybatis動態加載mapper.xml 教程連接&#xff1a;https://blog.csdn.net/weixin_44480167/article/details/136356398

測試linux系統某些文件屬性之test命令

要檢測系統上某些文件或相關屬性時&#xff0c;我們可以使用test命令&#xff0c;比如&#xff1a;檢查/root/ztj.txt文件是否存在&#xff0c;可以使用test -e /root/ztj.txt命令&#xff0c;不過執行結果不會顯示任何信息&#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;…

【C語言】字符型變量and整型變量的類型轉換

一、將字符型變量轉換為整型變量 char c A; int i (int)c; 二、將整型變量轉換成字符型變量 int i 65; char c (char)i;

Unity 實戰一:這幾年被廣告刷屏的沙雕跑酷游戲

姐就是女王&#xff0c;功夫跑酷&#xff0c;揀槍干架跑酷等 核心不用說了吧&#xff1a; 就是一個人不斷地跑&#xff0c;獲取不同屬性&#xff0c;判斷是否過關 好的&#xff0c;以下是一篇基于Unity 開發簡易版有障礙物的跑酷游戲的教程博客&#xff1a; 在這篇博客中&…