生成随机数ATMega168,AVR STUDIO 4

时间:2016-09-26 07:07:48

标签: assembly random numbers avr

如何在Avr Studio 4中生成随机数(命令)。我有一个ATMEGA168。 我想生成随机数,因此“warten”(等待)具有未定义的等待时间并且正在改变所有时间。因此,如果它已从255减少到0等,我希望它生成一个随机数,用于定义它是否会在等待中再次进行,或者它是否会返回。 这是我的代码:

   .include "m168def.inc"  ;ATMega 168

    rjmp main                

main:  
    ldi r16, 0b00000100     


    out ddrB, r16           

loop:    
    ldi r16, 0b00000100    
    out portB, r16             

    rcall warten            

    ldi r16, 0b00000000     
    out portB, r16          
    rcall warten

    rjmp loop

warten:
    ldi r17,2              
w3:                         
    ldi r18,255        
w2:                        
    ldi r19,255            
w1:                         
    dec r19               
    brne w1                 

    dec r18                 
    brne w2                 

    dec r17                 
    brne w3                 

    ret

1 个答案:

答案 0 :(得分:2)

您可以实现xorshift suited to generate 8 bit伪随机数的版本:

static uint8_t y8 = 1;

uint8_t xorshift8(void) {
    y8 ^= (y8 << 7);
    y8 ^= (y8 >> 5);
    return y8 ^= (y8 << 3);
}

我觉得强调这是 a CSRNG的冲动。

在ATMega168的AVR组装中,我们有:

;Return random number in r0
;The symbol xorshift_Y8 must be defined (it must be a SRAM address, i.e. > 0x60)
xorshift8:
  push r1
  push r2

  ldi r0, 128                ;r0 = 2^7
  lds r2, xorshift_Y8        ;r2 = y8
  mul r0, r2                 ;r1:r0 = y8 << 7
  eor r2, r0                 ;r2 = y8 ^ (y8 << 7)

  ;r2 = y8

  mov r0, r2                 ;r0 = y8
  andi r0, 0xf0              ;r0 = y8 high nibble
  swap r0                    ;r0 = y8 >> 4
  lsr r0                     ;r0 = y8 >> 5
  eor r2, r0                 ;r2 = y8 ^ (y8 >> 5)

  ;r2 = y8

  ldi r0, 8                  ;r0 = 2^3
  mul r2, r0                 ;r1:r0 = y8 << 3
  eor r0, r2                 ;r0 = y8 ^ (y8 << 3)

  sts xorshift_Y8, r0        ;Save new state

  pop r2
  pop r1
  ret

注意我尚未测试此代码,请将其用作模板 注2 AVR具有单位移位功能,乘法速度足够快,在y8 << 7等代码时更喜欢多次移位。 注3 由于没有除法且2 ^ 32在8位域中没有模块化逆,y8 >> 5是通过交换 y8 半字节来实现的,再移动一个咬合正确并掩盖无用的位。不按此顺序。

唯一要做的就是初始化xorshift_Y8变量,即种子 RNG。
列举ATMega168中的所有熵源是一个过于愚蠢的主题,你可以从第一个Google result开始为“avr随机种子”。
主要想法是:

  • 以预定义值(如1)开始,并在每次启动时递增它。
  • 使用不带上拉的浮动GPIO。
  • 使用浮动ADC输入。
  • 启动时设置定时器,在第一次使用RNG时读取定时器值。

重要的是从不将状态设置为0,因为它是xorshift的“稳定”状态!