|
用AVR单片机8位数据产生随机数
作者:佚名 星星灯 源程序:SLAVR737.ASM 用AVR单片机8位数据产生随机数,由PORTA 口及PORTC 口输出随机数,在8X8 LED上显示,硬件接线电路见“7.3.8按钮猜数”。随机数的种子由程序设定(也可外接开关设定),启动种子后,由移位寄存器以互斥的异或逻辑组合返回循环产生。 .include"8515def.inc" rjmp RESET .def temp =r16 ;暂存器 .def temp1 =r17 ;暂存器1 .def udata =r21 ;存随机数送A口 .def ddata =r22 ;存随机数送C口 .cseg .org 0x10 RESET: ldi temp,high(RAMEND);设堆栈指针 out SPH,temp ldi temp,low(RAMEND) out SPL,temp ldi temp,0xff ;设A口、C口为输出 out ddra,temp ;送方向寄存器A out ddrc,temp ;送方向寄存器C start: wdr ;关看门狗 ldi udata,0x6a ; 设置随机数初值 ldi ddata,0x3c ; startp: out porta,udata ;输出到A口 out portc,ddata ;输出到C口 ldi temp,0x80 ;设延时常数 rcall delay ;调用延时子程序 rcall randm ;调用十六位随机数子程序 rjmp startp delay: ; 通用延时子程序 从略 .... 16位移位产生随机数原理图 8~16位移位寄存器产生随机数循环组合 位 数 循环输入组合 S=2^n-1 Qn XOR Qm 8 Q2 ⊕ Q3 ⊕ Q4 ⊕ Q8 (现程序按钮猜数采用8位数) 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: ;产生十六位随机数子程序 mov temp,udata ;产生A口随机数 mov temp1,udata ; rol temp ;通过进位位左循环移位 eor temp1,temp ;异或 rol temp ; 通过进位位左循环移位 rol temp ; 通过进位位左循环移位 eor temp1,temp ;异或 mov temp,ddata ; 产生C口随机数 swap temp ; 通过进位位左循环移位 eor temp,temp1 ;异或通过进位位左循环移位 rol temp ; 通过进位位左循环移位 rol ddata ; 通过进位位左循环移位 rol udata ; 通过进位位左循环移位 ret ;子程序返回 7.3.8 按钮猜数程序 源程序:SLAVR738.ASM 许多场合如按钮猜数(电脑摇奖,电脑选出幸运号),游戏开始按钮等待一个不规则且不定序的数据产生,即须要随机数发生器。随机数的种子由程序设定(也可外接开关设定),启动种子后,由移位寄存器以互斥的异或逻辑组合返回循环产生。产生随机数的原理图如下: 16位移位产生随机数原理图 8~16位移位寄存器产生随机数循环组合 位 数 循环输入组合 S=2^n-1 Qn XOR Qm 8 Q2 ⊕ Q3 ⊕ Q4 ⊕ Q8 (现程序按钮猜数采用8位数) 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阵列,开机时为了避免被使用者预测出压按时间对应随机数的变化值,故LED字幕以广告动画画面显示,并令随机数随着变化使无法预测随机数起始值,广告动画面共有四张,每张有8位数据。见”org dpfstb”;
由按钮(PD1)按下,AVR用8位数据产生随机数,由PORTA 口及PORTC 口输出随机数,在8X8 LED上显示好玩的真实的按钮猜数。 .include "8515def.inc" .def peed =r16 .def dspn =r17 ;存显示初始动画次数 .def temp2 =r18 .def temp1 =r19 .def temp =r20 .def scndp =r21 .def cnt =r22 .def rdata =r23 ;存随机种子数 .def rdata9 =r24 .equ dpfstb =0x01e0 ;大小矩形图表首址 .equ randtb =0x0210 ;随机数种子表首址 .equ numbertb=0x0240 ;0-9数字表首址 .org $0000 rjmp RESET ;Reset Handle .cseg .org $0010 RESET: ldi peed,high(RAMEND) ;设置堆栈$25F,见器件配置文件"8515def.inc" out SPH,peed ldi peed,low(RAMEND) out SPL,peed ldi peed,0xff ;对口初始化, out ddra,peed ;设A口为输出 out ddrc,peed ;设C口为输出 ldi peed,0xfd ;PD1作输入,且接内部上拉电阻 out ddrd,peed ;PD1为输入,其余为输出 ldi peed,0xff ;关D口 out portd,peed ldi peed,0x13 ;显示画面次数 start: ldi dspn,0x06 ;显示初始动画 ldi zh,high(dpfstb*2) ldi zl,low(dpfstb*2) dspfm: rcall ldtb8 ;调用程序区数送到内存RAM ldi temp2,0xa0 ;显示动画面次数 dspfm1: rcall scan1 ;调用从内存取数显示一次 sbis pind,01 ;I/O口的位被置位跳行,检测到PD1按下否 rjmp getseed ; 检测到PD1按下转 dec temp2 ;-1 brne dspfm1 ;不为0转 dec dspn ; 初始画面次数-1 brne dspfm ; 不为0转 rjmp start ;转到显示初始动画 getseed:inc temp ;+`1,根据PD1按下的时间,选择随机数种子 sbis pind,01 ; I/O口的位被置位跳行,检测到PD1按下否 rjmp getseed ; 检测到PD1按下,继续计数 andi temp,0x1f ;按钮松开,取随机数种子与0X0F加 ldi zh,high(randtb*2) ldi zl,low(randtb*2) add zl,temp lpm mov rdata,r0 ;得到随机数种子 next: ldi dspn,0x08 ;显示8个不同的随机数; repeet: rcall randm ;调用产生随机数子程序 rcall dspnumber ;调用显示8个不同的随机数 dec dspn ;-1 brne repeet ;dspn不为0转 rcall randm ; 调用产生随机数子程序 guess1: rcall dspnumber ;调用显示同一随机数,直到有键按下 sbic pind,01 ;松开后再往下执行(I/O口清零跳行) rjmp guess1 ;转显示同一随机数,直到有键按下 wait: rcall dspnumber ; sbis pind,01 rjmp wait ;等待按钮按下 ldi rdata9,0x03 ;显示动画三次 start0: ldi dspn,0x06 ;每次显示六幅画面 ldi zh,high(dpfstb*2) ldi zl,low(dpfstb*2) dspfm0: rcall ldtb8 ;调用从Z指向的程序区取数据送到内存0080-0087中 ldi temp2,0xa0 ;显示次数 dspfm1a:rcall scan1 ;调用从内存0080-0087中取数据显示一次 dec temp2 ;-1 brne dspfm1a ;不为0转 dec dspn ;显示初始动画次数-1 brne dspfm0 ;不为0转 dec rdata9 ;显示动画三次-1 brne start0 ;不为0转 rjmp next ;转显示8个不同的随机数 dspnumber: ;显示一个0-9数字的子程序 ldi zh,high(numbertb*2) ldi zl,low(numbertb*2) add zl,rdata9 rcall ldtb8 ;取数 ldi temp2,0xa0 ;该数字重复显示A0H次 dspn1: rcall scan1 dec temp2 brne dspn1 ret scan1: push xl ;从内存0080-0087中取数据显示一次 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指向的程序区取数据送到内存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: ;通用延时子程序从略 .... randm: mov temp,rdata ;产生8N(0≤N≤9)随机数子程序 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 ;产生了一个0≤RDATA9≤9的随机数 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 ;随机数种子表 .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数字字形表 ;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 |