Exploration and practice of SCM32F1 random number generation (based on CUBEMX and KEIL5)

Random numbers are widely used in games and test environments. The random numbers generated in this article will be used to test the performance of the sorting algorithm.

Some high-end single-chip microcomputers have hardware random number generators, such as STM32F4, STM32H7, etc. From the structure and principle of the random number generators of these single-chip microcomputers, the principle generates and collects analog noise signals, and true random numbers can be generated using this hardware. However, low-end single-chip microcomputers, such as STM32F1, 8051, etc. do not have random number generators, and can only use software to generate pseudo-random numbers.

When generating pseudo-random numbers, the random number generator functions in <stdlib.h> are usually used. However, it must be clear before use that this random number generator function is not a panacea, otherwise high-end single-chip microcomputers do not need a random number generator. If you want to generate more random random numbers, you must provide a different random number seed before each random number generation .

The code to generate random numbers is as follows:

    #include <stdlib.h>	
    srand(每次需要一个不同的无符号整型数值);//随机数种子设置
	#define RANDOM_MAX	65535		//随机数最大值
	#define RANDOM_MIN  0			//随机数最小值
	uint32_t random_value;
	random_value = rand() % (RANDOM_MAX + 1 - RANDOM_MIN) + RANDOM_MIN;//随机数生成
	printf("	当前随机数为:%d\r\n", random_value);

With these few lines of code, it is enough to generate a desired random number, but the last step before success is the generation of the random number seed.

After testing, each time a random number is generated, a different seed must be given, otherwise the generated random numbers will be the same.

There are many ways to generate random number seeds. Commonly used random number generation methods include: using timers, real-time clocks, analog circuits and ADCs. The specific effect of the way of analog circuit generation will be determined by the structure of the analog circuit. This article only explores and practices two ways of timer generation and real-time clock generation.

The first is the real-time clock way

The configuration of the real-time clock is as follows:

 The code to read the time is as follows:

	RTC_DateTypeDef  date_info;
	RTC_TimeTypeDef  time_info;
	HAL_RTC_GetTime(&hrtc, &time_info, RTC_FORMAT_BIN);	  //读时间
	HAL_RTC_GetDate(&hrtc, &date_info, RTC_FORMAT_BIN);   //读日期
    srand(time_info.Hours+time_info.Minutes+time_info.Seconds);//随机数种子设置

Note: When using the RTC of STM32, whether only the time or the date is required, both the date and time must be read when reading, and the time must be read first and then the date (in STM32H7 and STM32F0 must be in this order otherwise it cannot be used normally).

The code uses time as a random number seed, which changes every second. The actual test is shown in the figure below:

 It can be clearly seen from the figure that the same random number is generated every second. If you want to generate a true random number using this method, you can only generate one per second. As shown below:

 Although this can generate random numbers, it cannot meet the test requirements, because the author needs to quickly generate several random numbers for testing the sorting algorithm. So it is necessary to find a random number seed that is updated faster than the random number generation speed. Timer generation is used here .

The timer can work at a very high frequency, and setting the timer to the automatic reload mode can produce rapidly changing values ​​repeatedly. The timer configuration interface is as follows:

The places that need to be manually configured are shown in the yellow area in the figure, and the rest can be defaulted. Among them, the PSC frequency divider configuration can choose other values, do not choose too large or the timer value will still change very slowly. Auto-reload automatic reloading must be turned on.

After using this method, the code is as follows (TIM3 is used here): 

	HAL_TIM_Base_Start(&htim3);//打开定时器
	srand(__HAL_TIM_GET_COUNTER(&htim3));//随机数种子设置
	#define RANDOM_MAX	65535		//随机数最大值
	#define RANDOM_MIN  0			//随机数最小值
	uint32_t random_value;
	random_value = rand() % (RANDOM_MAX + 1 - RANDOM_MIN) + RANDOM_MIN;//随机数生成
	printf("	当前随机数为:%d\r\n", random_value);

You can also use this method with a real-time clock, ie:

	HAL_RTC_GetTime(&hrtc, &time_info, RTC_FORMAT_BIN);	  
	HAL_RTC_GetDate(&hrtc, &date_info, RTC_FORMAT_BIN);
	printf("当前时间:%2d:%2d:%2d", time_info.Hours, time_info.Minutes, time_info.Seconds);	 
	HAL_TIM_Base_Start(&htim3);
	srand(time_info.Hours+time_info.Minutes+time_info.Seconds+__HAL_TIM_GET_COUNTER(&htim3));//随机数种子设置
	#define RANDOM_MAX	65535		//随机数最大值
	#define RANDOM_MIN  0			//随机数最小值
	uint32_t random_value;
	random_value = rand() % (RANDOM_MAX + 1 - RANDOM_MIN) + RANDOM_MIN;//随机数生成
	printf("	当前随机数为:%d\r\n", random_value);

The running effect is as shown in the figure, which can quickly generate random numbers and meet the requirements:

 The complete code of this part is as follows. Since FreeRTOS is used, only the code of the process of generating random numbers is shown here:

#include <stdio.h>
#include <stdlib.h>
#include "rtc.h"
#include "tim.h"
/* USER CODE BEGIN Header_Algorithm_Function */
/**
* @brief Function implementing the Algorithm_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Algorithm_Function */
void Algorithm_Function(void *argument)
{
  /* USER CODE BEGIN Algorithm_Function */
	RTC_DateTypeDef  date_info;
	RTC_TimeTypeDef  time_info;
	printf("勇敢牛牛,不怕困难\r\n");
  /* Infinite loop */
  for(;;)
  {
	HAL_RTC_GetTime(&hrtc, &time_info, RTC_FORMAT_BIN);	  
	HAL_RTC_GetDate(&hrtc, &date_info, RTC_FORMAT_BIN);
	printf("当前时间:%2d:%2d:%2d", time_info.Hours, time_info.Minutes, time_info.Seconds);	 
	HAL_TIM_Base_Start(&htim3);
	srand(time_info.Hours+time_info.Minutes+time_info.Seconds+__HAL_TIM_GET_COUNTER(&htim3));//随机数种子设置
	#define RANDOM_MAX	65535		//随机数最大值
	#define RANDOM_MIN  0			//随机数最小值
	uint32_t random_value;
	random_value = rand() % (RANDOM_MAX + 1 - RANDOM_MIN) + RANDOM_MIN;//随机数生成
	printf("	当前随机数为:%d\r\n", random_value);
    osDelay(77);
  }
  /* USER CODE END Algorithm_Function */
}

Guess you like

Origin blog.csdn.net/Fairchild_1947/article/details/118757154