摘要: 本应用笔记给出了一个使用带有12位ADC的MAX7651/52微控制器生成随机数的函数。
本应用笔记给出了一个使用带有12位数字转换器(ADC)的MAX7651/52微控制器生成随机数的函数。
诸如扩频通信、安全、加密和调制解调器等应用需要生成随机数。实现随机数生成器最常见的方法是线性反馈移位寄存器(LFSR)。LFSR生成的代码实际上是“伪”随机的,因为经过一段时间后数字会重复。诀窍是使用足够长度的移位寄存器,使模式在一段极长的时间后重复。
长度为5的基本LFSR示于图1。移位寄存器是一组串接的触发器,具有异或反馈。异或门用于搅乱输入位。
图1所示。5级线性反馈移位寄存器。
有一些表给出了适当的反馈点触位置,以生成需要最大数量的时钟来重复的序列。如下表所示:
表1。2至32位最大长度lfsr的抽头
不。的位 | 回路长度 | 水龙头 |
2 | 3 * | [0, 1] |
3. | 7 * | (0, 2) |
4 | 15 | [0, 3] |
5 | 31 * | (1、4) |
6 | 63 | [0, 5] |
7 | 127 * | (0, 6) |
8 | 255 | (1、2、3、7) |
9 | 511 | (3 8) |
10 | 1023 | (2、9) |
11 | 2047 | (1, 10) |
12 | 4095 | (0、3、5、11) |
13 | 8191 * | (0, 2、3、12) |
14 | 16383年 | (0、2、4、13) |
15 | 32767年 | [0, 14] |
16 | 65535年 | (1、2、4、15) |
17 | 131071 * | (2, 16) |
18 | 262143年 | (6、17) |
19 | 524287 * | [0, - 1, 4, 18) |
20. | 1048575年 | (2、19) |
21 | 2097151年 | (1、20) |
22 | 4194303年 | [0, 21) |
23 | 8388607年 | (4、22) |
24 | 16777215年 | (0, 2、3、23) |
25 | 33554431年 | (7、24) |
26 | 67108863年 | (0、1、5、25) |
27 | 134217727年 | [0, - 1, 4, 26) |
28 | 268435455年 | (2, 27岁) |
29 | 536870911年 | [1, 28] |
30. | 1073741823年 | [0、3、5,29) |
31 | 2147483647 * | (2、30) |
32 | 4294967295年 | (1、5、6、31) |
长度为素数的序列
请注意,有多种解决方案可以生成 最大长度序列。
使用lfsr有一个主要问题:如果所有阶段都是 '0',移位寄存器就会“卡住”。这是因为 所有'0'的异或仍然是'0'。异或反馈 不会产生一个'1'来重新开始序列。为了防止 这种情况,例行程序必须首先加载一个非零的 种子值。这个值可以是任何数字,只要它不是 零。LFSR生成的数字是基于种子值的。您 将一遍又一遍地得到相同的数字序列,除非在 的某个时刻用不同的种子重新加载LSFR。
这种种子价值从何而来?这取决于您的特定应用程序中可用的 。例如,如果您的系统可以访问 到RTC(实时时钟),那么一个好的种子是基于时间的。您 可以读取当前时间和/或日期,屏蔽部分并使用 作为种子。另一个例子是温度。如果您的系统可以读取温度 (假设它不是恒定的),那么它可以制作一个好种子。 MAX765x的ADC可以设置为读取各种各样的东西:缩放交流电源线 电压,一些传感器位置,甚至放大来自齐纳 二极管的约翰逊噪声(密码学中的常见做法)。
然而,在某些情况下,您只需要使用01H或其他数字 ,并接受序列最终将以 预定模式重复的事实。
给出的例程使用25位序列,在 调用3300万次后重复该序列。即使您不能每次 时间都生成唯一的种子,但在大多数应用程序中,长度是这样的,“随机性” 已经足够了。
MAX765x清单如下所示。该例程使用4个8位内存 位置,标记为RN1-RN4。较低的3个字节RN1-RN3用于24位, 和RN4的MSB是25位。该算法使用异或反馈(使用 处理器的XRL指令),来自“阶段”25 (Carry 位)和阶段7 (RN1的MSB)。由于所有电阻都是 RAM位置,因此可以形成最多32位宽的随机数。对于这个 示例,一个8位数字RANNUM存储在例程末尾的RAM中。
要得到随机数的真正高斯分布函数,您可以 做进一步的处理。添加任意数量的连续 样本并取平均值(例如4)将创建高斯分布。
算法中使用的一个编程“技巧”是“字节交换” 来模拟“8个时钟的移位”。这是为了节省CPU时钟周期。例如,如果原始字节顺序是ABCD,那么在字节交换 之后,顺序是BCDA。这可以防止代码不得不做“家务” 从一个字节的MSB转移到下一个字节的LSB。这并不重要 如果随机数计算每一个时钟或每8时钟:他们 仍然是随机的。由于LFSR的总长度是3个 质数(31,601和1801)的乘积,序列仍然是33,554,431子例程 调用,直到序列重复!当然,由于我们在示例中查看的是8个 位,因此值被限制为00H到0FFH, ,因此将多次返回相同的值。
另一个节省周期的“技巧”是当感兴趣的2位 的异或被执行时,RN1的整个内容被改变(参见下面的评论)。
;;随机子程序 ; ;生成随机数使用25位移位寄存器 ;与xor反馈阶段7和25(最大周期长度) ; ;为了使这个例程工作,有两件事要考虑: ;A)某种类型的非零值' seed '必须首先加载到rn1 ; b)在对例程进行大约3300万次调用后,序列将重复 ; ;所需CPU资源: ; ;6闸板位置如下 ; ;Rannum:计算出的随机数 ;Rn1-rn1:形成移位寄存器 ;Temp1:临时刮擦板寄存器 ; ;例程销毁寄存器a和进位 ; ; random: mov a, rn4;位25进位 RRC a mov rn4, rn3 mov rn3, rn2 mov rn2, rn1;左移所有字节 mov a, rn4;是rn3 RRC a;将第25位(进位)转换为old rn3 mov temp1, a;保存它以供以后使用 mov a, rn1 RLC a;位1到位7 mov rn1, a;放回 mov a, temp1;还原 XRL a, rn1;取rn1中所有位与进位的和 mov temp1, a;保存 mov a, rn4 RRC a mov rn4, a;旋转rn4 mov a, rn3 RRC a mov rn3, a;旋转rn3 mov a, rn2 RRC a mov rn2, a;旋转rn2 mov a, temp1;恢复 RLC和 mov rn1, a;xor覆盖所有8位,但没关系 MOV RANNUM,A;随机数! !受潮湿腐烂
社群二维码
关注“华强商城“微信公众号
Copyright 2010-2023 hqbuy.com,Inc.All right reserved. 服务热线:400-830-6691 粤ICP备05106676号 经营许可证:粤B2-20210308