STM32F4 随机数发生器(RNG)的几个寄存器
RNG 控制寄存器:RNG_CR
该寄存器只有 bit2 和 bit3 有效,用于使能随机数发生器和中断。我们一般不用中断,所以 只需要设置 bit2 为 1,使能随机数发生器即可。
RNG 状态寄存器:RNG_SR
该寄存器我们仅关心最低位(DRDY 位),该位用于表示 RNG_DR 寄存器包含的随机数数 据是否有效,如果该位为 1,则说明 RNG_DR 的数据是有效的,可以读取出来了。读 RNG_DR 后,该位自动清零。
RNG 数据寄存器:RNG_DR
在 RNG_SR 的 DRDY 位置位后,我们就可以读取该寄存器获得 32 位随机数值。此寄存器 在最多 40 个 PLL48CK 时钟周期后,又可以提供新的随机数值。
随机数发生器操作步骤:
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);
RNG库函数
void RNG_DeInit(void);//复位
void RNG_Cmd(FunctionalState NewState);//使能RNG
uint32_t RNG_GetRandomNumber(void);//获取随机数
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初始化以及获得随机数函数
//初始化RNG
u8 RNG_Init(void)
{
u16 retry=0;
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);//开启RNG时钟,来自PLL48CLK
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;
}
main函数
int main(void)
{
u32 random;
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
KEY_Init(); //按键初始化
delay_ms(10000);
LED0=!LED0;
while(RNG_Init()) //初始化随机数发生器
{
printf("RNG Error!\r\n ");
delay_ms(200);
printf("RNG Trying...\r\n");
}
printf("RNG Ready!\r\n ");
printf("KEY0:Get Random Num\r\n");
printf("KEY1:Get Random Num[0,9]\r\n");
while(1)
{
delay_ms(10);
key=KEY_Scan(0);
if(key==KEY0_PRES)
{
random=RNG_Get_RandomNum(); //获得随机数
printf("Random Num:%d\r\n",random); //显示随机数
}
delay_ms(10);
key=KEY_Scan(0);
if(key== KEY1_PRES)
{
random=RNG_Get_RandomRange(0,9);//获取[0,9]区间的随机数
printf("Random Num[0,9]:%d\r\n",random); //显示随机数
}
//if((t%20)==0)
//LED0=!LED0; //每200ms,翻转一次LED0
//t++;
}
}
运行视频
随机数发生器实验