rand()和srand()函數原型:
int?rand(void)?返回一個范圍在 0 到?RAND_MAX?之間的偽隨機數。
void?srand(unsigned int?seed)用來給rand()?設置隨機數發生器,隨機數發生器輸出不同的數值,rand()?就會生成不同的隨機數
1)、在“D:\Keil_v5\ARM\ARMCC\include\stdlib.h”中,有下面的定義:
#ifdef?__USE_ANSI_EXAMPLE_RAND
#define?srand _ANSI_srand
#define?rand _ANSI_rand
#define?RAND_MAX 0x7fff
#else
#define?RAND_MAX 0x7fffffff??/*MDK-ARM默認使用RAND_MAX為0x7fffffff*/
#endif
MDK-ARM默認使用RAND_MAX為0x7fffffff。
2)、在“D:\Keil_v5\ARM\ARMCC\include\time.h”中,有下面的定義:
extern _ARMABI time_t time(time_t * /*timer*/);
但是time沒有具體的函數,因此“srand((unsigned int)time(NULL))”就不能用了。
srand()函數用來生成“隨機數種子”。當我們使用相同的種子時,將生成相同的隨機數序列。為了能通讓rand()函數生成不同的隨機數,可以使用“TIM1的計數器值”作為作為種子值。因為“TIM1的計數器值”是不斷變化的,這樣每次運行rand()函數,就可以生成不同的隨機數序列。
3)、測試rand()和srand()函數
void?TIM1_Interrupt_Initializtion(u16 arr,u16 psc);//函數聲明
//定時器1中斷初始化
//APB2時鐘為72MHz
//arr:自動重裝值。
//psc:時鐘預分頻數
//TIM_CKD_DIV1:定時器時鐘 = 輸入頻率
//TIM_CKD_DIV2:定時器時鐘 = 輸入頻率/2
//TIM_CKD_DIV4:定時器時鐘 = 輸入頻率/4
//TIM1溢出時間: arr*psc/72000000/TIM_CKD_DIVx
//TIM1_Interrupt_Initializtion(1000,72);
//當arr=1000,psc=72時,則為1ms,誤差為1us;
void?TIM1_Interrupt_Initializtion(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef ?TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//使能定時器TIM1的APB2外設時鐘
//定時器TIM1初始化
TIM_TimeBaseStructure.TIM_Period = arr-1;
//設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc-1;
//設置用來作為TIMx時鐘頻率除數的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//設置時鐘分割:TDTS = Tck_tim
//計算公式:arr*psc/72000000/1,當arr=1000,psc=72時,則為1ms,誤差為1us;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM向上計數模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//根據指定的參數初始化TIMx的時間基數單位
? TIM_SetCounter(TIM1,0); ?????????????????????//設置TIM1的計數器值為0;
??TIM_ClearFlag(TIM1, TIM_FLAG_Update); ???????//清除TIM1溢出的待處理標志位
TIM_ClearITPendingBit(TIM1, TIM_IT_Update ); //清除TIM1中斷的待處理位
// TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE ); //允許TIM1溢出產生中斷
/*中斷優先級NVIC設置
NVIC_PriorityGroup_4設置NVIC中斷分組4:表示搶占優先級為4位,取值為0~15,沒有響應優先級,取值為0
NVIC_PriorityGroup_3設置NVIC中斷分組3:表示搶占優先級為3位,取值為0~7,響應優先級只有1位,取值為0~1
NVIC_PriorityGroup_2設置NVIC中斷分組3:表示搶占優先級為2位,取值為0~3,響應優先級只有2位,取值為0~3
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; ?//TIM1中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11; ?//設置搶占優先級為11
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; ?//設置響應優先級為0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ????//IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化NVIC嵌套向量中斷控制寄存器
*/
TIM_Cmd(TIM1, ENABLE);//使能TIM1外設
}
#include?"stdlib.h"
//rand()和srand()需要包含stdlib.h頭文件
void?Test_rand_And_srand(void)
{
unsigned int?rand_Value;//聲明無符號32位變量rand_Value
unsigned int?ms;//聲明無符號32位變量ms
rand_Value=rand(); //返回一個范圍在0到RAND_MAX之間的偽隨機數
ms=rand_Value%1000+1;//ms為1到1000之間的數
printf("ms=%u\r\n",ms);
}
int?main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4
USART1_Serial_Interface_Enable(115200);
printf("\r\nCPU reset\r\n");
????TIM1_Interrupt_Initializtion(1000,72);
//當arr=1000,psc=72時,則為1ms,誤差為1us;
srand( TIM_GetCounter(TIM1) );//使用“TIM1的計數器值”作為作為種子值
??while(1)
??{
Test_rand_And_srand();
??}
}
仿真結果:
3)、在MDK-ARM中,不用srand()設置隨機數發生器,也可以使用rand()得到不同的隨機數。
#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "USART1.h"
//注意:"USART1.h"要放在 "stdio.h" 包含文件之后,如果這個位置顛倒了,業不能打印浮點數。#include "stdlib.h"
//rand()需要包含stdlib.h頭文件void Test_Rand(void)
{unsigned int rand_Value;//聲明無符號32位變量rand_Valueunsigned int ms;//聲明無符號32位變量msrand_Value=rand(); //返回一個范圍在0到RAND_MAX之間的偽隨機數printf("rand_Value=%u\r\n",rand_Value);ms=rand_Value%1000+1;//ms為1到1000之間的數printf("ms=%u\r\n",ms);
}int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4USART1_Serial_Interface_Enable(115200);printf("\r\nCPU reset\r\n");while(1){Test_Rand();}
}
?仿真結果如下:
4)、如果在調用rand()前,每次都使用srand()設置一個常數作為種子,就會得到相同的隨機數。
#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "USART1.h"
//注意:"USART1.h"要放在 "stdio.h" 包含文件之后,如果這個位置顛倒了,業不能打印浮點數。#include "stdlib.h"
//rand()需要包含stdlib.h頭文件void Test_Rand(void)
{unsigned int rand_Value;//聲明無符號32位變量rand_Valueunsigned int ms;//聲明無符號32位變量mssrand(1);rand_Value=rand(); //返回一個范圍在0到RAND_MAX之間的偽隨機數printf("rand_Value=%u\r\n",rand_Value);ms=rand_Value%1000+1;//ms為1到1000之間的數printf("ms=%u\r\n",ms);
}int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4USART1_Serial_Interface_Enable(115200);printf("\r\nCPU reset\r\n");while(1){Test_Rand();}
}
仿真結果:
5)、?如果在調用rand()前,只用一次srand()設置一個常數作為種子,可以得到不同的隨機數。
#include "stm32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "USART1.h"
//注意:"USART1.h"要放在 "stdio.h" 包含文件之后,如果這個位置顛倒了,業不能打印浮點數。#include "stdlib.h"
//rand()需要包含stdlib.h頭文件void Test_Rand(void)
{unsigned int rand_Value;//聲明無符號32位變量rand_Valueunsigned int ms;//聲明無符號32位變量msrand_Value=rand(); //返回一個范圍在0到RAND_MAX之間的偽隨機數printf("rand_Value=%u\r\n",rand_Value);ms=rand_Value%1000+1;//ms為1到1000之間的數printf("ms=%u\r\n",ms);
}int main(void){NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4USART1_Serial_Interface_Enable(115200);printf("\r\nCPU reset\r\n");srand(1);while(1){Test_Rand();}
}
仿真結果:
為什么在keil中,會出現這種結果?
在Keil環境中,如果不使用srand()函數,直接調用rand()函數也可以生成隨機數。調用rand()不但可以生成一個新的隨機數,而且也會更新“種子值”。