OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10632|回复: 6

【正点原子探索者STM32F407开发板例程连载+教学】第21章 随机数发生器实验-RNG

[复制链接]

230

主题

1950

帖子

10

精华

论坛元老

Rank: 8Rank: 8

积分
4562
金钱
4562
注册时间
2010-12-14
在线时间
32 小时
发表于 2014-12-6 12:39:22 | 显示全部楼层 |阅读模式

第二十一章 硬件随机数实验

     

[mw_shl_code=c,true]1.硬件平台:正点原子探索者STM32F407开发板 2.软件平台:MDK5.1 3.固件库版本:V1.4.0 [/mw_shl_code]

 


本章我们将向大家介绍STM32F4的硬件随机数发生器。在本章中,我们将使用KEY0按键来获取硬件随机数,并且将获取到的随机数值显示在LCD上面,同时,使用DS0指示程序运行状态。本章将分为如下几个部分:

21.1 STM32F4随机数发生器简介

21.2 硬件设计

21.3 软件设计

21.4 下载验证

 

21.1 STM32F4随机数发生器简介

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


21.1.1 随机数发生器(RNG)框图

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

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

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

接下来,我们介绍下STM32F4随机数发生器(RNG)的几个寄存器。

首先是RNG控制寄存器:RNG_CR,该寄存器各位描述如图21.1.2所示:

21.1.2 RNG_CR寄存器各位描述

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

       然后,我们看看RNG状态寄存器:RNG_SR,该寄存器各位描述如图21.1.3所示:

21.1.3 RNG_SR寄存器各位描述

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

       最后,我们看看 RNG数据寄存器:RNG_DR,该寄存器各位描述如图21.1.4所示:

21.1.4 RNG_DR寄存器各位描述

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

       至此,随机数发生器的寄存器,我们就介绍完了。接下来,我们看看要使用库函数操作随机数发生器,应该如何设置。

       首先,我们要说明的是,库函数中随机数发生器相关的操作在文件stm32f4xx_rng.c和对应的头文件stm32f4xx_rng.h中。所以我们实验工程必须引入这两个文件。

随机数发生器操作步骤如下:

1)使能随机数发生器时钟。

要使用随机数发生器,必须先使能其时钟。随机数发生器时钟来自PLL48CK,通过AHB2ENR寄存器使能。 所以我们调用使能AHB2总线外设时钟的函数使能RNG时钟即可:

 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);//开启RNG时钟

2)使能随机数发生器。

这个就是通过RNG_CR寄存器的最低位设置为1,使能随机数发生器。当然,如果需要用到中断,你快还可以使能RNG中断。本章我们不用中断。库函数中使能随机数发生器的方法为:

RNG_Cmd(ENABLE);  //使能RNG

3)判断DRDY位,读取随机数值。

经过前面两个步骤,我们就可以读取随机数值了,不过每次读取之前,必须先判断RNG_SR寄存器的DRDY位,如果该位为1,则可以读取RNG_DR得到随机数值,如果不为1,则需要等待。

在库函数中,获取随机数发生器状态的函数为:

FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);

库函数中,判断数据是否有效的入口参数为RNG_FLAG_DRDY,所以等待就绪的方法为:

while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET);

判断数据有效后,然后我们读取随机数发生器产生的随机数即可,调用函数为:

uint32_t RNG_GetRandomNumber(void);

通过以上几个步骤的设置,我们就可以使用STM32F4的随机数发生器(RNG)了。本章,我们将实现如下功能:通过KEY0获取随机数,并将获取到的随机数显示在LCD上面,通过DS0指示程序运行状态。

21.2 硬件设计

本实验用到的硬件资源有:

1)  指示灯DS0

2)  串口

3)  KEY0按键

4)  随机数发生器(RNG)

5)  TFTLCD模块

这些资源,我们都已经介绍了,硬件连接上面也不需要任何变动,插上TFTLCD模块即可。

21.3 软件设计

打开本章的实验工程可以看到,我们在FWLIB下面添加了随机数发生器支持库函数stm32f4xx_rng.c和对应的头文件stm32f4xx_rng.h。同时我们编写的随机数发生器相关的函数在新增的文件rng.c中。

接下来我们看看rng.c源文件内容:

//初始化RNG

//返回值:0,成功;1,失败

u8 RNG_Init(void)

{

       u16 retry=0;

       RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); //开启RNG时钟  

RNG_Cmd(ENABLE);  //使能RNG

       while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET&&retry<10000)//等待就绪

       {   retry++;  delay_us(100);

       }

       if(retry>=10000)return 1;//随机数产生器工作不正常

       return 0;

}

//得到随机数

//返回值:获取到的随机数

u32 RNG_Get_RandomNum(void)

{    

       while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET);    //等待随机数就绪 

       return RNG_GetRandomNumber();      }

//生成[min,max]范围的随机数

int RNG_Get_RandomRange(int min,int max)

{

   return RNG_Get_RandomNum()%(max-min+1) +min;

}

该部分总共3个函数,其中:RNG_Init用于初始化随机数发生器;RNG_Get_RandomNum用于读取随机数值;RNG_Get_RandomRange用于读取一个特定范围内的随机数,实际上也是调用的前一个函数RNG_Get_RandomNum来实现的。这些函数的实现方法都比较好理解。

rng.h头文件内容就主要是三个函数申明,比较简单,这里我们就不做讲解。

最后我们看看main.c文件内容:

int main(void)

{

       u32 random; u8 t=0,key;

       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2

       delay_init(168);  //初始化延时函数

       uart_init(115200);  //初始化串口波特率为115200

       LED_Init();           //初始化LED

       KEY_Init();           //按键初始化

      LCD_Init();       //初始化液晶接口

       POINT_COLOR=RED;

       LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");      

       LCD_ShowString(30,70,200,16,16,"RNG TEST");    

       LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");

       LCD_ShowString(30,110,200,16,16,"2014/5/5");      

       while(RNG_Init())             //初始化随机数发生器

       {

              LCD_ShowString(30,130,200,16,16,"  RNG Error! ");    

              delay_ms(200);

              LCD_ShowString(30,130,200,16,16,"RNG Trying...");     

       }                                

       LCD_ShowString(30,130,200,16,16,"RNG Ready!   ");  

       LCD_ShowString(30,150,200,16,16,"KEY0:Get Random Num");    

       LCD_ShowString(30,180,200,16,16,"Random Num:");     

 

       POINT_COLOR=BLUE;

       while(1)

       {           

              delay_ms(10);

              key=KEY_Scan(0);

              if(key==KEY0_PRES)

              {   random=RNG_Get_RandomNum(); //获得随机数

                     LCD_ShowNum(30+8*11,180,random,10,16); //显示随机数

              }

              if((t%20)==0)

{  LED0=!LED0;  //200ms,翻转一次LED0

random=RNG_Get_RandomRange(0,9);//获取[0,9]区间的随机数

LCD_ShowNum(30+8*22,210,random,2,16); //显示随机数

}

              delay_ms(10); t++;

       }    

该部分代码也比较简单,在所有外设初始化成功后,进入死循环,等待按键按下,如果KEY0按下,则调用RNG_Get_RandomNum函数,读取随机数值,并将读到的随机数显示在LCD上面。每隔200ms获取一次区间[0,9]的随机数,并实时显示在液晶上。同时DS0,周期性闪烁,400ms闪烁一次。这就实现了前面我们所说的功能。

至此,本实验的软件设计就完成了,接下来就让我们来检验一下,我们的程序是否正确了。

21.4 下载验证

将程序下载到探索者STM32F4开发板后,可以看到DS0不停的闪烁,提示程序已经在运行了。同时每隔200ms,获取一次区间[0,9]的随机数,实时显示在液晶上。然后我们也可以按下KEY0,就可以在屏幕上看到获取到的随机数,如图21.4.1所示:

 

21.4.1 获取随机数成功

 

 实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm 

正点原子探索者STM32F407开发板购买地址http://item.taobao.com/item.htm?id=41855882779

  


第二十一章 硬件随机数实验-STM32F4开发指南-正点原子探索者STM32开发板.pdf

615.18 KB, 下载次数: 686

实验16 随机数发生器实验.zip

520.48 KB, 下载次数: 749

我是开源电子网?网站管理员,对网站有任何问题,请与我联系!QQ:389063473Email:389063473@qq.com
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

34

主题

149

帖子

0

精华

高级会员

Rank: 4

积分
889
金钱
889
注册时间
2012-9-11
在线时间
153 小时
发表于 2015-6-19 15:45:38 | 显示全部楼层
http://url.cn/PqU0jG
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2015-6-19 23:46:58 | 显示全部楼层
回复【2楼】physics:
---------------------------------
没哟
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

21

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
372
金钱
372
注册时间
2015-11-12
在线时间
83 小时
发表于 2016-9-23 10:46:36 | 显示全部楼层
F1怎么产生随机数呀?我使用rand后一直报错,头疼,有哪位大侠用F1产生过随机数吗?
回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
186
金钱
186
注册时间
2015-10-12
在线时间
48 小时
发表于 2016-12-8 14:06:46 | 显示全部楼层


KEIL MDK V5
F4标准库 1.8
ST-LINK V2

int main()
{
    uint32_t rng;
   
    RCC_AHB2PeriphResetCmd(RCC_AHB2Periph_RNG, ENABLE);
    RNG_Cmd(ENABLE);
   
    while (RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET); 《======== 程序永远卡在这里,寄存器不置位

    rng = RNG_GetRandomNumber();


    while (1){}






请问,这是为什么?难道F407不支持RNG?
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
131
金钱
131
注册时间
2018-6-23
在线时间
18 小时
发表于 2019-1-8 20:20:49 | 显示全部楼层
adylee 发表于 2016-12-8 14:06
**** 作者被禁止或删除 内容自动屏蔽 ****

while后面加;了
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
4
金钱
4
注册时间
2021-12-3
在线时间
1 小时
发表于 2021-12-3 20:07:24 | 显示全部楼层
为什么我stm32f4探索版烧不进去啊,一开始没有flash,复制进去,加入flash还是烧不进去
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 09:50

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表