01. 概述
STM32F4 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。
相关头文件和源码在stm32f4xx_rng.h/stm32f4xx_rng.c。
02. 硬件模块
用到的硬件资源有:
1) 指示灯 DS0
2) 串口
3) KEY0 按键
4) 随机数发生器(RNG)
5) TFTLCD 模块
03. 相关函数
- /* Exported macro ------------------------------------------------------------*/
- /* Exported functions --------------------------------------------------------*/
- /* Function used to set the RNG configuration to the default reset state *****/
- void RNG_DeInit(void);
- /* Configuration function *****************************************************/
- void RNG_Cmd(FunctionalState NewState);
- /* Get 32 bit Random number function ******************************************/
- uint32_t RNG_GetRandomNumber(void);
- /* Interrupts and flags management functions **********************************/
- void RNG_ITConfig(FunctionalState NewState);
- FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);
- void RNG_ClearFlag(uint8_t RNG_FLAG);
- ITStatus RNG_GetITStatus(uint8_t RNG_IT);
- void RNG_ClearITPendingBit(uint8_t RNG_IT);
复制代码
04. 程序示例
rng.h文件
- #ifndef __RNG_H__
- #define __RNG_H__
- #include "sys.h"
- //初始化
- u8 RNG_Init(void);
- //获取随机数
- u32 RNG_Get_RandomNum(void);
- //获取范围内的随机数
- u32 RNG_Get_RandomRange(int min, int max);
- #endif/*__RNG_H__*/
复制代码
rng.c文件
- #include "rng.h"
- #include "delay.h"
- //初始化
- u8 RNG_Init(void)
- {
- u16 retry = 0;
-
- //使能时钟
- RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
-
- //使能RNG
- RNG_Cmd(ENABLE);
-
- //等待随机数就绪
- while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET && retry < 10000)
- {
- retry++;
-
- delay_us(100);
- }
-
- if (retry >= 10000)
- {
- return 1;
- }
-
- //获取第一个随机数丢弃处理
- //将 RNGEN 位置 1 后产生的第一个随机数不应使用,但应保存起来,
- //与产生的下一个随机数进行比较。随后产生的每个随机数都需要与
- //产生的上一个随机数进行比较。如果任何一对进行比较的数字相等,
- //则测试失败(连续随机数发生器测试)。
- RNG_GetRandomNumber();
- return 0;
- }
- //获取随机数
- u32 RNG_Get_RandomNum(void)
- {
- //等待随机数就绪
- while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET)
- /*Do Nothing*/;
- return RNG_GetRandomNumber();
- }
- //获取范围内的随机数
- u32 RNG_Get_RandomRange(int min, int max)
- {
- return RNG_Get_RandomNum() % (max - min + 1) + min;
- }
复制代码
main.c文件
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "led.h"
- #include "beep.h"
- #include "key.h"
- #include "usmart.h"
- #include "lcd.h"
- #include "rtc.h"
- #include "rng.h"
- #include "key.h"
- //LED状态设置函数
- void led_set(u8 sta)
- {
- LED1 = sta;
- }
- //函数参数调用测试函数
- void test_fun(void(*ledset)(u8), u8 sta)
- {
- ledset(sta);
- }
- int main(void)
- {
- u32 num = 0;
- u8 key = 0;
- u8 t = 0;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
-
- delay_init(168);
-
- uart_init(115200);
-
- usmart_dev.init(84);
-
- LED_Init();
-
- 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@tom");
- LCD_ShowString(30,110,200,16,16,"2020/09/10");
-
- //初始化随机数发生器
- 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: ");
- LCD_ShowString(30,210,200,16,16,"Random Num[0-9]: ");
-
- POINT_COLOR = BLUE;
-
- while(1)
- {
- delay_ms(20);
-
- key = Key_Scan();
- if (key == KEY0_PRESS)
- {
- //获取随机数
- num = RNG_Get_RandomNum();
- LCD_ShowNum(30 + 8 * 16, 180, num, 10, 16);
- }
-
-
- if ((t % 25) == 0)
- {
- LED1 = !LED1;
- //获取随机数
- num = RNG_Get_RandomRange(0, 9);
- LCD_ShowNum(30 + 8 * 16, 210, num, 1, 16);
- }
-
- t++;
- }
- }
复制代码
05. 结果验证
将程序下载到探索者 STM32F4 开发板后,可以看到 DS0 不停的闪烁,提示程序已经在运行了。同时每隔 250ms,获取一次区间[0,9]的随机数,实时显示在液晶上。然后我们也可以按下 KEY0,就可以在屏幕上看到获取到的随机数,
|