单片机
返回首页

AVR单片机8位数据产生随机数

2017-12-17 来源:eefocus

      源程序: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  


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • CCD图像传感器在微光电视系统中的应用

  • 离子检测器电路分析

  • 一个简单的立体声平衡指示器电路

  • 分享一个电网倾角计电路

  • 电谐波图形均衡器示意图

  • 一种构建12V和230V双直流电源的简单方法

    相关电子头条文章