8位单片机产生随机数文档格式.docx
《8位单片机产生随机数文档格式.docx》由会员分享,可在线阅读,更多相关《8位单片机产生随机数文档格式.docx(29页珍藏版)》请在冰点文库上搜索。
Q0003:
MOV
R4,08H
0003
AC08
R5,09H
0005
AD09
R6,0AH
0007
AE0A
R7,0BH
0009
AF0B
R0,#0FH
000B
780F
Q000D:
A,R7
000D
EF
C,ACC.2
000E
A2E2
A,R4
0010
EC
JB
ACC.6,Q0015
0011
20E601
CPL
C
0014
B3
Q0015:
ANL
A,R5
0015
5D
A,R6
0016
5E
0017
5F
A
0018
F4
JNZ
Q001F
0019
7004
R4,A
001B
FC
R5,A
001C
FD
R6,A
001D
FE
R7,A
001E
FF
Q001F:
001F
RRC
0020
13
0021
0022
EE
&
nb
3楼:
53:
2、一个简单的随机数发生函数:
rand8reg是得到的随机数,为了更随机,可以把它与定时器相加
如果可以把rand8reg保存在非易失性存储器中更好,但是什么时候保存需要认真考虑
==============================================================
NAME:
rand8
DESCRIPTION:
geta8bitrandomNUMBER
Function:
Thisroutinesendscalca8bitrandomNUMBER
Attention:
getarandom"
rand8reg"
beforeinitializetheprogram
Calls:
None
Input:
rand8reg
Outputs:
RegisterUsage:
A,psw
--------------------------------------------------------------
rand8:
mov
a,rand8reg
jnz
rand8b
cpl
a
rand8reg,a
rand8b:
anl
a,#10111000b
c,p
rlc
ret
00:
50修改者:
4楼:
后学于2005-3-2914:
25:
3、这个可能复杂一些:
其实和周航慈《单片机程序设计基础》上的例子是一样的,使用线性移位寄存器构成随机数发生器
**********************************************************;
*
Random
*;
*Random_Buf6个字节看成48个位,可以表示280亿个数值,原理:
用反*;
*馈函数F()把这280亿个无顺序的放在一个可以旋转数码盘上,程序
*有定时器在跑,当随机发生时,让转盘转计数器的值圈数即可得到一个*;
*随机数.
*奇校验反馈函数d0=d48+d7+d5+d4+d2+d1+1,6Byte有280亿种状态*;
Random:
PUSH
ACC
RandomREG,Count
Data_Rotate:
A,Random_Buf+5
取D41-D48的当前状态
RLC
将D48提取到标志中去
A,Random_Buf
取D1-D8的当前状态
A,#5BH
提取D7,D5,D4,D2,D1的当前值
ACC.7,C
再加上D48的当前值
C,PSW.0
取得偶校验的结果
转换成奇校验,且得到反馈函数的值
开始移位操作,先处理低字节
将反馈函数的值移入,最高位移出
Random_Buf,A
保存移位后的结果
A,Random_Buf+1
再依次进行其他字节的移位操作
A
Random_Buf+1,A
A,Random_Buf+2
Random_Buf+2,A
A,Random_Buf+3
Random_Buf+3,A
A,Random_Buf+4
Random_Buf+4,A
A,Random_Buf+5
Random_Buf+5,A
完成巨型数字转盘转动一格
DJNZ
RandomREG,Data_Rotate
取当前时间随机时间转动n格
Random_Exit:
POP
RET
2005-3-308:
40:
39修改者:
5楼:
29:
4、我最终使用的程序
使用一个简单的随机数发生器产生种子
运行中用TL0作为干扰
TEST.asm
TEST
创建及修改记录
-------------------------------------------------------------
创建人:
创建时间:
文件名:
程序功能:
初始版本:
修改日期:
修改原因:
修改人:
版本更改:
Define
STACK_TOP
EQU
0D0H
STACK:
48Bytes
Random_Buf
70H
VARIABLE
BUFFER(70H~75H)
RND0
第1字节
RND1
71H
第2字节
RND2
72H
第3字节
RND3
73H
第4字节
RND4
74H
第5字节
RND5
75H
第6字节
RandCount
76H
VAIRABLE
跳动格数
rand8reg
77H
简单随机数,用来产生种子和跳动格数
MAINPROGRAM:
程序入口
ORG0000H
mainprogram
LJMP
main
ORG0003H
Int0Interrupt
RETI
ORG000BH
T0Interrupt
ORG0013H
Int1Interrupt
ORG001BH
T1Interrupt
ORG0023H
Si1Interrupt
ORG002BH
T2Interrupt
ORG0033H
ORG003BH
Si2Interrupt
ORG0043H
Int2Interrupt
ORG004BH
Int3Interrupt
ORG0053H
Int4Interrupt
ORG005BH
Int5Interrupt
ORG0063H
WatchDogInterrupt
ORG0100H
main:
CLR
EA
ResetRAM
R0,#0FFH
ResetRam:
@R0,#00H
R0,ResetRam
SP,#STACK_TOP
LCALL
Init_Random
初始化随机数发生器
R0,#20H
R1,#40H
RANDLOOP:
产生随机数
A,RND0
@R0,A
把随机数暂存到RAM中
INC
R0
R1,RANDLOOP
循环取40H个随机数
NOP
main
Init_Random
initializetherandom
givetheVALUEofRandom_BufandRandCount
Random_Buf,RandCount
Random_Buf
Init_Random:
ADD
A,B
A,R0
A,R1
nbs
8位单片机随机数 2007-09-1823:
27
分类:
单片机
字号:
大大
中中
小小
8位单片机很多地方需要随机数,比如游戏的洗牌,可在timer中取数,但是随机数质
量不高。
随机数是一个既简单又复杂的问题,这里的例子使用了众所周知的线性叠加法,没
有完美的方法产生随机数,不过线性叠加法是一个合适的方法,彻底解决8位机随机数的问
题。
伪随机数函数总是返回可预知的数字,像抛骰子,如果抛足够多次,那么我们得到了一
个足够长的数字序列,
3,1,5,1,4,6,5,4,6,5,4,5,6,1,3,2,1,6,4,6,5,4,3,2,1,3,2,1,4,2,3,1,3......
如果从序列中一个接一个的取出数字,那么数字就看似随机。
问题的关键是从这序列的哪个点(数字)开始取数?
这个开始的点(数字)叫做种子。
注意,如果从相同的点(种子)开始,将会得到相同的数字,这是因为我们是从固定的序
列中取数字(所以叫伪随机)。
但这却是一个有用的特性,我们可以每次从不同的点取数,即
改变种子!
在6502上,8位或16位随机数是最常用的,函数返回一个32位的数字,范围0~2^32。
名
词"
线性叠加"
听起来容易范晕,其实只涉及二个内容:
乘法和加法。
三个步骤:
1.为了取得新的种子(也就是从序列开始的那个点的数字),旧的种子和一个常数A相乘,
2.所得结果然后和第二个常数c相加。
3.新的种子是结果的低32位(记住,这个函数返回32位数字)。
保留低32位很重要,用来获
得下一个种子。
计算公式:
种子=A*种子+C
此公式在几何图中表示一条直线,而且新种子由旧种子反复相加得来,所以叫线性叠加。
随机数函数的关键在于选择优秀的"
常数A"
(也叫乘数A),其实也就是选择了一个固定
的数字序列。
"
常数c"
不像乘数A那样重要,但是它一定是个奇数。
事实上,c可选1,而
且这是例程所使用的,因为它会简化计算。
注意,奇数(旧的种子)乘奇数(乘数A)是奇数,再加奇数(常数c)将会是一个偶数;
偶数
(旧的种子)乘奇数(乘数A),加奇数(常数c)将会是一个奇数。
如此种子将会在奇数和偶数之
间转变。
因为种子的变化足够随机,所以新种子的值可以作为8位或16位随机数。
子程序F_RandomSeed,计算"
种子=乘数*种子+1"
(记得,c=1)。
有三个版本:
(1)快速版本,速度快,但占用Rom多。
(2)兼顾版本,速度和占用Rom适中,空间和速度是在另外二个版本之间。
兼顾版B,使用了另一个神奇的数字66066(10进制).
(3)最小版本,速度慢,但占用Rom小。
三个版本中使用的乘数1664525(10进制)=19660D(16进制),是从&
lt;
计算机程序的艺术,
第2册&
gt;
一书中选出,这是一个神奇的数字,经过论证和测试,这个数字对产生随机数至
关重要。
想进一步研究的朋友可以阅读原著(参考资料2),书中以特别专业的数学方法讨论
了随机数问题。
这里只是应用了其中的两个常数1664525(10进制)和69069(10进制),这里不
作讨论,因为篇幅问题是借口,其实自己没弄懂。
==============================================================================
快速版本
丰收先要选好种子,育种很重要,同样,获得随机种子是重要的一步。
种子变量设定在零页RAM可以提高速度。
程序F_RandomSeed计算1664525*种子,需要5个字节(R_Seed0~R_Seed3,R_Temp)。
F_GeneratTables预先计算1664525*X(x=0~255),生成四个256字节的列表T3,T2,T1,T0.
T3,X=表T3的第X字节=1664525*X的第31~24位(X=0to255)