本帖最后由 lkl0305 于 2015-1-25 23:17 编辑
srand和rand()配合使用产生伪随机数序列。
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。
当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。
上个程序:ADC_Random.c
- <p>#include "adc_random.h"
- uint16_t Get_ADC_RandomSeek(void);</p><p>
- /*初始化ADC*/
- void ADC_RandomConfig(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);
- RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);
- GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
- GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);
- ADC_DeInit(ADC_RANDOM);
- ADC_StructInit(&ADC_InitStructure);
- ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
- ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
- ADC_Init(ADC_RANDOM, &ADC_InitStructure);
- ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
- ADC_GetCalibrationFactor(ADC_RANDOM);
- ADC_Cmd(ADC_RANDOM, ENABLE);
- while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY));
- }
- /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/
- uint16_t Get_ADC_RandomSeek(void)
- {
- uint8_t Count;
- uint16_t ADC_RandomSeek = 0;
- ADC_StartOfConversion(ADC_RANDOM);
- for(Count = 0; Count < 4; Count++){
- while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){
- ;
- }
- ADC_RandomSeek <<= 4;
- ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;
- }
- ADC_StopOfConversion(ADC_RANDOM);
- return ADC_RandomSeek;
- }
- /*拿种子产生随机数*/
- uint16_t Get_ADC_Random(void)
- {
- srand(Get_ADC_RandomSeek());
- return rand();
- }
- </p>
复制代码
接下来再主函数中需要的地方调用就可以了:
- int main(void)
- {
- uint16_t RandomNumber, RandomSeek;
- USART2_GPIO_Init();
-
- ADC_RandomConfig();
-
- while (1)
- {
- RandomSeek = Get_ADC_Random();
- srand(RandomSeek);
- RandomNumber = rand();
- printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);
- delay_ms(500);
- }
- }
复制代码 完整的程序:
ADC_Random.rar
(4.6 MB, 下载次数: 475)
|
或者说故意把AD的输入做的不稳定?不然每次相差一到两个字,那产生的随机器是不是也相对固定?
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
嗯那还可以,可以尝试从多个通道采集,随机选择
尽管拿去