用AVR單片機(jī)產(chǎn)生隨機(jī)數(shù)
, 星星燈
源程序:SLAVR737.ASM
用AVR單片機(jī)8位數(shù)據(jù)產(chǎn)生隨機(jī)數(shù),由PORTA 口及PORTC 口輸出隨機(jī)數(shù),在8X8 LED上顯示,硬件接線電路見(jiàn)“7.3.8按鈕猜數(shù)”。隨機(jī)數(shù)的種子由程序設(shè)定(也可外接開(kāi)關(guān)設(shè)定),啟動(dòng)種子后,由移位寄存器以互斥的異或邏輯組合返回循環(huán)產(chǎn)生。
.include"8515def.inc"
rjmp RESET
.def temp =r16 ;暫存器
.def temp1 =r17 ;暫存器1
.def udata =r21 ;存隨機(jī)數(shù)送A口
.def ddata =r22 ;存隨機(jī)數(shù)送C口
.cseg
.org 0x10
RESET: ldi temp,high(RAMEND);設(shè)堆棧指針
out SPH,temp
ldi temp,low(RAMEND)
out SPL,temp
ldi temp,0xff ;設(shè)A口、C口為輸出
out ddra,temp ;送方向寄存器A
out ddrc,temp ;送方向寄存器C
start: wdr ;關(guān)看門狗
ldi udata,0x6a ; 設(shè)置隨機(jī)數(shù)初值
ldi ddata,0x3c ;
startp: out porta,udata ;輸出到A口
out portc,ddata ;輸出到C口
ldi temp,0x80 ;設(shè)延時(shí)常數(shù)
rcall delay ;調(diào)用延時(shí)子程序
rcall randm ;調(diào)用十六位隨機(jī)數(shù)子程序
rjmp startp
delay: ; 通用延時(shí)子程序 從略
....
16位移位產(chǎn)生隨機(jī)數(shù)原理圖
8~16位移位寄存器產(chǎn)生隨機(jī)數(shù)循環(huán)組合
位 數(shù) 循環(huán)輸入組合 S=2^n-1 Qn XOR Qm
8 Q2 ⊕ Q3 ⊕ Q4 ⊕ Q8 (現(xiàn)程序按鈕猜數(shù)采用8位數(shù))
9 Q5 ⊕ Q9
10 Q7 ⊕ Q10
11 Q9 ⊕ Q11
12 Q2 ⊕ Q10 ⊕ Q11 ⊕ Q12
13 Q1 ⊕ Q11 ⊕ Q12 ⊕ Q13
14 Q2 ⊕ Q12 ⊕ Q13 ⊕ Q14
15 Q14 ⊕ Q15
16 Q4 ⊕ Q13 ⊕ Q15 ⊕ Q16
randm: ;產(chǎn)生十六位隨機(jī)數(shù)子程序
MOV temp,udata ;產(chǎn)生A口隨機(jī)數(shù)
MOV temp1,udata ;
rol temp ;通過(guò)進(jìn)位位左循環(huán)移位
eor temp1,temp ;異或
rol temp ; 通過(guò)進(jìn)位位左循環(huán)移位
rol temp ; 通過(guò)進(jìn)位位左循環(huán)移位
eor temp1,temp ;異或
MOV temp,ddata ; 產(chǎn)生C口隨機(jī)數(shù)
swap temp ; 通過(guò)進(jìn)位位左循環(huán)移位
eor temp,temp1 ;異或通過(guò)進(jìn)位位左循環(huán)移位
rol temp ; 通過(guò)進(jìn)位位左循環(huán)移位
rol ddata ; 通過(guò)進(jìn)位位左循環(huán)移位
rol udata ; 通過(guò)進(jìn)位位左循環(huán)移位
ret ;子程序返回
7.3.8 按鈕猜數(shù)程序
源程序:SLAVR738.ASM
許多場(chǎng)合如按鈕猜數(shù)(電腦搖獎(jiǎng),電腦選出幸運(yùn)號(hào)),游戲開(kāi)始按鈕等待一個(gè)不規(guī)則且不定序的數(shù)據(jù)產(chǎn)生,即須要隨機(jī)數(shù)發(fā)生器。隨機(jī)數(shù)的種子由程序設(shè)定(也可外接開(kāi)關(guān)設(shè)定),啟動(dòng)種子后,由移位寄存器以互斥的異或邏輯組合返回循環(huán)產(chǎn)生。產(chǎn)生隨機(jī)數(shù)的原理圖如下:
16位移位產(chǎn)生隨機(jī)數(shù)原理圖
8~16位移位寄存器產(chǎn)生隨機(jī)數(shù)循環(huán)組合
位 數(shù) 循環(huán)輸入組合 S=2^n-1 Qn XOR Qm
8 Q2 ⊕ Q3 ⊕ Q4 ⊕ Q8 (現(xiàn)程序按鈕猜數(shù)采用8位數(shù))
9 Q5 ⊕ Q9
10 Q7 ⊕ Q10
11 Q9 ⊕ Q11
12 Q2 ⊕ Q10 ⊕ Q11 ⊕ Q12
13 Q1 ⊕ Q11 ⊕ Q12 ⊕ Q13
14 Q2 ⊕ Q12 ⊕ Q13 ⊕ Q14
15 Q14 ⊕ Q15
16 Q4 ⊕ Q13 ⊕ Q15 ⊕ Q16
以8X8 LED陣列,開(kāi)機(jī)時(shí)為了避免被使用者預(yù)測(cè)出壓按時(shí)間對(duì)應(yīng)隨機(jī)數(shù)的變化值,故LED字幕以廣告動(dòng)畫(huà)畫(huà)面顯示,并令隨機(jī)數(shù)隨著變化使無(wú)法預(yù)測(cè)隨機(jī)數(shù)起始值,廣告動(dòng)畫(huà)面共有四張,每張有8位數(shù)據(jù)。見(jiàn)”org dpfstb”;
由按鈕(PD1)按下,AVR用8位數(shù)據(jù)產(chǎn)生隨機(jī)數(shù),由PORTA 口及PORTC 口輸出隨機(jī)數(shù),在8X8 LED上顯示好玩的真實(shí)的按鈕猜數(shù)。
.include "8515def.inc"
.def peed =r16
.def dspn =r17 ;存顯示初始動(dòng)畫(huà)次數(shù)
.def temp2 =r18
.def temp1 =r19
.def temp =r20
.def scndp =r21
.def cnt =r22
.def rdata =r23 ;存隨機(jī)種子數(shù)
.def rdata9 =r24
.equ dpfstb =0x01e0 ;大小矩形圖表首址
.equ randtb =0x0210 ;隨機(jī)數(shù)種子表首址
.equ numbertb=0x0240 ;0-9數(shù)字表首址
.org $0000
rjmp RESET ;Reset Handle
.cseg
.org $0010
RESET: ldi peed,high(RAMEND) ;設(shè)置堆棧$25F,見(jiàn)器件配置文件"8515def.inc"
out SPH,peed
ldi peed,low(RAMEND)
out SPL,peed
ldi peed,0xff ;對(duì)口初始化,
out ddra,peed ;設(shè)A口為輸出
out ddrc,peed ;設(shè)C口為輸出
ldi peed,0xfd ;PD1作輸入,且接內(nèi)部上拉電阻
out ddrd,peed ;PD1為輸入,其余為輸出
ldi peed,0xff ;關(guān)D口
out portd,peed
ldi peed,0x13 ;顯示畫(huà)面次數(shù)
start: ldi dspn,0x06 ;顯示初始動(dòng)畫(huà)
ldi zh,high(dpfstb*2)
ldi zl,low(dpfstb*2)
dspfm: rcall ldtb8 ;調(diào)用程序區(qū)數(shù)送到內(nèi)存RAM
ldi temp2,0xa0 ;顯示動(dòng)畫(huà)面次數(shù)
dspfm1: rcall scan1 ;調(diào)用從內(nèi)存取數(shù)顯示一次
sbis pind,01 ;I/O口的位被置位跳行,檢測(cè)到PD1按下否
rjmp getseed ; 檢測(cè)到PD1按下轉(zhuǎn)
dec temp2 ;-1
brne dspfm1 ;不為0轉(zhuǎn)
dec dspn ; 初始畫(huà)面次數(shù)-1
brne dspfm ; 不為0轉(zhuǎn)
rjmp start ;轉(zhuǎn)到顯示初始動(dòng)畫(huà)
getseed:inc temp ;+`1,根據(jù)PD1按下的時(shí)間,選擇隨機(jī)數(shù)種子
sbis pind,01 ; I/O口的位被置位跳行,檢測(cè)到PD1按下否
rjmp getseed ; 檢測(cè)到PD1按下,繼續(xù)計(jì)數(shù)
andi temp,0x1f ;按鈕松開(kāi),取隨機(jī)數(shù)種子與0X0F加
ldi zh,high(randtb*2)
ldi zl,low(randtb*2)
add zl,temp
lpm
MOV rdata,r0 ;得到隨機(jī)數(shù)種子
next: ldi dspn,0x08 ;顯示8個(gè)不同的隨機(jī)數(shù);
repeet: rcall randm ;調(diào)用產(chǎn)生隨機(jī)數(shù)子程序
rcall dspnumber ;調(diào)用顯示8個(gè)不同的隨機(jī)數(shù)
dec dspn ;-1
brne repeet ;dspn不為0轉(zhuǎn)
rcall randm ; 調(diào)用產(chǎn)生隨機(jī)數(shù)子程序
guess1: rcall dspnumber ;調(diào)用顯示同一隨機(jī)數(shù),直到有鍵按下
sbic pind,01 ;松開(kāi)后再往下執(zhí)行(I/O口清零跳行)
rjmp guess1 ;轉(zhuǎn)顯示同一隨機(jī)數(shù),直到有鍵按下
wait: rcall dspnumber ;
sbis pind,01
rjmp wait ;等待按鈕按下
ldi rdata9,0x03 ;顯示動(dòng)畫(huà)三次
start0: ldi dspn,0x06 ;每次顯示六幅畫(huà)面
ldi zh,high(dpfstb*2)
ldi zl,low(dpfstb*2)
dspfm0: rcall ldtb8 ;調(diào)用從Z指向的程序區(qū)取數(shù)據(jù)送到內(nèi)存0080-0087中
ldi temp2,0xa0 ;顯示次數(shù)
dspfm1a:rcall scan1 ;調(diào)用從內(nèi)存0080-0087中取數(shù)據(jù)顯示一次
dec temp2 ;-1
brne dspfm1a ;不為0轉(zhuǎn)
dec dspn ;顯示初始動(dòng)畫(huà)次數(shù)-1
brne dspfm0 ;不為0轉(zhuǎn)
dec rdata9 ;顯示動(dòng)畫(huà)三次-1
brne start0 ;不為0轉(zhuǎn)
rjmp next ;轉(zhuǎn)顯示8個(gè)不同的隨機(jī)數(shù)
dspnumber: ;顯示一個(gè)0-9數(shù)字的子程序
ldi zh,high(numbertb*2)
ldi zl,low(numbertb*2)
add zl,rdata9
rcall ldtb8 ;取數(shù)
ldi temp2,0xa0 ;該數(shù)字重復(fù)顯示A0H次
dspn1: rcall scan1
dec temp2
brne dspn1
ret
scan1: push xl ;從內(nèi)存0080-0087中取數(shù)據(jù)顯示一次
ldi temp,0b01111111
MOV scndp,temp
ldi cnt,0x08
col1: out portc,scndp ;顯示屏幕的一列
ld r1,x+
out porta,r1
rcall delay
sec
ror scndp
dec cnt
brne col1
pop xl
ret
ldtb8: ldi xl,0x80 ;從Z指向的程序區(qū)取數(shù)據(jù)送到內(nèi)存0080-0087中
ldi xh,0x00
ldi temp1,0x08
push xl
nexld1: lpm
st x+,r0
ld r0,z+
dec temp1
brne nexld1
pop xl
ret
delay: ;通用延時(shí)子程序從略
....
randm: MOV temp,rdata ;產(chǎn)生8N(0≤N≤9)隨機(jī)數(shù)子程序
MOV temp1,rdata
swap temp1
eor temp,temp1
rol temp1
eor temp,temp1
rol temp1
eor temp,temp1
rol temp
rol rdata
MOV rdata9,rdata
andi rdata9,0x0f
cpi rdata9,0x0a
brsh randm ;產(chǎn)生了一個(gè)0≤RDATA9≤9的隨機(jī)數(shù)
lsl rdata9
lsl rdata9
lsl rdata9
ret
.cseg
.org dpfstb; ;大小方框字形表
;small o
.db 0b00000000,0b00000000,0b00000000,0b00011000
.db 0b00011000,0b00000000,0b00000000,0b00000000
.db 0b00000000,0b00000000,0b00111100,0b00100100
.db 0b00100100,0b00111100,0b00000000,0b00000000
.db 0b00000000,0b01111110,0b01000010,0b01000010
.db 0b01000010,0b01000010,0b01111110,0b00000000
;big o
.db 0b11111111,0b10000001,0b10000001,0b10000001
.db 0b10000001,0b10000001,0b10000001,0b11111111
.db 0b00000000,0b01111110,0b01000010,0b01000010
.db 0b01000010,0b01000010,0b01111110,0b00000000
.db 0b00000000,0b00000000,0b00111100,0b00100100
.db 0b00100100,0b00111100,0b00000000,0b00000000
.cseg
.org randtb ;隨機(jī)數(shù)種子表
.db 0x5a,0x7b,0x5b,0x4f,0x66,0x6d,0x7d,0x07
.db 0x3b,0x8c,0x67,0x9a,0x99,0x7e,0x2d,0x3e
.db 0x5c,0x6d,0x5b,0x7e,0xf6,0xe7,0x4c,0xc8
.db 0x69,0x9c,0xe2,0x75,0x6c,0xd3,0xe8,0x9a
.cseg
.org numbertb ;0-9數(shù)字字形表
;0
.db 0b00111000,0b01000100,0b01000100,0b01000100
.db 0b01000100,0b01000100,0b01000100,0b00111000
;1
.db 0b00010000,0b00011000,0b00010000,0b00010000
.db 0b00010000,0b00010000,0b00010000,0b00111000
;2
.db 0b00011100,0b00100010,0b00100000,0b00010000
.db 0b00001000,0b00000100,0b00000010,0b00111110
;3
.db 0b00111100,0b00010000,0b00001000,0b00010000
.db 0b00100000,0b00100000,0b00100010,0b00011100
;4
.db 0b00100000,0b00110000,0b00101000,0b00100100
.db 0b00100010,0b11111110,0b00100000,0b00100000
;5
.db 0b01111110,0b00000010,0b00111110,0b01000000
.db 0b01000000,0b01000000,0b01000010,0b00111100
;6
.db 0b00110000,0b00001000,0b00000100,0b00111100
.db 0b01000100,0b01000100,0b01000100,0b00111000
;7
.db 0b01111100,0b01000000,0b00100000,0b00010000
.db 0b00001000,0b00001000,0b00001000,0b00001000
;8
.db 0b00111000,0b01000100,0b01000100,0b00111000
.db 0b01000100,0b01000100,0b01000100,0b00111000
;9
.db 0b00111000,0b01000100,0b01000100,0b01111000
.db 0b01000000,0b01000000,0b01000100,0b00111000
單片機(jī)相關(guān)文章:單片機(jī)教程
單片機(jī)相關(guān)文章:單片機(jī)視頻教程
單片機(jī)相關(guān)文章:單片機(jī)工作原理
上拉電阻相關(guān)文章:上拉電阻原理
評(píng)論