利用微控制器生成随机数的创新方法

在许多电子系统中,生成随机数是一个重要的功能,尤其是在需要安全性通信可靠性的场合。然而,对于具有相同硬件和软件的设备来说,生成唯一的随机地址是一个挑战。本文将介绍一种利用微控制器生成随机数的创新方法,该方法通过硬件限制和编程技巧来提高随机性。

微控制器中,模拟数字转换器(ADC)已经被用来生成真正的随机数。但是,当无法为随机化分配模拟输入引脚,或者ADC在电路附近的电磁场和静电场影响下饱和时,就会遇到一些限制。本文使用Atmega328p微控制器来展示如何克服这些限制。不是尝试读取一个浮动的(假设是随机的)输入信号,而是创建一个内部信号,并利用硬件无法完全合成信号的限制。这为提供了一个机会来随机化一些位。

方法

Atmega328p(以及其他AVR和大多数具有内部ADC的控制器)的ADC使用可编程复用器将不同的引脚路由到主转换器。除了将其连接到控制器的输入引脚外,它还可以连接到一些内部预定义的电压,对于Atmega328p来说,这些电压是0V和1.1V的带隙电压。参考电压也可以改变,但在这种方法中不使用改变它的效果。使用这两个电压,在ADC上合成了一个振幅为1.1V的脉动方波脉冲。当假设有方波脉冲时,ADC应该读取“0”表示低脉冲,“1023”表示高脉冲。但是,由于内部电容的存在,改变电压水平需要一些时间,而这个时间正好是ADC每次转换所需的时间。因此,在完全线性的微控制器电路中,形成了一个由于多种因素(如供电电压、温度,以及最重要的是,当在其他组件的自然频率范围内操作时,振荡倾向于利用系统的非常有趣的动态)而高度非线性的子系统。

编码技术

为了减少这种效应,使用了一些编码技术。比如使用“种子”,使用位移动,以及随机改变合成信号的频率。首先,使用前一次转换的结果作为起点(就像在伪随机数中所做的那样);位移动是使用处理器的标准移位指令完成的;最后一个是通过在每次转换后改变ADC的时钟频率来完成的。

代码示例

以下是生成8位随机数的示例代码。通过增加位深度或使用多个随机数生成器,可以获得更宽的数字。

int N = 20; // 20对于uint8来说效果很好,可以增加以减少模式。 // 每个循环大约需要80微秒在16MHz的主时钟上 // 这将每1.5毫秒生成一个随机数。 for (int i = 0; i < N; i++) { // 在输入上合成一个电压 if (i % 2 == 0) ADMUX = 0b01001110; // [A] // 高(1.1V)。// 参见Atmega328p数据手册表23-3和23-4 else ADMUX = 0b01001111; // [A] // 低(0V) ADCSRA |= 1 << ADSC; // 开始一次转换。参见Atmega328p数据手册第207页 uint8_t low, high; // ADSC在转换完成时被清除 while ((ADCSRA >> ADSC) & 2); // 等待转换完成 low = ADCL; // 不要交换这个顺序。必须首先获取低值。 high = ADCH; // 值总是在0-3之间 V ^= low; V ^= high; // 让旋转移动这个数字; uint8_t last = V % 2; V >>= 1; V |= last << 7; // “7”将需要改变为K-1以使用K位宽的数据类型 // 禁用ADC ADCSRA = 0; // 启用ADC,随机选择时钟预分频器在2和128之间。 // 由于每次转换需要13个ADC周期,在16MHz系统时钟下, // ADC现在每次转换将需要1.6微秒到104微秒(平均75微秒)。 ADCSRA = 0b10000000 | ((V % 4) << 1); // 参见Atmega328p数据手册表23-5 }

改进余地

在测量信号时,可以通过改变参考电压来增加非线性。这将需要嵌入到上述代码的[A]点中。

最终数字可以通过添加一个伪随机数生成器,以真实数字作为种子来补充。

为了使ADC读取更加随机,可以使信号更加不稳定(例如,使用可变时钟速率),或者使信号移动得非常快。当ADC读取非常快的信号时,不确定性会增加。这可以通过将振荡系统更多地移动到共振点来实现。这意味着只有ADC时钟的一个可能频率会为信号提供最大的上升和下降时间,从而获得更不稳定的ADC读取。

随机数的位宽可以增加。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485