OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 40|回复: 0

《ESP32-P4开发指南— V1.0》第二十六章 RNG实验

[复制链接]

1230

主题

1244

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
5292
金钱
5292
注册时间
2019-5-8
在线时间
1353 小时
发表于 前天 09:25 | 显示全部楼层 |阅读模式
第二十六章 RNG实验

1)实验平台:正点原子DNESP32P4开发板

2)章节摘自【正点原子】ESP32-P4开发指南— V1.0

3)购买链接:https://detail.tmall.com/item.htm?id=873309579825

4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32P4.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子DNESP32S3开发板技术交流群:132780729

2.jpg

3.png

26.1 RNG介绍
随机数发生器(Random Number Generators),用于生成随机数的程序或软件。
随机数的特性:产生的后面那个数与前面那个数毫无关系。
随机数又分为真随机数和伪随机数。真随机数:完全随机,毫无规律;伪随机数:用确定性算法计算出的随机数序列,并非真随机。
ESP32-P4内置一个真随机数发生器,其生成的32位随机数可作为加密等操作的基础。
ESP32-P4的随机数发生器可通过物理过程而非算法生成真随机数,所有生成的随机数在特定范围内出现的概率完全一致。
接下来,介绍一下随机数生成的过程,如下图所示。

第二十六章 RNG实验418.png
图26.1.1 随机数生成过程

随机数的源,在这里称为噪声源。噪声源为系统中的热噪声和异步时钟。使用随机数生成器时,至少启用其一,否则,生成的是伪随机数。热噪声可以来自SAR ADC。当芯片SAR ADC工作时,就会产生比特流,并通过异或(XOR)逻辑运算作为随机数种子进入随机数生成器。RC_FAST_CLK是一种异步时钟源,它通过引入电路亚稳态来增加RNG熵。
当有噪声来自SAR ADC时,随机数发生器在一个RC_FAST_CLK时钟周期中被输入1位熵,这是由内部RC振荡器产生的。读取LPSYSREG_RNG_DATA_REG寄存器时可用最大速率1MHz异或以获得最大熵。

26.2 硬件设计

26.2.1 例程功能
使用ESP32-P4的硬件随机数发生器来生成随机数,并显示在LCD屏幕上。按下BOOT可以获取一次随机数。同时程序会自动获取0~9范围内的随机数,显示在LCD屏上。LED0闪烁用于提示程序正在运行。

26.2.2 硬件资源
1)LED灯
        LED        0        - IO51
2)KEY按键
        BOOT        - IO35
3)RGBLCD / MIPILCD(引脚太多,不罗列出来)

26.2.3 原理图
RNG属于ESP32-P4的片上资源,因此没有对应的连接原理图。

26.3 程序设计

26.3.1 RNG的IDF驱动
使用RNG相关功能函数,必须先导入以下头文件:
  1. #include "esp_random.h"
复制代码
接下来,作者将介绍一些常用的函数,这些函数的描述及其作用如下:
1,得到随机数函数esp_random
该函数用于从系统中获取时间,其函数原型如下:
  1. uint32_t esp_random(void);
复制代码
无函数形参
函数返回值:
返回的是0~uint32_max之间的随机数。

26.3.2 程序流程图

第二十六章 RNG实验1216.png
图26.3.2.1 RNG实验程序流程图

26.3.3 程序解析
在17_rng例程中,作者在17_rng\components\BSP路径下新增了1个文件夹RNG,并且需要更改CMakeLists.txt内容,以便在其他文件上调用。
1. RNG驱动代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。RNG驱动源码包括两个文件:rng.c和rng.h。
rng.h用于声明rng_get_random_num等函数,以便在其他文件中调用,具体内容不再赘述。
下面我们再解析rng.c的程序,主要就是两个获取随机数的函数rng_get_random_num和rng_get_random_range,他们的功能是不一样的,代码如下:
  1. <font size="3">/**</font>
  2. <font size="3"> * @brief            得到随机数</font>
  3. <font size="3"> * [url=home.php?mod=space&uid=271674]@param[/url]             无</font>
  4. <font size="3"> * @retval             获取到的随机数(32bit)</font>
  5. <font size="3"> */</font>
  6. <font size="3">uint32_t rng_get_random_num(void)</font>
  7. <font size="3">{</font>
  8. <font size="3">    return esp_random();</font>
  9. <font size="3">}</font>

  10. <font size="3">/**</font>
  11. <font size="3"> * @brief             得到某个范围内的随机数</font>
  12. <font size="3"> * @param             min,max: 最小,最大值.</font>
  13. <font size="3"> * @retval             得到的随机数(rval),满足:min<=rval<=max</font>
  14. <font size="3"> */</font>
  15. <font size="3">int rng_get_random_range(int min, int max)</font>
  16. <font size="3">{ </font>
  17. <font size="3">    return esp_random() % (max - min + 1) + min;</font>
  18. <font size="3">}</font>
复制代码
上述两个函数都是调用esp_random函数实现功能的。rng_get_random_num函数用于读取一个32位随机数,而rng_get_random_range函数用于读取一个特定范围内的随机数。
2. CMakeLists.txt文件
本例程的功能实现主要依靠RNG驱动。要在main函数中,成功调用RNG文件中的内容,就得需要修改BSP文件夹下的CMakeLists.txt文件,修改如下:
  1. <font size="3">set(src_dirs</font>
  2. <font size="3">                   LED</font>
  3. <font size="3">                        KEY</font>
  4. <font size="3">                        LCD</font>
  5. <font size="3">                   RNG)</font>

  6. <font size="3">set(include_dirs</font>
  7. <font size="3">                  LED</font>
  8. <font size="3">                        KEY</font>
  9. <font size="3">                        LCD</font>
  10. <font size="3">                   RNG)</font>

  11. <font size="3">set(requires</font>
  12. <font size="3">                   driver</font>
  13. <font size="3">                   esp_lcd</font>
  14. <font size="3">                        esp_common)</font>

  15. <font size="3">idf_component_register(        SRC_DIRS ${src_dirs} INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})</font>

  16. <font size="3">component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format)</font>
复制代码
3. main.c驱动代码
在main.c里面编写如下代码。
  1. <font size="3">void app_main(void)</font>
  2. <font size="3">{</font>
  3. <font size="3">    esp_err_t ret;</font>
  4. <font size="3">    uint8_t key = 0;</font>
  5. <font size="3">    uint32_t random = 0;</font>
  6. <font size="3">    uint8_t t = 0;</font>

  7. <font size="3">    ret = nvs_flash_init();          /* 初始化NVS */</font>
  8. <font size="3">    if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)</font>
  9. <font size="3">    {</font>
  10. <font size="3">        ESP_ERROR_CHECK(nvs_flash_erase());</font>
  11. <font size="3">        ESP_ERROR_CHECK(nvs_flash_init());</font>
  12. <font size="3">    }</font>

  13. <font size="3">    led_init();                     /* LED初始化 */</font>
  14. <font size="3">    key_init();                     /* KEY初始化 */</font>
  15. <font size="3">    lcd_init();                     /* LCD屏初始化 */</font>
  16. <font size="3">    lcd_show_string(30, 50,  200, 16, 16, "ESP32-P4", RED);</font>
  17. <font size="3">    lcd_show_string(30, 70,  200, 16, 16, "RNG TEST", RED);</font>
  18. <font size="3">    lcd_show_string(30, 90,  200, 16, 16, "ATOM@ALIENTEK", RED);</font>
  19. <font size="3">    lcd_show_string(30, 110, 200, 16, 16, "BOOT:Get Random Num", RED);</font>
  20. <font size="3">    lcd_show_string(30, 130, 200, 16, 16, "Random Num:", RED);</font>
  21. <font size="3">    lcd_show_string(30, 150, 200, 16, 16, "Random Num[0-9]:", RED);</font>

  22. <font size="3">    while(1)</font>
  23. <font size="3">    {</font>
  24. <font size="3">        key = key_scan(0);</font>

  25. <font size="3">        if (key == BOOT_PRES)    </font>
  26. <font size="3">        {</font>
  27. <font size="3">            random = rng_get_random_num();             /* 获取随机数 */</font>
  28. <font size="3">            lcd_show_num(118, 130, random, 10, 16, BLUE);</font>
  29. <font size="3">            ESP_LOGI("test", "data:%ld ", random);</font>
  30. <font size="3">        }</font>

  31. <font size="3">        if ((t % 20) == 0)         </font>
  32. <font size="3">        {                                </font>
  33. <font size="3">            random = rng_get_random_range(0, 9);        /* 取[0,9]区间的随机数 */</font>
  34. <font size="3">            lcd_show_num(158, 150, random, 1, 16, BLUE);</font>

  35. <font size="3">            LED0_TOGGLE(); </font>
  36. <font size="3">        }</font>

  37. <font size="3">        vTaskDelay(pdMS_TO_TICKS(10));</font>
  38. <font size="3">        t++;</font>
  39. <font size="3">    }</font>
  40. <font size="3">}</font>
复制代码
在app_main函数中,完成所需外设初始化以后,进入到死循环,等待按键按下,如果BOOT按键按下,则调用rng_get_random_num函数,读取随机数值,并将读到的随机数显示在LCD上面。每隔200ms调用rng_get_random_range函数获取一次区间[0,9]的随机数,并实时显示在LCD上。LED0闪烁,以提示程序正在运行。

26.4 下载验证
将程序下载到开发板后,可以看到LED0不停闪烁,提示程序已经在运行了。然后我们按下BOOT按键,就可以在LCD上看到获取到的随机数。同时,就算不按BOOT按键,程序也会自动的获取0~9区间的随机数显示在LCD上。实验效果如图26.4.1所示。

第二十六章 RNG实验4198.png
图26.4.1 RNG实验程序运行效果图
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-1-7 16:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表