IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F407ZG 随机数发生器RNG -> 正文阅读

[嵌入式]STM32F407ZG 随机数发生器RNG

硬件随机数发生器

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

  • 提供由模拟量发生器产生的 32 位随机数
  • 两个连续随机数的间隔为 40 个 PLL48CLK 时钟信号周期
  • 通过监视 RNG 熵来标识异常行为(产生稳定值,或产生稳定的值序列)
  • 可被禁止以降低功耗

原理

原理图

LFSR寄存器的原理介绍:详解线性反馈移位寄存器(LFSR)——引用知乎:come back

随机数发生器采用模拟电路实现。此电路产生馈入线性反馈移位寄存器 (RNG_LFSR) 的种子, 用于生成 32 位随机数。
该模拟电路由几个环形振荡器组成,振荡器的输出进行异或运算以产生种子。RNG_LFSR由专用时钟 (PLL48CLK) 按恒定频率提供时钟信息,因此随机数质量与 HCLK 频率无关。当将大量种子引入RNG_LFSR 后,RNG_LFSR 的内容会传入数据寄存器 (RNG_DR)。
同时,系统会监视模拟种子和专用时钟 PLL48CLK。状态位(RNG_SR 寄存器中)指示何时在种子上出现异常序列,或指示何时 PLL48CLK 时钟频率过低。检测到错误时生成中断。

寄存器

RNG 与控制寄存器、数据寄存器和状态寄存器相关联。必须通过字(32 位)进行访问

RNG 控制寄存器 (RNG_CR)

CR

仅使用2、3位,其他位保留,必须保持复位值。

CR

RNG 状态寄存器 (RNG_SR)

SR
SR
SR

RNG 数据寄存器 (RNG_DR)

RNG_DR 寄存器是只读寄存器,在读取时提供 32 位随机数值。读取后,此寄存器在最多 40 个 PLL48CLK 时钟周期后,提供新的随机数值。在读取 RNDATA 值之前,软件必须检查 DRDY 位是否已置 1。

实验

使用RNG生成随机数,通过串口显示。
此实验仅获取随机数,暂不对随机数产生错误时的中断做出处理。

使用及配置步骤

  1. 使能RNG时钟。该时钟来自PLL48CK。
  2. 使能RNG,即CR中的RNGEN位置1。
  3. 根据SR中的DRDY标志位可以判断是否能读取随机数。

代码

串口的作用只做显示,无需从PC发送数据,因此也无需配置中断。此处我直接使用了我另一篇文章 串口通信+固定首尾帧传输数据 中的串口配置源文件和头文件,不再贴出。

rng.c

/*********************************
    函数名:rng_init
    简介:初始化RNG
    参数:无
    返回:0 --初始化成功
         1 --初始化超时,失败
**********************************/
uint8_t rng_init(void)
{
    uint16_t retry = 0;
    
    //使能RNG时钟
    RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
    RNG_Cmd(ENABLE);//使能RNG
    
    while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET && retry < 10000)
    {
        retry++;
        delay_us(100);
    }
    if(retry >= 10000)return 1;//100us×10000=1s
    return 0;
}

/*********************************
    函数名:rng_get_random
    简介:获取32位随机数
    参数:无
    返回:32位随机数
**********************************/
uint32_t rng_get_random(void)
{
    while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET);//等待至随机数准备好
    return RNG_GetRandomNumber();
}

/*********************************
    函数名:rng_get_range_random
    简介:获取[min, max]内随机整数
    参数:int min --下限
          int max --上限
    返回:[min, max]内随机整数
**********************************/
int rng_get_range_random(int min, int max)
{
    return rng_get_random() % (max - min + 1) + min;
}

main.c

#include "delay.h"
#include "usart.h"
#include "led.h"
#include "rng.h"

int main(void)
{
    uint32_t random;
    int num;
    
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置系统中断优先级分组2
    delay_init(168);		//延时初始化
    usart_init(); //串口初始化波特率为115200
    LED_Init(); //初始化与LED连接的硬件接口
    
    while(rng_init()) //初始化RNG
    {
        delay_ms(200);
        printf("RNG准备中...");
        printf("\r\n\r\n");
    }
    printf("RNG准备完成!");
    printf("\r\n\r\n");
    
    while(1)
    {
        LED0 = !LED0;
        random = rng_get_random();
        //USART_SendData(USART3, random);
        //while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET);
        printf("%u", random);
        printf("\r\n\r\n");
        delay_ms(200);
        
        num = rng_get_range_random(0, 9);
        //USART_SendData(USART3, (u16)num);
        //while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET);
        printf("%u", num);
        printf("\r\n\r\n");
        while(USART_GetFlagStatus(USART3, USART_FLAG_TC) != SET);
        delay_ms(200);
	}
}

另外,之所以能使用 printf 函数在串口中打印数据,是在 usart.c 中有如下预编译代码:

//支持printf
#if 1
#pragma import(__use_no_semihosting) //不使用半主机模式
//标准库需要的支持函数
struct __FILE 
{ 
	int handle; 
}; 

FILE __stdout;
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x)
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{
	while((USART3->SR & 0X40)==0);//循环发送,直到发送完毕,这里根据自己使用的串口更改
	USART3->DR = (u8) ch;      
	return ch;
}
#endif

实验结果

如图所示,每200ms分别显示一个二进制32位随机数和一个0到9间的随机整数(十进制显示)。
实验结果

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:22:29  更:2022-08-19 19:25:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 12:25:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码