图31.3.1.1随机数实验程序流程图
31.3.2 RNG函数解析
ESP-IDF提供了一套API来配置RNG。要使用此功能,需要导入必要的头文件:
#include "esp_random.h"
接下来,作者将介绍一些常用的ESP32-S3中的RNG函数,这些函数的描述及其作用如下:
1,得到随机数
该函数用于获取一个32位的硬件随机数,其函数原型如下:
uint32_t esp_random(void);
该函数的形参描述,如下表所示:
表31.3.2.1 函数esp_random()形参描述
该函数的返回值描述,如下表所示:
| |
result ^ REG_READ(WDEV_RND_REG) | |
表31.3.2.2 函数esp_random ()返回值描述
31.3.3 RNG驱动解析
在IDF版21_rng例程中,作者在21_rng\components\BSP路径下新增了一个RNG文件夹,分别用于存放rng.c、rng.h这两个文件。其中,rng.h文件负责声明RNG相关的函数和变量,而rng.c文件则实现了RNG的驱动代码。下面,我们将详细解析这两个文件的实现内容。
1,rng.h文件
/* 函数声明 */
uint32_t rng_get_random_num(void); /* 得到随机数 */
int rng_get_random_range(int min, int max); /* 得到某个范围内的随机数 */
2,rng.c文件
/**
* @retval 获取到的随机数(32bit)
*/
uint32_t rng_get_random_num(void)
{
uint32_t randomnum;
randomnum = esp_random();
return randomnum;
}
/**
* @brief 得到某个范围内的随机数
* @param min,max: 最小,最大值.
* @retval 得到的随机数(rval),满足:min<=rval<=max
*/
int rng_get_random_range(int min, int max)
{
uint32_t randomnum;
randomnum = esp_random();
return randomnum % (max - min + 1) + min;
}
从上述代码中,我们不难看出,对于RNG我们并没有相应的初始化函数,ESP32 IDF提供了相应的API函数,我们只需调用即可,具体的在上一小节我们已经介绍过了,在此不做出赘述。
31.3.4 CMakeLists.txt文件
打开本实验BSP下的CMakeLists.txt文件,其内容如下所示:
set(src_dirs
IIC
KEY
LCD
LED
RNG
SPI
XL9555)
set(include_dirs
IIC
KEY
LCD
LED
RNG
SPI
XL9555)
set(requires
driver)
idf_component_register(SRC_DIRS ${src_dirs}
INCLUDE_DIRS ${include_dirs} REQUIRES ${requires})
component_compile_options(-ffast-math -O3 -Wno-error=format=-Wno-format) 上述的红色RNG驱动需要由开发者自行添加,以确保RNG驱动能够顺利集成到构建系统中。这一步骤是必不可少的,它确保了RNG驱动的正确性和可用性,为后续的开发工作提供了坚实的基础。
31.3.5 实验应用代码
打开main/main.c文件,该文件定义了工程入口函数,名为app_main。该函数代码如下。
i2c_obj_t i2c0_master;
/**
* @brief 程序入口
* @param 无
* @retval 无
*/
void app_main(void)
{
uint8_t key;
uint32_t random;
uint8_t t = 0;
esp_err_t ret;
ret = nvs_flash_init(); /* 初始化NVS */
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
led_init(); /* 初始化LED */
i2c0_master = iic_init(I2C_NUM_0); /* 初始化IIC0 */
spi2_init(); /* 初始化SPI2 */
xl9555_init(i2c0_master); /* 初始化XL9555 */
lcd_init(); /* 初始化LCD */
key_init(); /* 初始化按键 */
lcd_show_string(30, 50, 200, 16, 16, "ESP32", RED);
lcd_show_string(30, 70, 200, 16, 16, "RNG TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "RNG Ready! ", RED);
lcd_show_string(30, 130, 200, 16, 16, "BOOT:Get Random Num", RED);
lcd_show_string(30, 150, 200, 16, 16, "Random Num:", RED);
lcd_show_string(30, 180, 200, 16, 16, "Random Num[0-9]:", RED);
while(1)
{
key = key_scan();
if (key == BOOT) /* 获取随机数并显示至LCD */
{
random = rng_get_random_num();
lcd_show_num(30 + 8 * 11, 150, random, 10, 16, BLUE);
}
if ((t % 20) == 0) /* 获取0~9间的随机数并显示至LCD */
{
LED_TOGGLE(); /* 每200ms,翻转一次LED */
random = rng_get_random_range(0, 9); /* 取[0,9]区间的随机数 */
lcd_show_num(30 + 8 * 16, 180, random, 1, 16, BLUE);/* 显示随机数 */
}
vTaskDelay(10);
t++;
}
}
该部分代码也比较简单,在所有外设初始化成功后,进入死循环,等待BOOT按键按下,如果按下,则调用rng_get_random_num函数,读取随机数值,并将读到的随机数显示在LCD上面。每隔200ms获取一次区间[0,9]的随机数,并实时显示在液晶上。同时LED,周期性闪烁,400ms闪烁一次。
31.4 下载验证
将程序下载到开发板后,可以看到LED不停的闪烁,提示程序已经在运行了。然后我们按下BOOT,就可以在屏幕上看到获取到的随机数。同时,就算不按BOOT,程序也会自动的获取0~9区间的随机数显示在LCD上面。实验结果如图31.4.1所示: