第二十一章 硬件随机数实验
[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寄存器各位描述
该寄存器只有
bit2和
bit3有效,用于使能随机数发生器和中断。我们一般不用中断,所以只需要设置
bit2为
1,使能随机数发生器即可。
然后,我们看看
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_SR的
DRDY位置位后,我们就可以读取该寄存器获得
32位随机数值。此寄存器在最多
40个
PLL48CK时钟周期后,又可以提供新的随机数值。
至此,随机数发生器的寄存器,我们就介绍完了。接下来,我们看看要使用库函数操作随机数发生器,应该如何设置。
首先,我们要说明的是,库函数中随机数发生器相关的操作在文件
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
一周热门 更多>