STM32 产生随机数方式

news2024/11/19 8:37:10

STM32 产生随机数方式

C语言的stdlib.h库里的srand(unsigned seed)和rand(void)函数,可以配合产生伪随机数。其中srand(seed)产生算法种子,再由rand()通过算法产生随机数,产生的随机数在宏定义RAND_MAX范围内。如果seed不变,则产生的随机数不变。

这里介绍STM32 HAL库环境的随机数产生代码,采用STM32CUBEIDE开发环境,以STM32F103C6T6为例,通过USB虚拟串口将归一化随机数打印出,归一化随机数为0~1之间的浮点值。顺便这里将STM32指令微秒延时函数PY_Delay_us_t(us);的基本参数usDelayBase的测定值打印出。STM32微秒延时函数参考: STM32 HAL us delay(微秒延时)的指令延时实现方式及优化 。

STM32工程配置

首先建立基本工程并设置时钟,这里只用到USB接口用于打印输出:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
设置USB虚拟串口:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
保存并生成初始工程文件:
在这里插入图片描述

STM32随机数生成代码

随机数种子seed的选择,在计算机应用领域,可以采用系统时间作为种子,而在嵌入式方面,因为STM32 HAL有不断运行的毫秒计数值uwTick,因此可选作随机数种子。uwTick是递增形态,为了加强随机性,还可以将uwTick进行一次CRC32计算得到32位验证码,然后用此验证码作为随机数种子。STM32的硬件和软件CRC32计算,参考 C语言CRC-32 STM32格式校验函数,硬件CRC32可以加快随机数产生速度,而软件CRC32则具有通用型,一些型号MCU并不具有硬件CRC32计算组件。

采用空间节约的编译方式,参考 STM32 region `FLASH‘ overflowed by xxx bytes 问题解决
USB虚拟串口的使用,参考 STM32 USB VCOM和HID的区别,配置及Echo功能实现(HAL)
采用的浮点转字符函数py_f2s4printf(),参考 STM32 UART串口printf函数应用及浮点打印代码空间节省 (HAL)

主要功能代码实现部分如下:

      if(USB_CONN_STATUS())
      {
    	     py_f2s4printf(fchar, usDelayBase, 8);
    	     sprintf(console, "usDelayBase for STM32F103 in 72MHz is %s\r\n", fchar);
			 CDC_Transmit_FS((uint8_t*)console, strlen(console)) ;

			 seed = uwTick;
			 srand((unsigned)PY_CRC_32_T32_STM32(&seed, 1));
			 rn = ((float)rand())/RAND_MAX;
			 py_f2s4printf(fchar, rn, 8);
			 sprintf(console, "Random number is %s\r\n\r\n", fchar);
			 CDC_Transmit_FS((uint8_t*)console, strlen(console)) ;
      }

包含主要功能代码的完整的main.c文件:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{
  __IO uint32_t firstms, secondms;
  __IO uint32_t counter = 0;

  firstms = HAL_GetTick()+1;
  secondms = firstms+1;

  while(uwTick!=firstms) ;

  while(uwTick!=secondms) counter++;

  usDelayBase = ((float)counter)/1000;
}

void PY_Delay_us_t(uint32_t Delay)
{
  __IO uint32_t delayReg;
  __IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}

void PY_usDelayOptimize(void)
{
  __IO uint32_t firstms, secondms;
  __IO float coe = 1.0;

  firstms = HAL_GetTick();
  PY_Delay_us_t(1000000) ;
  secondms = HAL_GetTick();

  coe = ((float)1000)/(secondms-firstms);
  usDelayBase = coe*usDelayBase;
}


void PY_Delay_us(uint32_t Delay)
{
  __IO uint32_t delayReg;

  __IO uint32_t msNum = Delay/1000;
  __IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);

  if(msNum>0) HAL_Delay(msNum);

  delayReg = 0;
  while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
uint32_t PY_CRC_32_T32_STM32(uint32_t *di, uint32_t len)
{
	uint32_t crc_poly = 0x04C11DB7;  //X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+1 total 32 effective bits without X^32.
	//uint32_t data_t = 0; //CRC register
	uint32_t data_t = 0xffffffff; //CRC register

    for(uint32_t i = 0; i < len; i++)
    {
    	data_t ^= di[i]; //32-bit data

        for (uint8_t j = 0; j < 32; j++)
        {
            if (data_t & 0x80000000)
            	data_t = (data_t << 1) ^ crc_poly;
            else
            	data_t <<= 1;
        }
    }
    return (data_t);
}

uint32_t seed;
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
/*
*Convert float to string type
*Written by Pegasus Yu in 2022
*stra: string address as mychar from char mychar[];
*float: float input like 12.345
*flen: fraction length as 3 for 12.345
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
void py_f2s4printf(char * stra, float x, uint8_t flen)
{
	uint32_t base;
	int64_t dn;
	char mc[32];

	base = pow(10,flen);
	dn = x*base;
	sprintf(stra, "%d.", (int)(dn/base));
	dn = abs(dn);
	if(dn%base==0)
	{
		for(uint8_t j=1;j<=flen;j++)
		{
			stra = strcat(stra, "0");
		}
		return;
	}
	else
	{
		if(flen==1){
			sprintf(mc, "%d", (int)(dn%base));
			stra = strcat(stra, mc);
			return;
		}

		for(uint8_t j=1;j<flen;j++)
		{
			if((dn%base)<pow(10,j))
			{
				for(uint8_t k=1;k<=(flen-j);k++)
				{
					stra = strcat(stra, "0");
				}
				sprintf(mc, "%d", (int)(dn%base));
				stra = strcat(stra, mc);
				return;
			}
		}
		sprintf(mc, "%d", (int)(dn%base));
		stra = strcat(stra, mc);
		return;
	}
}

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
char fchar[16];
char console[256];

float rn;
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */
  PY_usDelayTest();
  PY_usDelayOptimize();


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      if(USB_CONN_STATUS())
      {
    	     py_f2s4printf(fchar, usDelayBase, 8);
    	     sprintf(console, "usDelayBase for STM32F103 in 72MHz is %s\r\n", fchar);
			 CDC_Transmit_FS((uint8_t*)console, strlen(console)) ;

			 seed = uwTick;
			 srand((unsigned)PY_CRC_32_T32_STM32(&seed, 1));
			 rn = ((float)rand())/RAND_MAX;
			 py_f2s4printf(fchar, rn, 8);
			 sprintf(console, "Random number is %s\r\n\r\n", fchar);
			 CDC_Transmit_FS((uint8_t*)console, strlen(console)) ;
      }

      PY_Delay_us_t(500000);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


代码测试效果

版本下载后,通过USB连接虚拟串口,测试效果如下:

在这里插入图片描述

例程下载

STM32F103C6T6为例 随机数产生例程下载

–End–

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/455053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

测试从未如此简单:接口自动化测试Python脚本实现

目录 摘要 步骤1&#xff1a;安装依赖项 步骤2&#xff1a;编写测试脚本 步骤3&#xff1a;运行测试 结论 摘要 自动化测试是现代软件开发过程中的重要环节。在许多情况下&#xff0c;特别是在web应用程序和移动应用程序中&#xff0c;接口自动化测试是其基础。下面就来介绍一…

嵌入式就业怎么样?

嵌入式就业怎么样? 现在的IT行业,嵌入式是大热门&#xff0c;下面也要来给大家介绍下学习嵌入式之后的发展以及就业怎么样。 首先是好找工作。嵌入式人才目前是处于供不应求的状态中&#xff0c;据权威统计机构统计在所有软件开发类人才的需求中&#xff0c;对嵌入式工程师的…

详解树与二叉树的概念,结构,及实现(上篇)

目录 一&#xff0c; 树 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 二&#xff0c; 二叉树 2.1二叉树概念 三&#xff0c;特殊的二叉树 1. 满二叉树 2. 完全二叉树 3. 1 二叉树的性质 3. 2 二叉树的存储…

北邮22信通:二叉树层序遍历的两种方法首发模板类交互

北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 获取更多文章 请访问专栏~ 北邮22信通_青山如墨雨如画的博客-CSDN博客 目录 一.总纲 二.用队列存储 2.1用模板类实现队列 2.1.1核心思路&#xff1a; …

FL Studio电音编曲软件V21中文完整版 安装下载教程

目前水果软件最版本是FL Studio 21&#xff0c;它让你的计算机就像是全功能的录音室&#xff0c;大混音盘&#xff0c;非常先进的制作工具&#xff0c;让你的音乐突破想象力的限制。喜欢音乐制作的小伙伴千万不要错过这个功能强大&#xff0c;安装便捷的音乐软件哦&#xff01;…

PTA L2-045 堆宝塔 (25 分)

堆宝塔游戏是让小朋友根据抓到的彩虹圈的直径大小&#xff0c;按照从大到小的顺序堆起宝塔。但彩虹圈不一定是按照直径的大小顺序抓到的。聪明宝宝采取的策略如下&#xff1a; 首先准备两根柱子&#xff0c;一根 A 柱串宝塔&#xff0c;一根 B 柱用于临时叠放。把第 1 块彩虹圈…

掌握ChatGPT:全面指南和GPT-3.5与GPT-Plus的对比分析

在人工智能领域&#xff0c;最近的一大重磅炸弹是OpenAI发布了GPT-4架构下的ChatGPT。这款先进的自然语言处理模型已经引起了很多关注&#xff0c;让我们来深入了解怎么使用这个强大的工具&#xff0c;以及比较GPT-3.5与GPT-Plus的差异。 什么是ChatGPT&#xff1f; ChatGPT是…

JavaScript经典教程(三)-- JavaScript -- 基础数据类型详解

183&#xff1a;基础数据类型详解 1、复习 1、全局变量&#xff1a; 依托于window环境下的的变量。 在window大环境下&#xff08;即最外层&#xff09;申明的变量a&#xff0c;即为全局变量。 2、window&#xff1a; window下的变量为全局变量。 window可省略。 3、作用域…

021 - C++ 构造函数

我们继续学习 C 的面向对象编程&#xff0c;本期主要是讲其中的 构造函数。 什么是构造函数呢&#xff1f; 构造函数基本上是一种特殊类型的方法&#xff0c;它在每次实例化对象时运行。 我们直接来看一个例子吧。 例子时间 我们将要通过创建一个 Entity 类来深入了解这个…

vscode python3.6配置pcl点云库 obj3d模型转pcd点云图

配置vscode python3.6的环境我就跳过了,网上都有 1.下载PCL1.9 github:pcl-1.9.1 百度云:PCL-1.9.1-AllInOne-msvc2017-win64提取码adcx 2.安装硬盘任意位置,我是E盘,在安装过程中会弹出openni的安装提示,将它安装路径选择在E:\PCL 1.9.1\3rdParty\OpenNI2,等待安装完成 3.…

.netCHATING 10.4 for NET6-7.0-Crack

.NET 6.0图表支持--dotnetcharting .netCHATING 10.4添加了.NET 6.0图表nuget包和.NET 6.0图表示例包&#xff08;需要Visual Studio 2022&#xff09;&#xff0c;.NET 5是.NET Core 3.1和.NET Framework 4.8的继任者&#xff0c;旨在为.NET开发人员提供新的跨平台开发体验。…

Mysql列的类型定义(字符串类型)

文章目录 一、CHAR 类型和 VARCHAR 类型 1.字符串字符(M)2.实战类型二、TEXT 类型 1.类型表2.特别注意3.实战建议4.实战练习三、ENUM 和 SET 类型 1.ENUM类型2.SET类型总结 一、CHAR 类型和 VARCHAR 类型 CHAR类型和VARCHAR类型都在创建表时指定了最大长度&#xff0c;其基本形…

Java版工程行业管理系统源码-专业的工程管理软件-提供一站式服务

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

对数据结构的初步认识

前言: 牛牛开始更新数据结构的知识了.本专栏后续会分享用c语言实现顺序表,链表,二叉树,栈和队列,排序算法等相关知识,欢迎友友们互相学习,可以私信互相讨论哦! &#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&a…

拿下多家车企定点!4D毫米波雷达「域」系统首发出道

从1R、2R、3R到整车360感知方案&#xff0c;毫米波雷达的前装市场需求量依然保持着快速增长的态势。 高工智能汽车研究院监测数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;前装标配搭载ADAS毫米波雷达&#xff08;前向后向盲区&#xff09;交付1795.…

mov是什么格式的视频,mov怎么转mp4

mov是什么格式的视频&#xff0c;MOV即QuickTime影片格式&#xff0c;它是Apple公司开发的一种音频、视频文件格式&#xff0c;用于存储常用数字媒体类型。MOV部分编码在没有quicktime的电脑中不能播放&#xff0c;不能后期剪辑制作MP4的通用率高于MOV格式支持MP4格式的播放器绝…

获得将要生成的资源的GUID

1&#xff09;获得将要生成的资源的GUID ​2&#xff09;多个小资源包合并为大资源包的疑问 3&#xff09;模型Meta中的hasExtraRoot参数的作用和历史原因 4&#xff09;合批注意点 这是第333篇UWA技术知识分享的推送&#xff0c;也是《厚积薄发 | 技术分享》第三回&#xff0c…

PMP-上班摸鱼整理的知识点

1、主要解决流程:问题-风险-变更: 先分析是问题还是风险&#xff0c;解决问题、可以减少新的风险&#xff0c;登记风险&#xff0c;可以随时应对问题,2、变更管理流程 变更原则: 需提正式变更申请&#xff0c;先分析评估后变更&#xff0c;不改变基准项目经理审批&#xff0c;改…

2-07 使用JMeter测试单节点与集群的并发异常率

2-07 使用JMeter测试单节点与集群的并发异常率 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YVXaAkn2-1682304913240)(https://static.editool.cn/upload/47093438fcec4683a50626ae46a49942/pic-371.jpg)] [外链图片转存失败,源站可能有防盗链机制…

一些海洋资料收集及磁力tiff的数据提取

以下资料都来自于网络和公开发表的文献&#xff0c;欢迎下载 1、第一批至第十一批农业部国家级种质资源保护区的范围&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1fGcVcdbOUb3tOlYB8d4JUg 提取码&#xff1a;kgix 2、EGM2008 链接&#xff1a;https://pan.baidu…