打印
[技术问答]

单片机C语言如何产生随机数

[复制链接]
1650|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sesefadou|  楼主 | 2025-2-24 04:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
随机数在单片机的应用中也是很多的,当然产生随机数的方法有很多,当中有一个就是利用单片机定时器,取出未知的定时器THX和TLX的值,再加以运算得到一个规定范围内的随机数值。这做法也是可行的。或者预先写好一个随机数表,然后进行取数据。也是可以的。
KEIL里面产生随机数的函数确实是rand(),但头文件是stdlib.h,不是time.h。C语言提供了一些库函数来实现随机数的产生。C语言中有三个通用的随机数发生器,分别为 rand函数, random函数, randomize 函数;但是rand函数产生的并不是真意正义上的随机数,是一个伪随机数,是根据一个数,称之为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是void srand( int a);在调用rand函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。一般用for语句来设置种子的个数。

单片机产生随机数的两种方法

方法一:定时器直接随机取值

每按一次按键生成一个随机数,这个随机数实际是把定时器的值给取出来了,并不能算绝对的随机、方法二才是真正意义上的随机。

方法二:用定时器加rand()随机函数来实现

单片机上电之后通过按键去启动取随机数,若是单片机上电就立即取随机数的话,那每次上电随机的结果都是一样的。然后是0 到9不重复的随机数,程序中用了循环来判断是否和前面取的随机数相同,相同则进入,下次取随机数,不同则存入数组。

使用特权

评论回复
沙发
a_ziliu| | 2025-2-25 14:37 | 只看该作者
adc可以拿来产生随机数阵列

使用特权

评论回复
板凳
1988020566| | 2025-3-10 17:46 | 只看该作者
线性同余生成器              

使用特权

评论回复
地板
sheflynn| | 2025-3-11 15:41 | 只看该作者
使用外部噪声源的值作为种子,可以提高随机性。

使用特权

评论回复
5
kkzz| | 2025-3-11 22:09 | 只看该作者
利用外部环境的噪声,如热噪声、光电效应等,作为随机数的种子。

使用特权

评论回复
6
gouguoccc| | 2025-3-12 08:01 | 只看该作者
C语言标准函数库有一个软件随机数发生器,但是这个没法保证唯一性。

使用特权

评论回复
7
SophiaOP| | 2025-3-12 10:31 | 只看该作者
真随机数要用专用的芯片

使用特权

评论回复
8
wilhelmina2| | 2025-3-12 16:09 | 只看该作者
环境噪声是不可预测的,生成的随机数具有较高的随机性;适用性广,大多数单片机都配备ADC,可以方便地实现。

使用特权

评论回复
9
1988020566| | 2025-3-14 22:30 | 只看该作者
伪随机数生成器产生的随机数在统计上可能并不完美

使用特权

评论回复
10
burgessmaggie| | 2025-3-15 01:36 | 只看该作者
定时器计数值的随机性取决于定时器的启动时间和中断触发等因素。

使用特权

评论回复
11
averyleigh| | 2025-3-15 08:33 | 只看该作者
系统计时器通常用于生成时基或测量时间间隔,其计数值在每次读取时都不同,可以用于生成随机数。

使用特权

评论回复
12
mikewalpole| | 2025-3-16 11:31 | 只看该作者
读取未使用的ADC通道,获取环境噪声作为随机源。

使用特权

评论回复
13
juliestephen| | 2025-3-16 13:01 | 只看该作者
线性同余生成器(LCG)​              

使用特权

评论回复
14
abotomson| | 2025-3-16 13:26 | 只看该作者
模拟输入引脚的噪声可能受到外界环境的影响,如电磁干扰、电源波动等,因此生成的随机数可能存在一定的偏差。

使用特权

评论回复
15
tabmone| | 2025-3-16 14:15 | 只看该作者
uint32_t get_clock_jitter(void) {
    uint32_t start = DWT_Cyccnt;
    for (volatile int i = 0; i < 1000; i++);
    uint32_t end = DWT_Cyccnt;
    return end - start; // 利用时钟周期抖动
}

使用特权

评论回复
16
SophiaOP| | 2025-3-17 20:54 | 只看该作者
软件只能写出伪随机数

使用特权

评论回复
17
qiufengsd| | 2025-3-18 22:04 | 只看该作者
需要对采集到的随机数进行适当的处理,如取模运算,以得到所需范围内的随机数。

使用特权

评论回复
18
juliestephen| | 2025-3-19 11:44 | 只看该作者
硬件随机数生成器              

使用特权

评论回复
19
belindagraham| | 2025-3-19 14:50 | 只看该作者
如果你的单片机有实时时钟(RTC)或高精度的计数器,你可以使用它们来生成种子值,从而初始化你的伪随机数生成器。这样,每次程序运行时,由于种子值的不同,你将得到不同的随机数序列。

使用特权

评论回复
20
hearstnorman323| | 2025-3-19 18:13 | 只看该作者
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NUM_RANDOM_VALUES 100

// 预定义的随机数表
const int random_table[NUM_RANDOM_VALUES] = {
    45, 23, 89, 12, 67, 34, 56, 78, 90, 11,
    22, 33, 44, 55, 66, 77, 88, 99, 10, 20,
    30, 40, 50, 60, 70, 80, 91, 12, 34, 56,
    78, 90, 11, 22, 33, 44, 55, 66, 77, 88,
    99, 10, 20, 30, 40, 50, 60, 70, 80, 91,
    12, 34, 56, 78, 90, 11, 22, 33, 44, 55,
    66, 77, 88, 99, 10, 20, 30, 40, 50, 60,
    70, 80, 91, 12, 34, 56, 78, 90, 11, 22,
    33, 44, 55, 66, 77, 88, 99, 10, 20, 30,
    40, 50, 60, 70, 80, 91, 12, 34, 56, 78
};

int main() {
    // 设置随机数种子
    srand((unsigned int) time(NULL));

    // 随机选择一个索引
    int index = rand() % NUM_RANDOM_VALUES;

    // 获取随机数
    int random_number = random_table[index];

    // 打印随机数
    printf("Random number: %d\n", random_number);

    return 0;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

1669

帖子

0

粉丝