51/AVR单片机技术驿站!  <在线翻译>     便利工具    特色网址   无弹窗、无插件的绿色站点...  英才招聘   学历查询  喜欢>>收藏我站 

当前位置:首页 > 单片机技术文章 > AVR单片机 > 详细内容
用AVR单片机8位数据产生随机数
发布时间:2009/7/22  阅读次数:824  字体大小: 【】 【】【

来源:网络 源鹏 发表

用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
  

我要评论
  • 匿名发表
  • [添加到收藏夹]
  • 发表评论:(匿名发表无需登录,已登录用户可直接发表。) 登录状态:未登录
最新评论
所有评论[0]
    暂无已审核评论!

网站导航 管理登陆 ┊ 免责声明 问题反馈  友链说明
本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正!
不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作!

    我要报警 Alexa
 mcusy_cn#126.com (请把#改成@) 交流:522422171
本站学习交流群:138..158(高级群1-)、77930286(高级群2)、61804809(群3)
Copyright© MCUSY All Rights Reserved
本站网警备案号: WZ36040002485
  ICP备案证书号:粤ICP备09034963号