发新帖我要提问
12
返回列表
打印

想产生一个随机数

[复制链接]
楼主: qq604847322
手机看帖
扫描二维码
随时随地手机跟帖
21
yewuyi| | 2014-7-28 10:25 | 只看该作者 回帖奖励 |倒序浏览
MOn51 发表于 2014-7-28 10:23
这种方法我们用了快12年了。一直好用,如果觉得数据宽度还不够,可以整合到48位,64位。现在在STM32F405 ...

如果已经经过实战使用,那可信度提高不少。

另外,能否请问一下,你是用在什么样的应用中?

使用特权

评论回复
22
xlsf1048| | 2014-7-29 08:59 | 只看该作者
多个定时器,组合取值

使用特权

评论回复
23
wang47987146| | 2014-7-29 11:26 | 只看该作者
yewuyi 发表于 2014-7-28 09:25
有按键的,直接采集按键触发时的计数器数字做种子,因为每次按键触发事件是随机的,种子也就随机了。

AD ...

前些天我刚好碰到这个问题,用一个低成本的单片机,需要产生一个随机数,该单片机没有AD,电路也没有按键。尝试用软件延时和定时器直接的时间差来产生一个随机数,都无果。

后来有一位高人给我支招:加一个电容连接到单片机IO口上,上电时使得电容放完电,然后再充电,等待IO口变为高电平的时间。实际测试效果良好。

另一种方法是 定义一个变量不要赋值:
unsigned char X; //在每次上电时X的值都是不确定的,实际测试上电7次,有两次是重复的。

使用特权

评论回复
24
yewuyi| | 2014-7-29 11:48 | 只看该作者
xlsf1048 发表于 2014-7-29 08:59
多个定时器,组合取值

没用

使用特权

评论回复
25
yewuyi| | 2014-7-29 11:50 | 只看该作者
wang47987146 发表于 2014-7-29 11:26
前些天我刚好碰到这个问题,用一个低成本的单片机,需要产生一个随机数,该单片机没有AD,电路也没有按键 ...

随机范围很窄,还是利用的白噪声。

如果有备电,可以以开机时间点的定时器数值为随机数种子。

使用特权

评论回复
26
kamen588| | 2014-7-29 12:49 | 只看该作者
产生一个随机数不用那么麻烦吧 ??

我以前用过一下方法产生过随机数 凭**写一下 请自行测试

#include <stdlib.h> //包含 rand() 函数

float Random_Data;//定义一个浮点随机数 或者double类型的可以

//生成一个5 -999 之间的随机数 比如257.9865


Random_Data = rand()%999 + (rand()%999)*0.1+ (rand()%999)*0.01+ (rand()%999)*0.001+(rand()%999)*0.0001 + 5

//可以任意生成X-Y之间的任何随机数  Y最大值为 stdlid.h中的  RAND_MAX   

#ifndef RAND_MAX
#define RAND_MAX  32767u
#endif

可以修改上述定义 改变最大值

使用特权

评论回复
27
wang47987146| | 2014-7-29 13:19 | 只看该作者
本帖最后由 wang47987146 于 2014-7-29 13:20 编辑
yewuyi 发表于 2014-7-29 11:50
随机范围很窄,还是利用的白噪声。

如果有备电,可以以开机时间点的定时器数值为随机数种子。 ...

“随机范围很窄”,是指“用电容充电、放电的方法产生的随机数很小吗或者是随机数分布不均匀吗”?

我的方法是:定义一个CODE[10],给电容充电并计时,如果时间的个位数为偶数,则CODE[0]=1,
反之则为CODE[0]=0,由于电容有1uF,相对来说充电时间个位数的“奇、偶”还是相对随机的。然后把这些数合成一个大的随机数。

当然,如果用按键或者AD效果可能会好些。

顺便问一下前辈:PIC12F509每次上电定时的时间和上一次上电的时间都不一样,相差0.1ms,请问是要校准时钟吗?用C语言怎么表达?多谢!

使用特权

评论回复
28
yewuyi| | 2014-7-29 13:29 | 只看该作者
kamen588 发表于 2014-7-29 12:49
产生一个随机数不用那么麻烦吧 ??

我以前用过一下方法产生过随机数 凭**写一下 请自行测试

伪随机

使用特权

评论回复
29
yewuyi| | 2014-7-29 13:33 | 只看该作者
wang47987146 发表于 2014-7-29 13:19
“随机范围很窄”,是指“用电容充电、放电的方法产生的随机数很小吗或者是随机数分布不均匀吗”?

我的 ...

你的方法:上电时使得电容放完电,然后再充电,等待IO口变为高电平的时间

因为你每次放电和充电的时间是确定的,所以IO口变高电平的时间也基本确定了,虽然因为白噪声有微小的波动,但范围太窄了。

你如果再搞成奇、偶统计,最后会发现,已经谈不上随机了,因为白噪声的离散型又被你用统计学集中了。

PIC12F509每次上电定时的时间和上一次上电的时间都不一样,相差0.1ms,请问是要校准时钟吗?
没完全明白你这个问题。

使用特权

评论回复
30
wang47987146| | 2014-7-29 13:44 | 只看该作者
yewuyi 发表于 2014-7-29 13:33
你的方法:上电时使得电容放完电,然后再充电,等待IO口变为高电平的时间

因为你每次放电和充电的时间是 ...

确实,“用电容充电、放电的方法”,如果产生8位的随机数20次,会有大约2次是重复的,如果产生10位的随机数,操作20次还没有发现重复的,值的大小也比较分散。

是的,PIC12F509我想校准时钟试一下,效果会不会好些

使用特权

评论回复
31
kseeker| | 2014-7-29 14:21 | 只看该作者
本帖最后由 kseeker 于 2014-7-29 14:23 编辑
wang47987146 发表于 2014-7-29 13:44
确实,“用电容充电、放电的方法”,如果产生8位的随机数20次,会有大约2次是重复的,如果产生10位的随机 ...

这种方法得到的时间基本是个正态分布。想要平均分布的数据,可以只使用测得的时间的最低位。例如,8位时间如果大都分布在100到120之间,则离110越近就越多。但测8次时间,然后每次只取最低位,就得到了0到255之间平均分布的随机数。数据分布的方差越高,低位的分布就越好。校准时钟是没有任何意义的,这并不能够改变数据本身的方差,只是影响了平均值。有意义的是增加时钟分辨率,这样数据的方差就会变大(时钟越快,相对来说充电时间越不准)。这就是为什么10位的比8位的要好。如果方差足够大,可以使用最低的多位数,从而加快整个过程。以你的例子来开,10位情况下最低4位应该都是可用的。

使用特权

评论回复
32
wang47987146| | 2014-7-29 14:35 | 只看该作者
kseeker 发表于 2014-7-29 14:21
这种方法得到的时间基本是个正态分布。想要平均分布的数据,可以只使用测得的时间的最低位。例如,8位时间 ...

谢谢前辈的指点。

“校准时钟”是我的另外一个问题,与随机数无关。
PIC12F509,不管我是用软件延时,还是定时,每次上电与之前的测得的时间不一样,相差0.1ms,请问我是需要时钟校准吗?该怎么校准?

使用特权

评论回复
33
kseeker| | 2014-7-29 15:05 | 只看该作者
没用过这个片子,不过个人感觉0.1ms这么大的话应该不是时钟校准的问题。时钟不准也不会差出这么多。个人猜测可能是晶振起振太慢。高速晶振还好,32K晶振的话,stm32有的时候起振延迟可以到2秒(听说而已)。

使用特权

评论回复
34
kamen588| | 2014-7-29 20:23 | 只看该作者
本帖最后由 kamen588 于 2014-7-29 20:30 编辑
yewuyi 发表于 2014-7-29 13:29
伪随机

请教如何伪随机了  在我以前的测试里 没发现两个重复的数

使用特权

评论回复
35
yewuyi| | 2014-7-30 08:49 | 只看该作者
kamen588 发表于 2014-7-29 20:23
请教如何伪随机了  在我以前的测试里 没发现两个重复的数

伪随机是有规律可循的,你那个公式就是他的规律。

数字不重复完全不能说明是随机,例如执行i++,只要芯片数据宽度够,他的数值永远不会重复,但他和随机一点关系也么。

随机不代表绝对不重复,只代表重复是无规律的。

使用特权

评论回复
36
yewuyi| | 2014-7-30 08:49 | 只看该作者
kamen588 发表于 2014-7-29 20:23
请教如何伪随机了  在我以前的测试里 没发现两个重复的数

去看看概率论的书。

使用特权

评论回复
37
Rain_King| | 2014-7-30 22:17 | 只看该作者
对于单片机,用伪随机比较好......

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则