关于配置单片机生成随机数

发布时间 2023-09-20 15:21:39作者: ZaiLi

当单片机没有随机数发生器时,单片机一般用以下方法可以产生随机数:
1、直接使用C库函数rand()来生成随机数
该种用法下,一般配合定时器使用,通过获取定时器计数值,使用rand()函数来产生一个随机数。

2、利用ADC噪声产生随机数
由于噪声和生产误差等因素,ADC原始数据总会有波动,我们可以利用这些波动生成随机数。

使用C库函数rand()配合定时器产生随机数代码如下:

/********************************** (C) COPYRIGHT *******************************
* File Name          : main.c
* Author             : WCH
* Version            : V1.0.0
* Date               : 2021/06/06
* Description        : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for 
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/

/*
 *@Note
 USART Print debugging routine:
 USART1_Tx(PA9).
 This example demonstrates using USART1(PA9) as a print debug port output.

*/

#include "debug.h"
#include <stdio.h>
#include <stdlib.h>

/* Global typedef */

/* Global define */

/* Global Variable */

void GPIO_KEY_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure={0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void RAND_TIM_Init(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE);

    TIM_TimeBaseInitStructure.TIM_Period = 1000-1;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 48-1;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure );

    TIM_Cmd( TIM1, ENABLE );
}

void test_rand(u16 cnt)
{
    unsigned long n;
    srand(cnt);
    n = rand();
    printf("n=%d\n", n);
}
/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    u8 flag=1;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);    
    printf("SystemClk:%d\r\n",SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf("This is printf example\r\n");

    GPIO_KEY_Init();
    RAND_TIM_Init();

    while(1)
    {
        if((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==1)&&(flag==1))
        {
            flag = 0;
            printf("TIMCNT:%d\r\n",TIM_GetCounter(TIM1));
            test_rand(TIM_GetCounter(TIM1));
        }
    }
}