我曾经在单片机生成随机数的时候走入了误区
大家好我是小火,想学习单片机的同学可以关注、私信我或者在评论区回复小火。
今天我们来聊一下单片机生产随机数这个东西。相信大家都有在街边见过一个叫作打地鼠的游戏,这个游戏就是地鼠从洞里钻出来给我们锤,是一个解压的好游戏。在这个游戏中,地鼠随机钻出来就需要用到我们单片机的产生随机数。
很多同学的第一反应是这个项目做起来非常简单,不就是随机函数么,我也是这样想的,C语言课上我们就已经学过了。可是真正用这个方法做了之后却发现现实和想象中还是有一定的差距,程序像是写死的,复位后每次的顺序都是固定的,并没有随机的效果,于是我上网收集了很多资料,仔细研究了一下,总结了单片机生成随机数的几种常见方法。
首先,大家心里一定要要明确一点:一个独立的单片机系统,如果不引入一个随机信号,永远不能实现随机的效果。这里的随机信号可以是用户的交互、时间、采集的外部数据等等,我们常用伪随机数列+随机数种子的方式实现随机的效果,而这些随机信号就是用来做随机数种子。下面是我所使用的生成伪随机数代码。
……
#include<stdlib.h>
……
#define MAX 16 //随机数最大值
#define MIN 1 //随机数最小值
unsigned int random(unsigned int xxx)
{
unsigned int value,iii;
for(iii=0;iii<xxx;iii++)
{
value = rand() % (MAX + 1- MIN) + MIN; //获取一个随机数(1-16)
}
return value;
}
或者利用srand()函数,将上述函数改写成
unsigned int random(unsigned int xxx)
{
unsigned int value;
srand(xxx);
value = rand() % (MAX + 1 - MIN)+ MIN; //获取一个随机数(1-16)
return value;
}
说明:
srand()函数位于表头文件中,用来设置rand()产生随机数时的随机数种子。
定义函数 void srand (unsigned int seed);
参数seed必须是个整数,如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。
在上述程序中将用户按下按键时定时器中的ms时间值后两位作为函数的输入参数,这样就能获得一个随机值。
单片机生成随机数的几种常用随机信号如下:
1. 用一路AD采集温度或电源噪声,取后几位作为随机信号;
2. 将用户的交互信号时间作为随机信号;
3. 利用时钟芯片或RTC获取当前时间再经处理作为随机信号;
4. 自己搭一个硬件电路用来产生随机信号,如利用单片机的内置时钟设为1M,外接一个用温度敏感电阻搭建一个特征频率10M的RC振荡电路,用慢时钟去采集快时钟,然后经过简单处理,就可以得到一个真正的随机数了。
想要学习单片机编程的同学可以持续关注小火,回复“我要入门”,与我们一起成长,喜欢的可以点个赞关注我们!
单片机还可以这样得到加密随机数?
一、什么是随机数?
(1)随机数是概念
随机数,顾名思义,就是随机生成的一个数据。
随机数
举个例子,我们在一堆红豆中,随手抓一把红豆,那么手中这把红豆的粒数,就是一个随机数。
因为我们无法具体预判抓的这一把红豆具体多少粒,这个数据是随机的,不可预算的,故这种方式产生的数据,就叫随机数。
(2)随机数的用法
随机数,可用于做一些需要随机的事件,如抽奖,掷骰子等。
同时,随机数也多用于简单的加密。通过随机生成的一个随机数,将一段需要加密的数据,进行一定的数据公式运算,然后发送出去,接收方只要知道这段接收到的数据中,哪一段是密钥随机数,哪一段是加密密文,就可以通过协定的公式反向运算,进行解密,就可以获得密文数据。
数据简单加密
二、生成随机数的方法
(1)通过单片机计数器的方式
通过单片机计数器的方式声明一个16位的变量CNT,并将其放置于主循环while(1)中,让其自加,如
当单片机运行到某一需要随机数的时候,如按键触发某个功能,需要获取随机数,来作为加密的随机码时,这时正在自增变化的CNT变量,提取其尾数(CNT%10),就可以作为一个伪随机数。
在这里,可能会有一个疑问了,为何这个值可以作为随机数使用呢?原因如下:
1)裸机跑单片机属于单线程运行方式,在主循环while(1){}中,循环一次所需时间,是根据每次循环所执行的内容决定的,具有不确定性;
2)当我们按下按键时,由于按下的时间点是不确定的,所以CNT变化了多少,也具有不确定性;
3)由于单片机主频很高,在我们触发时,CNT已经递增了数千个值了,故截取数据时,CNT的尾数,也是不确定性的。
因此,可以用该方式,来生成一个我们想要的随机数。
(2)通过ADC的方式
使用ADC的方式,采集芯片内部温度传感器的方式。来获得一个伪随机数。
我们自行测试能知道,单片机在通过ADC采集这个温度波形模拟信号时,该数值的尾数,变化是很随机的。而温度传感器,受到不同时刻温度的影响时,该值的尾数变化也是不确定的。
因此。我们可以通过该方式,来生成一个伪随机数。
ADC采集温度
(3)通过单片机自带的硬件随机数发生器的方式
有些单片机,集成了专有的硬件随机数发生器,通过获取该发生器的随机数值,即可得到一个理想的随机数。
如STM32F4 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个32 位的随机数。
RNG发生器图
相关问答
如何在 单片机 中生成 随机数 ?KEIL里面产生随机数的函数确实是rand(),但头文件是stdlib.h,不是time.h。KEIL里面产生随机数的函数确实是rand(),但头文件是stdlib.h,不是time.h。
看到有人用吴鉴鹰 单片机 开发板做贪吃蛇游戏,觉得很好玩,这个思路是啥啊?大神指导一下?很简单的东西,基础知识的组合而已。首先,你要会用lcd屏幕,能在上面显示东西。然后做一个定时器,做一个随机数。然后用4个按键控制方向。没难度。很简单的东...
单片机 flash和ram/ROM的区别?单片机FLASH主要用作程序存贮器,就是替代以前的ROM,最大的有有点是降低了芯片的成本并且可以做到电擦写,目前市场上单片机的FALSH寿命相差比较大,擦写次数从10...
ddsf242型单相电子式多费率电能表的各种详细功能[回答]ESAM是嵌入式安全模块(EmbeddedSecureAccessModule)的简称。目前在我国,嵌入式安全模块主要应用在水、电、气三表中。为使用IC卡作为预付费的三...
零基础该如何学习编程?先自己定一个计划,然后找一套方案,计划自己定,方案可以参考别人怎么学的。用玩单片机(属于嵌入式,要与硬件接触)举个例子,学习怎么玩单片机一般都是要选择...关...
手机关机的话金属检测仪还能检测得到吗?-ZOL问答JAVA、C、C++、Python同样是高级语言,为什么只有C和C++可以编写单片机程序?17...肿么在excel生成随机数小于指定单元格6056浏览5回答ZOL问答测试仪问题....
基于51 单片机 的游戏程序设计1.基本功能实现如下游戏规则:(1)...你的功能都可帮实现的