【问题标题】:Generating random Number ATMega168, AVR STUDIO 4生成随机数 ATMega168, AVR STUDIO 4
【发布时间】:2016-09-26 07:07:48
【问题描述】:

如何在 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

【问题讨论】:

  • 你应该把它标记为程序集而不是 c
  • 可能最简单的 PRNG 是某种 xorshift 算法 en.wikipedia.org/wiki/Xorshift 。请注意,在汇编程序中编写算法时,您可以利用移位操作通常会移入进位这一事实,而这在 C 中是无法完成的
  • 对不起,我实际上并不确定这是哪种语言,因为我上周在学校开始学习。我的意思是在 AVR Studio 4 中生成随机数的代码

标签: assembly random numbers avr


【解决方案1】:

您可以实现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);
}

我很想强调这不是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 &lt;&lt; 7 这样的代码时,会进行多次移位。
注意 3 由于没有除法,并且 2^32 在 8 位领域中没有模逆,y8 &gt;&gt; 5 由以下方式实现交换 y8 半字节,再右移一位并屏蔽掉无用的位。不是这个顺序。


剩下要做的就是初始化xorshift_Y8 变量,即seed RNG。
枚举 ATMega168 中的所有熵源是一个过于宽泛的话题,您可以从第一个 Google result 开始“avr 随机种子”。
主要思想是:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    相关资源
    最近更新 更多