STM32F4 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。
相关头文件和源码在stm32f4xx_rng.h/stm32f4xx_rng.c。
用到的硬件资源有:
1) 指示灯 DS0
2) 串口
3) KEY0 按键
4) 随机数发生器(RNG)
5) TFTLCD 模块
/* 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);
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++;
}
}
将程序下载到探索者 STM32F4 开发板后,可以看到 DS0 不停的闪烁,提示程序已经在运行了。同时每隔 250ms,获取一次区间[0,9]的随机数,实时显示在液晶上。然后我们也可以按下 KEY0,就可以在屏幕上看到获取到的随机数,
6.1 【STM32】STM32系列教程汇总
网址:【STM32】STM32系列教程汇总
该教程参考了正点原子的《STM32 F4 开发指南》