導航:首頁 > 操作系統 > 單片機真隨機數

單片機真隨機數

發布時間:2023-11-10 08:00:36

① 怎樣在單片機C語言裡面產生一個0到100的隨機數

c語言本身並不能產生隨機數。
介紹一個比較簡單的隨機數獲取方法:啟動單片機的定時器,讓它自己跑不要發生溢出中斷,用戶操作時直接讀計數器數值,那基本上就是個隨機數。

② 51單片機產生隨機數c程序

剛寫的程序,我的思想是用定時器加rand()隨機函數來實現的,單片機上電之後通過按鍵去啟動取隨機數,若是單片機上電就立即取隨機數的話,那每次上電隨機的結果都是一樣的。然後是0到9不重復的隨機數,程序中用了循環來判斷是否和前面取的隨機數相同,相同則進入下次取隨機數,不同則存入數組。程序如下:#include<reg52.h>
#include<stdlib.h> //包含rand()隨機函數的頭文件
unsigned char t,k,i,j,a,f,n[10];
//t是計時變數,k是按鍵標志,i是數組下標,f是隨機數重復標志,n[10]是存放隨機數的數組
void init() //初始化函數
{
t=0;
i=0;
f=0;
k=0;
TMOD=0x02; //設置定時器0為工作方式2
TH0=7; //裝初值
TL0=7;
EA=1; //開總中斷
ET0=1; //開定時器0中斷
TR0=1; //啟動定時0
EX0=1; //開外部中斷0,同按鍵的效果一樣
IT0=1; //下降沿觸發
}
void main()
{
init();
while(1)
{
while(k) //外部中斷0觸發循環
{
if(!i) //i=0時取第一個隨機數放入數組n[0]
{
srand(t); //隨機數初始化
a=(char)(rand()%10); //取隨機數(0~9)
n[0]=a; //存入數組
i++; //數組下標加1
}
else
while(i<10) //存放剩下的9個隨機數
{
srand(t); //隨機數初始化
a=(char)(rand()%10); //取隨機數
for(j=0;j<i;j++) //與前面的隨機數比較
{
if(n[j]==a) //與前面的隨機數相同
f=1; //標志置1
}
if(f) //有重復執行
{
f=0; //標志清0
continue; //結束本次循環
}
n[i]=a; //不同則存入數組中
i++; //數組下標加1
}
}
}
}
void inter0() interrupt 0 //外部中斷0
{
k=1; //按鍵標志置1,主函數執行取隨機數
}
void time0() interrupt 1 //定時器0中斷
{
t++; //時間加1
if(t==100) t=0;
}

③ 單片機中如何求隨機數

單片機中取
隨機數
和C語言是一樣的,
頭文件
為stdlib.h,但還要有頭文件
time.h
int
temp;
srand
(unsigned
time(NULL));
temp=rand()%100
就是產生0-99
隨機數。

④ [請教高手]單片機怎麼實現產生隨機數

對於51單片機里有兩個定時器/計數器,可以利用其中的一個來產生隨機數。但要設置成方式2,自己計數狀態。這樣,只有8位數。但不要開中斷,只要計數就行。需要時就讀一次定時器的低8位就行了。
編程序,用定時器T1
MOV
TMOD,#20H
MOV
TH1,#0
MOV
TL1,#0
SETB
TR1
需要的時候,讀TL1,是8位數
MOV
A,
TL1
如果需要16位數,可以對讀出的8位數進行加或乘計算

⑤ 單片機C語言如何產生隨機數

KEIL裡面產生隨機數的函數確實是rand(),但頭文件是stdlib.h,不是time.h。

⑥ [請教高手]單片機怎麼實現產生隨機數

給你一個超強例子:
歡迎到卡卡空間:http://hi..com/woodking
主 題: 線性疊加偽隨機數函數
; 關 鍵 詞: 隨機數,8位單片機,random,8 bit mcu
; 參考資料: 1.<<Linear Congruential Pseudo-Random Number Generator Routines>>
; by Bruce Clark, 7 Jun 2004
; 2.<<The Art Of Computer Programming, Volume 2>>
; by Donald Knuth
;

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進制),是從<<計算機程序的藝術,
第2冊>>一書中選出,這是一個神奇的數字,經過論證和測試,這個數字對產生隨機數至
關重要。想進一步研究的朋友可以閱讀原著(參考資料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 = 0 to 255)
T2,X = 表T2的第X位元組 = 1664525 * X的第23~16位(X = 0 to 255)
T1,X = 表T1的第X位元組 = 1664525 * X的第15~ 8位(X = 0 to 255)
T0,X = 表T0的第X位元組 = 1664525 * X的第 7~ 0位(X = 0 to 255)

對於單片機來說 使用1K RAM很誇張,也可以不用F_GeneratTables,直接把隨機數表存
在ROM中。

;==============================================================================
; 偽隨機數函數的線性疊加
; 計算 Seed = 1664525 * Seed + 1
;------------------------------------------------------------------------------
; 輸入:
; R_Seed0 <--- 種子0
; R_Seed1 <--- 種子1
; R_Seed2 <--- 種子2
; R_Seed3 <--- 種子3
; 回返:
; 種子0 ---> R_Seed0
; 種子1 ---> R_Seed1
; 種子2 ---> R_Seed2
; 種子3 ---> R_Seed3
; 重寫
; R_Temp
;------------------------------------------------------------------------------
; 為提高速度R_Seed0,R_Seed1,R_Seed2,R_Seed3,R_Temp選零頁Ram
; 每張列表從Rom地址 xx00h 處開始 或在Rom中
;------------------------------------------------------------------------------
; 空間: 程序58個位元組
; 列表1024個位元組
; 速度: 調用F_RandomSeed需要94個周期
;==============================================================================
F_RandomSeed:
CLC ; 計算低32位:
LDX R_Seed0 ; 1664525*($100* R_Seed1+ R_Seed0)+1
LDY R_Seed1
LDA T0,X
ADC #1
STA R_Seed0
LDA T1,X
ADC T0,Y
STA R_Seed1
LDA T2,X
ADC T1,Y
STA R_Temp
LDA T3,X
ADC T2,Y
TAY ; 把位元組3留在Y中
CLC ; 加低32位:
LDX R_Seed2 ; 1664525*($10000* R_Seed2)
LDA R_Temp
ADC T0,X
STA R_Seed2
TYA
ADC T1,X
CLC
LDX R_Seed3 ; 加低32位:
ADC T0,X ; 1664525*($1000000* R_Seed3)
STA R_Seed3
rts

;==============================================================================
; 產生T0,T1,T2和T3列表,使用F_GeneratTables,列表在ram中
;==============================================================================
F_GeneratTables:
LDX #0 ;1664525*0=0
STX T0
STX T1
STX T2
STX T3
INX
CLC
L_GT1:
LDA T0-1,X ;把1664525加入
ADC #$0D ;位元組0
STA T0,X
LDA T1-1,X
ADC #$66 ;位元組1
STA T1,X
LDA T2-1,X
ADC #$19 ;位元組2
STA T2,X
LDA T3-1,X
ADC #$00 ;位元組3
STA T3,X
INX ;進位C=0退出
BNE L_GT1
RTS

;------------------------------------------------------------------------------
; 生成的列表,如果不要F_GeneratTables,可以直接將此表放在Rom中
;------------------------------------------------------------------------------
;1664525 * X的第31~24位(X = 0 to 255)
T3:
.DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01,$01,$01
.DB $01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$03
.DB $03,$03,$03,$03,$03,$03,$03,$03,$03,$04,$04,$04,$04,$04,$04,$04
.DB $04,$04,$04,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$06,$06,$06
.DB $06,$06,$06,$06,$06,$06,$06,$07,$07,$07,$07,$07,$07,$07,$07,$07
.DB $07,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$09,$09,$09,$09,$09
.DB $09,$09,$09,$09,$09,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0A,$0B
.DB $0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0B,$0C,$0C,$0C,$0C,$0C,$0C,$0C
.DB $0C,$0C,$0C,$0C,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0D,$0E,$0E
.DB $0E,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F
.DB $0F,$0F,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$11,$11,$11,$11
.DB $11,$11,$11,$11,$11,$11,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12
.DB $13,$13,$13,$13,$13,$13,$13,$13,$13,$13,$14,$14,$14,$14,$14,$14
.DB $14,$14,$14,$14,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$16,$16
.DB $16,$16,$16,$16,$16,$16,$16,$16,$17,$17,$17,$17,$17,$17,$17,$17
.DB $17,$17,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$19,$19,$19,$19

;1664525 * X的第23~16位(X = 0 to 255)
T2:
.DB $00,$19,$32,$4C,$65,$7E,$98,$B1,$CB,$E4,$FD,$17,$30,$4A,$63,$7C
.DB $96,$AF,$C9,$E2,$FB,$15,$2E,$48,$61,$7A,$94,$AD,$C7,$E0,$F9,$13
.DB $2C,$46,$5F,$78,$92,$AB,$C5,$DE,$F7,$11,$2A,$44,$5D,$76,$90,$A9
.DB $C3,$DC,$F5,$0F,$28,$42,$5B,$74,$8E,$A7,$C1,$DA,$F3,$0D,$26,$40
.DB $59,$72,$8C,$A5,$BF,$D8,$F1,$0B,$24,$3E,$57,$70,$8A,$A3,$BD,$D6
.DB $EF,$09,$22,$3C,$55,$6E,$88,$A1,$BB,$D4,$ED,$07,$20,$3A,$53,$6C
.DB $86,$9F,$B9,$D2,$EB,$05,$1E,$38,$51,$6A,$84,$9D,$B7,$D0,$E9,$03
.DB $1C,$36,$4F,$68,$82,$9B,$B5,$CE,$E7,$01,$1A,$34,$4D,$66,$80,$99
.DB $B3,$CC,$E5,$FF,$18,$32,$4B,$64,$7E,$97,$B1,$CA,$E3,$FD,$16,$30
.DB $49,$62,$7C,$95,$AE,$C8,$E1,$FB,$14,$2D,$47,$60,$7A,$93,$AC,$C6
.DB $DF,$F9,$12,$2B,$45,$5E,$78,$91,$AA,$C4,$DD,$F7,$10,$29,$43,$5C
.DB $76,$8F,$A8,$C2,$DB,$F5,$0E,$27,$41,$5A,$74,$8D,$A6,$C0,$D9,$F3
.DB $0C,$25,$3F,$58,$72,$8B,$A4,$BE,$D7,$F1,$0A,$23,$3D,$56,$70,$89
.DB $A2,$BC,$D5,$EF,$08,$21,$3B,$54,$6E,$87,$A0,$BA,$D3,$ED,$06,$1F
.DB $39,$52,$6C,$85,$9E,$B8,$D1,$EB,$04,$1D,$37,$50,$6A,$83,$9C,$B6
.DB $CF,$E9,$02,$1B,$35,$4E,$68,$81,$9A,$B4,$CD,$E7,$00,$19,$33,$4C

;1664525 * X的第15~ 8位(X = 0 to 255)
T1:
.DB $00,$66,$CC,$32,$98,$FE,$64,$CA,$30,$96,$FC,$62,$C8,$2E,$94,$FA
.DB $60,$C6,$2C,$92,$F9,$5F,$C5,$2B,$91,$F7,$5D,$C3,$29,$8F,$F5,$5B
.DB $C1,$27,$8D,$F3,$59,$BF,$25,$8B,$F2,$58,$BE,$24,$8A,$F0,$56,$BC
.DB $22,$88,$EE,$54,$BA,$20,$86,$EC,$52,$B8,$1E,$84,$EB,$51,$B7,$1D
.DB $83,$E9,$4F,$B5,$1B,$81,$E7,$4D,$B3,$19,$7F,$E5,$4B,$B1,$17,$7E
.DB $E4,$4A,$B0,$16,$7C,$E2,$48,$AE,$14,$7A,$E0,$46,$AC,$12,$78,$DE
.DB $44,$AA,$10,$77,$DD,$43,$A9,$0F,$75,$DB,$41,$A7,$0D,$73,$D9,$3F
.DB $A5,$0B,$71,$D7,$3D,$A3,$09,$70,$D6,$3C,$A2,$08,$6E,$D4,$3A,$A0
.DB $06,$6C,$D2,$38,$9E,$04,$6A,$D0,$36,$9C,$03,$69,$CF,$35,$9B,$01
.DB $67,$CD,$33,$99,$FF,$65,$CB,$31,$97,$FD,$63,$C9,$2F,$95,$FC,$62
.DB $C8,$2E,$94,$FA,$60,$C6,$2C,$92,$F8,$5E,$C4,$2A,$90,$F6,$5C,$C2
.DB $28,$8E,$F5,$5B,$C1,$27,$8D,$F3,$59,$BF,$25,$8B,$F1,$57,$BD,$23
.DB $89,$EF,$55,$BB,$21,$88,$EE,$54,$BA,$20,$86,$EC,$52,$B8,$1E,$84
.DB $EA,$50,$B6,$1C,$82,$E8,$4E,$B4,$1A,$81,$E7,$4D,$B3,$19,$7F,$E5
.DB $4B,$B1,$17,$7D,$E3,$49,$AF,$15,$7B,$E1,$47,$AD,$13,$7A,$E0,$46
.DB $AC,$12,$78,$DE,$44,$AA,$10,$76,$DC,$42,$A8,$0E,$74,$DA,$40,$A6

;1664525 * X的第 7~ 0位(X = 0 to 255)
T0:
.DB $00,$0D,$1A,$27,$34,$41,$4E,$5B,$68,$75,$82,$8F,$9C,$A9,$B6,$C3
.DB $D0,$DD,$EA,$F7,$04,$11,$1E,$2B,$38,$45,$52,$5F,$6C,$79,$86,$93
.DB $A0,$AD,$BA,$C7,$D4,$E1,$EE,$FB,$08,$15,$22,$2F,$3C,$49,$56,$63
.DB $70,$7D,$8A,$97,$A4,$B1,$BE,$CB,$D8,$E5,$F2,$FF,$0C,$19,$26,$33
.DB $40,$4D,$5A,$67,$74,$81,$8E,$9B,$A8,$B5,$C2,$CF,$DC,$E9,$F6,$03
.DB $10,$1D,$2A,$37,$44,$51,$5E,$6B,$78,$85,$92,$9F,$AC,$B9,$C6,$D3
.DB $E0,$ED,$FA,$07,$14,$21,$2E,$3B,$48,$55,$62,$6F,$7C,$89,$96,$A3
.DB $B0,$BD,$CA,$D7,$E4,$F1,$FE,$0B,$18,$25,$32,$3F,$4C,$59,$66,$73
.DB $80,$8D,$9A,$A7,$B4,$C1,$CE,$DB,$E8,$F5,$02,$0F,$1C,$29,$36,$43
.DB $50,$5D,$6A,$77,$84,$91,$9E,$AB,$B8,$C5,$D2,$DF,$EC,$F9,$06,$13
.DB $20,$2D,$3A,$47,$54,$61,$6E,$7B,$88,$95,$A2,$AF,$BC,$C9,$D6,$E3
.DB $F0,$FD,$0A,$17,$24,$31,$3E,$4B,$58,$65,$72,$7F,$8C,$99,$A6,$B3
.DB $C0,$CD,$DA,$E7,$F4,$01,$0E,$1B,$28,$35,$42,$4F,$5C,$69,$76,$83
.DB $90,$9D,$AA,$B7,$C4,$D1,$DE,$EB,$F8,$05,$12,$1F,$2C,$39,$46,$53
.DB $60,$6D,$7A,$87,$94,$A1,$AE,$BB,$C8,$D5,$E2,$EF,$FC,$09,$16,$23
.DB $30,$3D,$4A,$57,$64,$71,$7E,$8B,$98,$A5,$B2,$BF,$CC,$D9,$E6,$F3

;==============================================================================
; 最小版本
;==============================================================================

對於單片機來說,使用1K RAM或rom來完成一個隨機數,是很浪費的,以下是最小版本,
但是程序執行周期長。程序每次計算所需要的列表值。

;==============================================================================
; 線性疊加偽隨機數函數
; 計算 R_Seed=1664525 * R_Seed + 1
;------------------------------------------------------------------------------
; 輸入:
; R_Seed0 <--- 種子0
; R_Seed1 <--- 種子1
; R_Seed2 <--- 種子2
; R_Seed3 <--- 種子3
; 回返:
; 種子0 ---> R_Seed0
; 種子1 ---> R_Seed1
; 種子2 ---> R_Seed2
; 種子3 ---> R_Seed3
; 重寫
; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3
; 注意
; R_Temp~R_Temp+3 和 L_Rand6 是高位元組在前,低位元組在後
;------------------------------------------------------------------------------
; 空間: 53個位元組
; 速度: 調用F_RandomSeed平均2744個周期
; 1624+70* N(N=種子數) = 1624~3864個周期
;==============================================================================
F_RandomSeed:
LDA #1 ; R_Temp=1,需要給定初始值
LDX #3
L_Rand1 STA R_Temp,X
LSR
DEX
BPL L_Rand1
LDY #$20 ; 計算種子 = 種子 * L_Rand4+ R_Temp
BNE L_Rand5 ; 總是分支
L_Rand2 BCC L_Rand4 ; 如果零被移位,分支
CLC ; 把乘數加入乘積
LDX #3
L_Rand3 LDA R_Temp,X
ADC T_Rand6,X ;源碼有誤,已改正
STA R_Temp,X
DEX
BPL L_Rand3
L_Rand4 ROR R_Temp ; 右移結果
ROR R_Temp+1
ROR R_Temp+2
ROR R_Temp+3
L_Rand5 ROR R_Seed3 ; 右移種子
ROR R_Seed2
ROR R_Seed1
ROR R_Seed0
DEY
BPL L_Rand2
RTS

T_Rand6 .DB $00,$19,$66,$0D ;乘數(高位元組在前)

;==============================================================================
; 兼顧版本 乘數1664525(10進制)
;==============================================================================

兼顧版本 是不用上面的循環加來做乘法,而是在必要的時候加上 種子,$100* 種子,
$10000* 種子,來獲得數字序列,這樣能夠提高速度,又不增加太多代碼。

分解公式表

b7 b6 b5 b4 b3 b2 b1 b0
$0D = 0 0 0 0 1 1 0 1 b ---> +種子
$66 = 0 1 1 0 0 1 1 0 b ---> *$100h
$19 = 0 0 0 1 1 0 0 1 b ---> *$10000h
$00 = 0 0 0 0 0 0 0 0 b --->
| | | | | | | |
| | | | | | | |
V V V V V V V V
左 左 左 左 左 左
移 移 移 移 移 移
6 5 4 3 2 1
位 位 位 位 位 位

那麼 種子*bit0 時,種子*$10000+種子
種子*bit1 時,種子*$100, 左移1位
種子*bit2 時,種子*$100+種子, 左移2位
種子*bit3 時,種子*$10000+種子,左移3位
種子*bit4 時,種子*$10000, 左移4位
種子*bit5 時,種子*$100, 左移5位
種子*bit6 時,種子*$100, 左移6位

;==============================================================================
; 偽隨機數函數的線性疊加
; 計算 R_Seed=1664525 * R_Seed + 1
;------------------------------------------------------------------------------
; 輸入:
; R_Seed0 <--- 種子0
; R_Seed1 <--- 種子1
; R_Seed2 <--- 種子2
; R_Seed3 <--- 種子3
; 回返:
; 種子0 ---> R_Seed0
; 種子1 ---> R_Seed1
; 種子2 ---> R_Seed2
; 種子3 ---> R_Seed3
; 重寫
; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3
;-------------------------------------------------------------------------------
; 空間: 106個位元組
; 速度: F_RandomSeed 517個周期
;===============================================================================
F_RandomSeed:
CLC ; 復制種子進入R_Temp
LDA R_Seed0 ; 計算 種子 = 種子 *$10000+ 種子 +1
STA R_Temp
ADC #1
STA R_Seed0
LDA R_Seed1
STA R_Temp+1
ADC #0
STA R_Seed1
LDA R_Seed2
STA R_Temp+2
ADC R_Temp
STA R_Seed2
LDA R_Seed3
STA R_Temp+3
ADC R_Temp+1
STA R_Seed3
;-------------------------------------------------
;因為$0019660D 的Bit7=0,所以只需6次移位
;-------------------------------------------------
LDY #5
L_Rand1 ASL R_Temp ; 左移舊的種子
ROL R_Temp+1
ROL R_Temp+2
ROL R_Temp+3
;-------------------------------------------------
; 從 L_Rand4 列表取得 X, 4個索引值對應4種情況,數值選的巧妙!
; X=$00, 種子 = 種子 +$10000* R_Temp
; X=$01, 種子 = 種子 +$100 * R_Temp
; X=$FE, 種子 = 種子 +$10000* R_Temp+ R_Temp
; X=$FF, 種子 = 種子 +$100 * R_Temp+ R_Temp
;-------------------------------------------------
LDX L_Rand4,Y
BPL L_Rand2 ; 分支如果 X=$00 或 X=$01
CLC ; 種子 = 種子 +R_Temp
LDA R_Seed0
ADC R_Temp
STA R_Seed0
LDA R_Seed1
ADC R_Temp+1
STA R_Seed1
LDA R_Seed2
ADC R_Temp+2
STA R_Seed2
LDA R_Seed3
ADC R_Temp+3
STA R_Seed3
INX ; $ FE->$00,$ FF->$01
INX
L_Rand2 CLC
BEQ L_Rand3 ; 如果 X=$00, 種子 =種子 + R_Temp*$10000
LDA R_Seed1 ; 種子 = 種子 + R_Temp*$100
ADC R_Temp
STA R_Seed1
L_Rand3 LDA R_Seed2
ADC R_Temp,X
STA R_Seed2
LDA R_Seed3
ADC R_Temp+1,X
STA R_Seed3
DEY
BPL L_Rand1
RTS

L_Rand4 .DB $01,$01,$00,$FE,$FF,$01

;==============================================================================
; 改進的 兼顧版本B 選擇新的 乘數=69069(10進制)
;==============================================================================

兼顧版本B中, 用69069(10進制)替換1664525(10進制)作乘數,也就是說,選擇了另外一
個數字序列,這個乘數也是<<計算機程序的藝術,第2冊>>一書中選出,經過論證和測試,
這個數字雖不及1664525做乘數好,但也是個神奇的數字,而且可以進一步減小程序時間。

;===============================================================================
; 偽隨機數函數的線性疊加
; 計算種子 = 種子 * 69069 + 1
;-------------------------------------------------------------------------------
; 輸入:
; R_Seed0 <--- 種子0
; R_Seed1 <--- 種子1
; R_Seed2 <--- 種子2
; R_Seed3 <--- 種子3
; 回返:
; 種子0 ---> R_Seed0
; 種子1 ---> R_Seed1
; 種子2 ---> R_Seed2
; 種子3 ---> R_Seed3
; 重寫
; R_Temp,R_Temp+1,R_Temp+2,R_Temp+3
;--------------------------------------------------------------------------------
; 空間: 173個位元組
; 速度: F_RandomSeed 326個周期
;================================================================================
F_RandomSeed:
LDA R_Seed0 ; R_Temp= 種子 *2
ASL
STA R_Temp
LDA R_Seed1
ROL
STA R_Temp+1
LDA R_Seed2
ROL
STA R_Temp+2
LDA R_Seed3
ROL
STA R_Temp+3
CLC ; R_Temp= R_Temp+ 種子 (= 種子 *3)
LDA R_Seed0
ADC R_Temp
STA R_Temp
LDA R_Seed1
ADC R_Temp+1
STA R_Temp+1
LDA R_Seed2
ADC R_Temp+2
STA R_Temp+2
LDA R_Seed3
ADC R_Temp+3
STA R_Temp+3
CLC ; 種子 = 種子 +$10000* 種子
LDA R_Seed2
ADC R_Seed0
TAX ; 把位元組2保存在X中(利於提高速度)
LDA R_Seed3
ADC R_Seed1
TAY ; 把位元組3保存在Y中
CLC ; 種子 = 種子 +$100* 種子
LDA R_Seed1
ADC R_Seed0
PHA ; 壓入堆棧位元組1
TXA
ADC R_Seed1
TAX
TYA
ADC R_Seed2
TAY
LDA R_Temp ; R_Temp= R_Temp*4(= 舊種子 *$0C)
ASL
ROL R_Temp+1
ROL R_Temp+2
ROL R_Temp+3
ASL
ROL R_Temp+1
ROL R_Temp+2
ROL R_Temp+3
STA R_Temp
CLC ; 種子 = 種子 +R_Temp
ADC R_Seed0
STA R_Seed0
PLA ; 彈出堆棧的位元組1
ADC R_Temp+1
STA R_Seed1
TXA
ADC R_Temp+2
TAX
TYA
ADC R_Temp+3
TAY
CLC
LDA R_Temp ; 種子 = 種子 + R_Temp*$100
ADC R_Seed1
STA R_Seed1

⑦ [請教高手]單片機怎麼實現產生隨機數

給你一個超強例子: 歡迎到卡卡空間: http://hi..com/woodking 主 題: 線性疊加偽隨機數函數 ; 關 鍵 詞: 隨機數,8位單片機,random,8 bit mcu ; 參考資料: 1.<> ; by Bruce Clark, 7 Jun 2004 ; 2.<> ; by Donald Knuth ; 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進制),是從<<計算機程序的藝術, 第2冊>>一書中選出,這是一個神奇的數字,經過論證和測試,這個數字對產生隨機數至 關重要。想進一步研究的朋友可以閱讀原著(參考資料2),書中以特別專業的數學方法討論 了隨機數問題。這里只是應用了其中的兩個常數1664525(10進制)和69069(10進制),這里不 作討論,因為篇幅問題是借口,其實自己沒弄懂。 ;============================================================================== ; 快速版本 ;===================

閱讀全文

與單片機真隨機數相關的資料

熱點內容
app如何認定許可權 瀏覽:849
兩個復數相除的角度計演算法則 瀏覽:584
電商類app開發怎麼收費 瀏覽:300
打造電子書反編譯工具 瀏覽:74
壓縮比115 瀏覽:558
pdf怎麼摳圖 瀏覽:864
霍妮pdf 瀏覽:808
反編譯VMP 瀏覽:46
hello編譯器 瀏覽:771
apk程序加密 瀏覽:595
如何給app重命名 瀏覽:603
怎麼幽默調侃程序員 瀏覽:285
忘記密碼解壓視頻 瀏覽:911
運城機場春運加密 瀏覽:287
安卓手機如何關閉app後台 瀏覽:154
安卓數字密碼忘記怎麼破解 瀏覽:252
pythonzmq模式 瀏覽:182
linux運行php網站 瀏覽:866
實驗室無油壓縮機 瀏覽:807
哪裡可以免費看動畫app 瀏覽:54