本应用笔记介绍如何利用DS4温度寄存器的最低2790位产生16位随机值。本说明还提供了用于生成 16 位随机值的示例 C 代码。
介绍
随机数用于许多加密和身份验证方案。随机数的生成涉及查找随机行为并使用此行为生成随机值。因此,使用微控制器生成随机数可能是一项艰巨的任务,因为微控制器经常表现出重复行为。
幸运的是,DS2790允许设计人员使用温度寄存器的最低4位来产生16位随机值。虽然数据手册中只有温度寄存器的最高11位被定义为温度信息,但所有16位都被报告。此功能,加上寄存器的最低4位是高度随机的,使其成为生成16位随机值的理想选择。
扩展温度数据是随机的吗?
表1是将DS2790浸入受控温度浴中得出的。将器件放置在如此严格控制的温度环境中会迅速暴露非随机温度值。下面的数据显示了内存中存储温度的地址的最低 4 位。
表 1.DS2790的扩展温度数据
价值 | 计数 | 增量计数 | 三角洲平均 |
0 | 23657 | -453.625 | -1.8814% |
1 | 23822 | -288.625 | -1.1971% |
2 | 24422 | 311.375 | 1.2914% |
3 | 24091 | -19.625 | -0.0814% |
4 | 24222 | 111.375 | 0.4619% |
5 | 23994 | -116.625 | -0.4837% |
6 | 24218 | 107.375 | 0.4453% |
7 | 24258 | 147.375 | 0.6112% |
8 | 24612 | 501.375 | 2.0795% |
9 | 23984 | -126.625 | -0.5252% |
一个 | 23974 | -136.625 | -0.5667% |
B | 24005 | -105.625 | -0.4381% |
C | 24178 | 67.375 | 0.2794% |
D | 24066 | -44.625 | -0.1851% |
E | 23954 | -156.625 | -0.6496% |
F | 24313 | 202.375 | 0.8394% |
共计数: | 385770 | ||
总数的 1/16: | 24110.625 |
值列以十六进制显示温度寄存器最低 4 位的值。“计数”列显示每个值在大约 24 小时内出现的次数。在完全随机的系统中,给定无限的时间来监测DS2790的行为,我们会看到每个值在1/16的时间内出现。增量计数列显示与理想 1/16 值相比,每个值出现的次数的绝对误差。Delta-Avg 列显示的误差与理想 1/16 值的百分比相同,即理想随机行为与 1/16 时间发生的值之间的百分比差异。非常低的百分比值表明温度寄存器的最低4位是高度随机的。
生成 16 位随机数
为了确保在需要时随机数可用,该示例会在每次完成温度转换结果时更新随机值。若要生成 16 位随机数,请使用以下步骤。
将DS2790配置为在温度转换完成时产生中断。
注意温度中断发生的时间。
发生中断时,将温度寄存器的最低4位移入变量。
这些步骤导致DS2790每220ms (标称值)产生一个温度转换中断。由于每次温度转换提供 4 位,并且我们正在生成一个 16 位数字,因此每 880ms(标称值)提供一个全新的随机数。
示例 C 代码
下面的示例 C 代码生成一个 16 位随机值,该值可用作全局变量rand_num。请注意,必须初始化该器件,以便在温度中断完成时启用中断。温度中断在代码中定义为EINT_ti。
unsigned short rand_num; /* Global random number */ /* This is the main Interrupt Service Routine*/ void FuelGaugeISR(void) __interrupt { char temp_low4bits; /* Store the low 4 bits of temperature here */ /* Stay in the loop if there is an interrupt. */ while (IIR & IMR_IM0 || IIR & IMR_IM1) { /* The IIR signifies if a Module 0 or Module 1 interrupt has occured.*/ /* Module 0 will be treated with priority. */ if (IIR & IMR_IM0) /* Module 0 Interrupt */ { /* Detect and Service Higher Priority Module 0 Interrupts here. */ if (EINT & EINT_ti) /* A temperature conversion completion int occurs every 220ms. */ { EINT &= ~EINT_ti; /* Reset the temperature interrupt bit. */ /* This code builds a new 16 bit random number every 4 temperature interrupts */ /* The global variable rand_num is fully updated every 880ms */ /* Next statement clears all but low 4 bits of the temperature register */ temp_low4bits = (char)((pADC->TEMPERATURE) & 0x000F); /* Next statement shifts the old random number left by 4 bits. */ rand_num = rand_num << 4; /* Next statement "shifts" the new bits in by adding them. */ rand_num = rand_num + temp_low4bits; } } else /* This is a module 1 interrupt. */ { /* Handle module 1 interrupts here. */ } } }
审核编辑:郭婷
全部0条评论
快来发表一下你的评论吧 !