单片机产生随机数的方法
基于51单片机随机数产生
![基于51单片机随机数产生](https://img.taocdn.com/s3/m/daacc030aeaad1f347933f58.png)
基于51单片机随机数产生一:系统主要功能与设计方案功能:可以根据需要产生给定范围内的任何数字(0--999),显示于数码管上。
设计方案:利用51单片机内部的定时器与中断结合,来模仿随机数的产生;单片机编程上电后,定时器便启动开始计数,计数范围可以预先设置,其设置的上限值被储存在24c02中;当中断0口产生低电平,进入中断函数读取定时器所跑的数值,经处理送入数码管显示。
二:电路的硬件电路搭建如下图,这里我们采用74ls595来驱动数码管,另外,为了防止电流过大这里串联一个75欧电阻用于限流;当操控"启动"按键后,三个数码管开始跑数字,操控“选择”锁定当前显示的数字,达到随机数产生的目的;考虑到,不同的人对随机数产生的范围要求不同,这里,通过操控“储存,加1,加10,”预设的上限值存储在24c02中。
三:软件设计#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define delay _nop_() /* 定义空指令*/sbit ds0= P2^0; //74ls595移位寄存器sbit st0=P2^1;sbit sh0=P2^2;sbit ds1= P2^3;sbit st1=P2^4;sbit sh1=P2^5;sbit ds2= P2^6;sbit st2=P2^7;sbit sh2=P0^7;sbit p30=P3^0; // 启动sbit p31=P3^1; // 加1sbit p32=P3^2; // 选择sbit p35=P3^5; // 存储sbit p36=P3^6; // 加10sbit scl=P0^0; //I2C 时钟sbit dat=P0^1; //I2C 数据bit ack; /*应答标志位*/uchar temp,a,j,aa,flag,flag1,flag2,flag3;uchar b,c,d;uchar bb,cc,dd;uchar x,y,z,f,xx;uchar code tab []={ 0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6} ; //共阴void delay1 (uint Z){uint x,y;for(x=Z;x>0;x--)for(y=110;y>0;y--);}void write0(unsigned char a){unsigned char i;st0=0;for (i=0;i<8;i++){if (a&0x01)ds0=1;elseds0=0;sh0=1;sh0=0;a>>=1;}st0=1;}void write1(unsigned char a){unsigned char i;st1=0;for (i=0;i<8;i++){if (a&0x01)ds1=1;elseds1=0;sh1=1;sh1=0;a>>=1;}st1=1;}void write2(unsigned char a) {unsigned char i;st2=0;for (i=0;i<8;i++){if (a&0x01)ds2=1;elseds2=0;sh2=1;sh2=0;a>>=1;}st2=1;}void init (){scl=1;dat=1;a=0;p30=1;p31=1;p32=1;p35=1;p36=1;bb=0;temp=0;TMOD=0x02;TH0=0x00;TL0=0x00;EA=1;ET0=1;TR0=1;IT0=1;EX0=1;}void start24(){dat=1;delay;scl=1;delay;delay;delay;delay;delay;dat=0;delay;}void stop24(){dat=0;delay;delay;scl=1;delay;delay;dat=1;delay;delay;delay;delay;delay; }void respons24(){uchar i;scl=1; delay;while ((dat==1) &&(i<255));scl=0;delay;delay;delay;}void write24(uchar a){uchar i,temp;temp=a;scl=0;delay;delay;for (i=0;i<8;i++){temp=temp<<1;dat=CY;delay;delay;delay;delay; delay;scl=1;delay;delay;delay;delay;scl=0;delay;delay;}dat=1;//释放总线delay;delay;delay;delay;}uchar read24(){uchar i,j,k;scl=0;delay;delay;delay;delay;dat=1;//释放总线delay;delay;delay;for (i=0;i<8;i++){scl=1;delay;delay;delay;delay;j=dat;k=(k<<1)|j;delay;scl=0;delay;delay;delay;delay;}return k;}void writein(uchar address,uchar date) {start24();write24(0xa0);respons24();write24(address);respons24();write24(date);respons24();stop24();}uchar readout(uchar address){start24();write24(0xa0);respons24();write24(address);respons24();start24();write24(0xa1);respons24();temp=read24();return temp;}void main (){init () ;// 初始化temp=readout(0) ;// 读取24c02内数值delay1(20); // 等待读出cc=(temp&0xf0)/16;dd=(temp&0x0f)%16;temp=cc*16+dd;while (1){if(p31==0) //加1{while(p31!=1){flag=0;flag1=1;flag2=0;}}if(flag1==1){temp++;x=temp/100;y=temp%100/10;z=temp%10;write0(tab[z]);write1(tab[y]);write2(tab[x]); flag1=0;}if(p36==0)//加10{while(p36!=1){flag=0;flag1=0;flag2=1;}}if(flag2==1){temp=f*10;x=temp/100;y=temp%100/10;z=temp%10;write0(tab[z]);write1(tab[y]);write2(tab[x]);flag2=0;f++;}if (p30==0) //启动{while (p30!=1);flag=1;}if (flag==1){write0(tab[j]); delay1 (20);write1(tab[10-j]); delay1 (30);write2(tab[j]); delay1 (30);j++;if (j==9)j=0;}if(p35==0) //存储用户设置的随机数产生范围到24c02{while(p35!=1){flag=0;flag1=0;flag2=0;flag3=1;}}if(flag3==1){xx=temp;writein(0,((xx/16)<<4|(xx%16)));delay1(2000);flag3=0;flag=1;}}}void timer0() interrupt 1{TH0=0;TL0=0;aa++;if (aa==temp)aa=0;}void int0() interrupt 0{flag=0;d=aa/100;c=aa%100/10;b=aa%10;write0(tab[b]);write1(tab[c]);write2(tab[d]); }。
单片机随机数
![单片机随机数](https://img.taocdn.com/s3/m/fad0490ab52acfc789ebc927.png)
首先头文件写上:#include "stdlib.h"然后在后边就可调用rand()这个函数了.给你再具体说下吧,这里边还有些细节问题.实际上,随机函数有两个,srand和rand.要实现你说的功能得配合使用.函数一:int rand(void);从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。
函数二:void srand(unsigned seed);参数seed是rand()的种子,用来初始化rand()的起始值。
rand()在每次被调用的时候,它会查看:1)如果用户在此之前调用过srand(seed),给seed指定了一个值,那么它会自动调用srand(seed)一次来初始化它的起始值。
2)如果用户在此之前没有调用过srand(seed),它会自动调用srand(1)一次。
总结一下,也就是说:1)如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed 一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。
2)否则,如果给seed指定的是一个定值,那么每次程序运行时rand()产生的值都会一样,虽然这个值会是[seed, RAND_MAX(0x7fff))之间的一个随机取得所以,对于你来说,要想让每次的随机值不同,必需先调用srand函数,即:srand(i),而且要保证每次的i不同,这样才能使得种子不同,每次调用rand后才后有不同的返回值.一般来说,要使这个i不同,如果你的系统带时钟功能的话,可以把当前时间赋给i,这样每次的i就不同,如果单片机带AD的话也可以把AD引脚悬浮,读取一下AD转换值,因为最末位的数据很不稳定,也可以作为随机数的种子另外你所说的time.h是不行的,因为这个头文件是针对PC来说,可以读取系统时间,对于单片机一般没有时钟芯片,也无法读取时间.程序:简易程序,部分引脚及函数定义网友自己添加。
生成随机数的方法
![生成随机数的方法](https://img.taocdn.com/s3/m/f245516b3069a45177232f60ddccda38376be10a.png)
生成随机数的方法
生成随机数的方法有很多种,以下是其中几种常见的方法:
1. 使用随机数生成算法:常见的随机数生成算法有线性同余法、梅森旋转算法等。
这些算法可以基于一个种子值生成一个伪随机数序列。
2. 使用随机数生成器函数或类:许多编程语言都提供了内置的随机数生成函数或类,可以使用这些函数或类来生成随机数,通常需要指定生成随机数的范围。
3. 使用时间戳作为种子:可以使用当前时间戳作为随机数生成的种子,然后使用这个种子来生成随机数。
4. 使用外部硬件设备:某些情况下需要更高质量的随机数,可以利用外部硬件设备如热噪声发生器、麦克风或摄像头等生成真随机数。
5. 使用随机数表:事先准备好一张随机数表,需要时从中选取随机数。
不同的方法适用于不同的应用场景,选择适合的方法可以保证生成的随机数具有一定的随机性。
用单片机产生随机数的两种方法
![用单片机产生随机数的两种方法](https://img.taocdn.com/s3/m/0cb87a9729ea81c758f5f61fb7360b4c2e3f2a2e.png)
用单片机产生随机数的两种方法在单片机中产生随机数是非常重要且常见的需求。
随机数在许多应用中起着重要作用,例如密码生成、游戏开发、模拟实验等。
单片机中的随机数通常用于实现伪随机数序列。
下面将介绍两种常见的方法来产生随机数。
一、基于时间的随机数生成在单片机中,可以使用芯片计时器以及芯片内置的实时时钟来产生基于时间的随机数。
具体步骤如下:1.初始化计时器和实时时钟。
2.确定需要生成的随机数的范围。
3.使用计时器或实时时钟的当前值来作为随机数的种子。
4.通过其中一种算法(例如线性同余法)将种子转化为随机数。
5.将产生的随机数存储在指定的变量中。
这种方法的优点是简单易用,而且可以通过调整计时器和实时时钟的初始化设置来增加随机性。
但是缺点是随机数的质量可能不如其他方法,因为在一些情况下,计时器和实时时钟的值是可预测的。
二、基于模拟信号的随机数生成这种方法是通过模拟信号产生随机数。
具体步骤如下:1.选择一个可变的模拟信号(例如光敏电阻传感器、温度传感器等)。
2.初始化模拟信号,使其处于一个初始状态。
3.读取模拟信号的值。
4.使用其中一种算法(例如移位寄存器)对模拟信号的值进行处理,得到随机数。
5.将产生的随机数存储在指定的变量中。
这种方法的优点是产生的随机数质量较高,因为它们是基于真实的物理过程产生的。
然而,与基于时间的方法相比,基于模拟信号的方法更复杂一些,因为需要选择合适的模拟信号和算法。
总结:产生随机数是单片机中常见的需求之一、基于时间的随机数生成方法简单易用,但随机数质量可能不如其他方法。
基于模拟信号的随机数生成方法可以产生质量较高的随机数,但比较复杂。
根据具体需求选择适合的方法来产生随机数是很重要的。
c语言随机函数在单片机中的应用
![c语言随机函数在单片机中的应用](https://img.taocdn.com/s3/m/c19cf22cfd4ffe4733687e21af45b307e971f97a.png)
c语言随机函数在单片机中的应用
c语言随机函数在单片机中的应用
c语言的随机数,可以用stdlib.h文件中的rand函数产生,在调用rand之前,需要用srand()设种子,为了得到真正的随机数,一般我们用time(0)获取当前的时间值给了srand作为种子。
但是在单片机上,要实现这一点,需要带有RTC 实时时钟功能才可以。
对于一般的单片机,我们可以利用定时器做到,让定时器一直跑个不停,需要随机数的时候,取一个定时器的值,赋予给srand当种子,然后再调用rand产生随机数,就可以了。
在实际应用中,我们一般要得到一定范围内的随机数,这时候,就需要利用一个数学技巧了。
例如,要得到[min,max]之间的数据,可以用rand()%(max-min)+min来实现。
真随机数产生方法
![真随机数产生方法](https://img.taocdn.com/s3/m/a468289076c66137ef06193f.png)
ATmega1 28单片机的真随机数发生矗时间:2009-12-16 15:39:00 来源:单片机与嵌入式系统作者:刘晓旭,曹林,董秀成西华大学ATmega1 28单片机的真随机数发生矗时间:2009-12-16 15:39:00 来源:单片机与嵌入式系统作者:刘晓旭,曹林,董秀成西华大学引言随机数已广泛地应用于仿真、抽样、数值分析、计算机程序设计、决策、美学和娱乐之中。
常见的随机数发生器有两种:使用数学算法的伪随机数发生器和以物理随机量作为发生源的真随机数发生器。
要获取真正随机的真随机数,常使用硬件随机数发生器的方法来获取。
这些真随机数都是使基于特定的真随机数发生源(如热噪声、电流噪声等),每次获取的真随机数都是不可测的,具有很好的随机性。
真随机数因其随机性强,在数据加密、信息辅助、智能决策和初始化向量方面有着广泛应用,构建一种基于硬件真随机数发生源,具有广泛的应用价值。
但目前硬件真随机数发生源均较复杂,而且很少有基于单片机的真随机数发生器。
本文利用RC充放电的低稳定度,根据AVR单片机的特点设计了一种性价比极高的真随机数发生器。
该随机数发生器使用元件很少,稳定性高,对一些价格敏感的特殊场合,如金融、通信、娱乐设备等有较大的应用意义。
1 基本原理和方法1.1 基本原理串联的RC充放电电路由于受到漏电流、电阻热噪声、电阻过剩噪声、电容极化噪声等诸多不确定性因素的影响,其充放电稳定度一般只能达到10-3。
利用这种RC充放电的低稳定度特性实现廉价的真随机数发生源。
Atmel公司AVR单片机ATmega 128以其速度快、功能强、性价比高等优点广泛应用于各种嵌入式计算场合。
利用AVR单片机引脚配置灵活多样的特点,使用Amnega128两个I /O口作为真随机数的电气接口。
其原理如图1所示。
主要原理是利用串联RC电路的不确定性产生真随机数源,收集数据,通过AVR单片机ATmega128和主时钟电路量化RC电路的充放电时问,获得不确定的2位二进制数据,再利用程序将每4次采集的数据综合,最后产生1个8位的真随机数。
单片机技术与应用11_CC2530随机数生成器应用
![单片机技术与应用11_CC2530随机数生成器应用](https://img.taocdn.com/s3/m/0c46b21eaf1ffc4ffe47acf1.png)
2、相关寄存器
ADCCON1寄存器中与随机数生成器有关的位
位
名称
复位
3:2 RCTRL[1:0] 00
R/W R/W
描述
控制16位随机数生成器,当写入01时,随机数生成器不展开 运行一次,并在运行完成时自动将此值复位成00。 00:正常运行(13X展开)。 01:运行一次(不展开)。 10:保留。 11:停止,关闭随机数生成器。
本章简介
1、随机数介绍 2、相关寄存器 3、开发实验 4、拓展题
1、随机数介绍
随机数是什么? 随机数就是在一定范围内随机产生的数,并且得到的 这一范围内的每个数的机会一样
随机数的运用? 随机抽样,随机密码,随机调查等等
伪随机数是什么? “伪随机数”:计算机中的随机数是按照一定算法模拟产生的, 其结果是确定的,是可见的,所以用计算机随机函数所产生的 “随机数”并不随机,是伪随机数。
CRC计算结果的低8位。
7:0 RNDL该寄
存器的原有值复制到RNDH寄存器,然后才将次寄存
器的值更新成新的数值。
RNDH寄存器
位 位名称 复位值 操作
描述
7:0 RNDH[7:0]
0xFF
R/W
种子值/随机数高8位数据,在进行CRC16运算时为输 入数据的寄存器,并输出CRC计算结果的高8位。 注意:在向该寄存器写入数据时,会触发CRC校验计 算功能。
4、拓展题
题1:
5、读取高位随机数RNDH 6、读取低位随机数RNDL
如:ADCCON1 |= 0x04 如:while(ADCCON1 & 0x04)
如:rn = RNDH 如:rn = (rn<<8)|RNDL
2、相关寄存器
利用单片机取得随机数
![利用单片机取得随机数](https://img.taocdn.com/s3/m/3556dfe1b8f67c1cfad6b8c2.png)
河北工业大学计算机硬件技术基础(MCS-51单片机原理及应用)课程设计报告学院土木班级交通工程C021班设计人田立全学号 026885一、设计题目:利用单片机取得随机数二、问题的提出:利用单片机的中断和定时器/计数器相结合产生一个6位的二进制随机数(即产生一个0-63之间的一个随机数)。
每当按下按钮之后,在LED显示器上显示这个二进制的随机数。
三、总体设计:1.所设计题目的功能:可以利用定时器/计数器进行自动重装载的计数,当触发中断的时候读出定时器/计数器的计数值作为产生的随机数。
整个程序分为两个部分,主程序部分负责定时器/计数器的初始化、中断系统初始化和LED显示三部分功能。
外部中断处理部分的程序负责取定时器/计数器中的随机数,然后取该数的低六位,然后将这个数转化为六个字节的二进制数(例如:将25h转变为:01h,00h,01h,00h,00h,01h)。
然后利用LED显示器显示这6个字节的数据。
2.总体方案设计:(1)断源的选择因为定时器/计数器只是在外部中断被触发的时候负责提供数据,所以虽然我们用到了定时器/计数器,但是它并不是一个中断源,即本系统的中断源只有一个外部中断。
(2)二进制转换的实现进制转换可以利用除二取余法。
四、 硬件系统设计 硬件电路:五、软件系统设计 1. 程序清单ORG 0000HAJMP MAIN;INT0 ENTERENCEORG 0003H AJMP INTER0ORG 0200HMAIN: MOV SP, #6FH;SET TIMMERMOV TMOD, #20HMOV TH1, #00HMOV TL1, #00HSETB TR1;ENABLE INTERRUPTSETB EX0SETB PX0SETB IT0SETB EAAJMP DSPLY;DISPLAY AND W AIT FOR INTERRUPTORG 0300HDSPL Y: MOV A, #03HMOV DPTR, #0FF20HMOVX @DPTR, ADSPL Y1: MOV R3, #01HMOV R0, #30H ;RESULT ENTRANCEMOV A, R3LD0: MOV DPTR, #0FF21HMOVX @DPTR, AMOV A, @R0MOV DPTR, #DTABMOVC A, @A+DPTRMOV DPTR, #0FF22HMOVX @DPTR, AACALL DELAYINC R0MOV A, R3JB ACC.5, LD1RL AMOV R3, AAJMP LD0LD1: SJMP DSPLY;DELAY FOR 1MSDELAY: MOV R7,#02HDL1: MOV R6,#0FFHDL2: DJNZ R6, DL2DJNZ R7, DL1RETORG 0400HINTER0: MOV A, TL1 ;READ COUNTERANL A, #00111111B;REQUIRE LAST 6 BITS AND 00111111BMOV R1, #30H;RESULT MEM ADDRESS STARTMOV R0, #06H ;LOOP FOR 6 TIMES ;CLEAR MEMMOV 0030H,#00HMOV 0031H,#00HMOV 0032H,#00HMOV 0033H,#00HMOV 0034H,#00HMOV 0035H,#00H;DIV LOOPLOOPED1: MOV B, #02HDIV ABMOV @R1, BINC R1DJNZ R0, LOOPED1RETIDTAB: DB 0C0H, 0F9HEND2.流程图。
C51产生随机数
![C51产生随机数](https://img.taocdn.com/s3/m/71a8154bc850ad02de80410f.png)
方法一:用定时计数器产生.方法二:#include<reg52.h>#include<stdlib.h>#define uchar unsigned char#define uint unsigned intvoid main(){uchar temp0;srand(5); //写入随意值初始化随机函数temp0=rand();//将产生的随机值赋给temp0//temp0=rand();}/question/89996065.htmlC中,rand()是什么意思,有什么作用悬赏分:0 - 解决时间:2009-3-24 12:03提问者:梅mei爱- 试用期一级最佳答案rand和srand的用法首先我们要对rand&srand有个总体的看法:srand初始化随机种子,rand产生随机数,下面将详细说明。
rand(产生随机数)表头文件: #include<stdlib.h>定义函数:int rand(void)函数说明:因为rand的内部实现是用线性同余法做的,他不是真的随机数,只不过是因为其周期特别长,所以有一定的范围里可看成是随机的,rand()会返回一随机数值,范围在0至RAND_MAX 间。
在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。
rand ()产生的是假随机数字,每次执行时是相同的。
若要不同,以不同的值来初始化它.初始化的函数就是srand()。
返回值:返回0至RAND_MAX之间的随机整数值,RAND_MAX的范围最少是在32767之间(int),即双字节(16位数)。
若用unsigned int 双字节是65535,四字节是4294967295的整数范围。
0~RAND_MAX每个数字被选中的机率是相同的。
范例:/* 产生介于1 到10 间的随机数值,此范例未设随机数种子,完整的随机数产生请参考srand()*/#include<stdlib.h>main(){int i,j;for(i=0;i<10;i++){j=1+(int)(10.0*rand()/(RAND_MAX+1.0));printf("%d ",j);}}执行:9 4 8 8 10 2 4 8 3 69 4 8 8 10 2 4 8 3 6 //再次执行仍然产生相同的随机数srand(设置随机数种子)表头文件:#include<stdlib.h>定义函数:void srand (unsigned int seed);函数说明:srand()用来设置rand()产生随机数时的随机数种子。
用单片机产生随机数的两种方法
![用单片机产生随机数的两种方法](https://img.taocdn.com/s3/m/92faad09f78a6529647d5301.png)
方法一:定时器直接随机取值每按一次按键生成一个随机数,这个随机数实际是把定时器的值给取出来了,并不能算绝对的随机、方法二才是真正意义上的随机。
仿真如下:#include<reg51.h>sbit k1=P1^0;void delay(unsigned int i){unsigned int j,k;for(j=0;j<i;j++)for(k=0;k<120;k++);}unsigned int sum1,sum2;unsigned charled[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0X40}; void init() interrupt 1{TH0=0X00;TL0=0X00;}void display(){P2=led[sum1%10];P3=0xfe;delay(2);P3=0xff;P2=led[sum1/10%10];P3=0xfd;delay(2);P3=0xff;P2=led[sum2%10];P3=0xfb;delay(2);P3=0xff;P2=led[sum2/10%10];P3=0xf7;delay(2);P3=0xff;}void main(){TMOD=0X01;TH0=0X00;TL0=0X00;EA=1;ET0=1;TR0=1;while(1){if(k1==0){while(k1==0);sum1=TL0;sum2=TH0;} display();}}方法二:用定时器加rand()随机函数来实现单片机上电之后通过按键去启动取随机数,若是单片机上电就立即取随机数的话,那每次上电随机的结果都是一样的。
然后是0到9不重复的随机数,程序中用了循环来判断是否和前面取的随机数相同,相同则进入下次取随机数,不同则存入数组。
程序如下:#include<reg52.h>#include<stdlib.h> //包含rand()随机函数的头文件unsigned char t,k,i,j,a,f,n[10];//t是计时变量,k是按键标志,i是数组下标,f是随机数重复标志,n[10]是存放随机数的数组void init() //初始化函数{t=0;i=0;f=0;k=0;TMOD=0x02; //设置定时器0为工作方式2TH0=7; //装初值TL0=7;EA=1; //开总中断ET0=1; //开定时器0中断TR0=1; //启动定时0EX0=1; //开外部中断0,同按键的效果一样IT0=1; //下降沿触发}void main(){init();while(1){while(k) //外部中断0触发循环{if(!i) //i=0时取第一个随机数放入数组n[0] {srand(t); //随机数初始化a=(char)(rand()%10); //取随机数(0~9) n[0]=a; //存入数组i++; //数组下标加1}elsewhile(i<10) //存放剩下的9个随机数{srand(t); //随机数初始化a=(char)(rand()%10); //取随机数for(j=0;j<i;j++) //与前面的随机数比较{if(n[j]==a) //与前面的随机数相同f=1; //标志置1}if(f) //有重复执行{f=0; //标志清0continue; //结束本次循环}n[i]=a; //不同则存入数组中i++; //数组下标加1}}}}void inter0() interrupt 0 //外部中断0{k=1; //按键标志置1,主函数执行取随机数}void time0() interrupt 1 //定时器0中断{t++; //时间加1if(t==100) t=0;}。
在C51下的随机数生成
![在C51下的随机数生成](https://img.taocdn.com/s3/m/9dce8c63caaedd3383c4d34c.png)
预定义10位长度的字符数组单片机为8位应该不会超过这个范围了intபைடு நூலகம்es0pos0length0
在 C51 下的随机数生成 #i nclude <stdio.h> #i nclude <stdlib.h> #i nclude <conio.h> #define A 3 int AdvancedLinearCongrutial(int x, int a, int b, int c, in t m, int max);
res = res + (mynums[pos] - 48) * m; pos = pos + 1; } // 定义随机种子 // srand(res); int x = rand(), a = 2, b = 3, c = 5, m = 65536; // 改进的线性同余算法 int i = AdvancedLinearCongrutial(x, a, b, c, 65536, rand()% 100); printf("i = %d", i); printf("\ printf("\tres = %d", res); return i; } // 改进的线性同余算法 AdvancedLinearCongrutial(int int AdvancedLinea rCongrutial(int x, int a, int b, int c, in t m, int max) { for(int i=0; i<max; i++) { a = A; for(int j=0; j<i; j++) { a *= A; } (ax = (a*x + (a-1)*c/b)%m; } return x; }
单片机C语言如何产生随机数
![单片机C语言如何产生随机数](https://img.taocdn.com/s3/m/7f2104622e60ddccda38376baf1ffc4ffe47e2e3.png)
单片机C语言如何产生随机数在单片机C语言编程中,产生随机数有多种方法。
下面将介绍其中两种常见的方法。
方法一:使用时间种子```c#include <stdio.h>int mai//使用当前时间作为种子//生成随机数int random_number = rand(;printf("随机数:%d\n", random_number);return 0;```该方法的缺点是种子的变化速度比较慢,因此可能在短时间内多次运行得到同样的随机数。
方法二:使用ADC模块ADC(模拟数字转换器)模块可以将模拟信号转换为数字信号,因此可以利用ADC模块来获取随机噪声,并将其作为随机数。
使用该方法需要连接一个外部噪声源(例如一个电阻),将其连接到MCU的ADC通道上,并配置ADC通道以读取模拟信号。
```c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <stdint.h>#include <linux/ioctl.h>#include <linux/types.h>#define DEVICE_FILE "/dev/myadc"static uint16_t read_adint fd;uint16_t value;fd = open(DEVICE_FILE, O_RDWR , O_NONBLOCK); if (fd < 0)perror("open");exit(1);}read(fd, &value, sizeof(value));close(fd);return value;int maiuint16_t random_value = read_adc(;printf("随机数:%d\n", random_value);return 0;```以上代码通过打开ADC设备文件(/dev/myadc)读取来自ADC的模拟信号,并将其转换为数字形式。
单片机正态分布算法
![单片机正态分布算法](https://img.taocdn.com/s3/m/22f4bc2a53d380eb6294dd88d0d233d4b14e3f86.png)
单片机正态分布算法
在单片机中实现正态分布算法需要用到随机数生成器和数学函数库。
下面是一种基本的实现思路:
1. 初始化随机数种子,可以使用单片机内部的定时器或外部硬件设备生成随机数种子。
2. 使用随机数生成器生成两个0到1之间的随机数u1和u2。
3. 将这两个随机数通过逆正态分布函数(Inverse Gaussian Distribution Function)转换为符合标准正态分布的变量z1和z2。
逆正态分布函数可以通过查找表或数学函数库来实现。
4. 使用极坐标转换法将z1和z2转换为两个独立的标准正态分布的随机变量x 和y。
具体过程为:r = sqrt(-2 * ln(u1)),θ= 2 * pi * u2,x = r * cos(θ),y = r * sin(θ)。
5. 根据需要的均值μ和标准差σ,对x和y进行线性变换得到符合正态分布的随机数。
具体公式为:result = μ+ σ* x。
需要注意的是,在单片机中生成的随机数并不是真正的随机数,而是伪随机数,其生成的序列具有一定的周期性和重复性。
因此在使用正态分布算法时,需要根
据具体的应用场景和精度要求进行适当的调整和优化。
8位单片机产生伪随机数的算法(6502版)
![8位单片机产生伪随机数的算法(6502版)](https://img.taocdn.com/s3/m/a5fd60116c175f0e7cd13775.png)
8位单片机产生伪随机数的算法8位单片机很多地方需要随机数,比如游戏的洗牌,可在timer中取数,但是随机数质量不高。
随机数是一个既简单又复杂的问题,这里的例子使用了众所周知的线性叠加法,没有完美的方法产生随机数,不过线性叠加法是一个合适的方法,彻底解决8位机随机数的问题。
伪随机数函数总是返回可预知的数字,像抛骰子,如果抛足够多次,那么我们得到了一个足够长的数字序列,3,1,5,1,4,6,5,4,6,5,4,5,6,1,3,2,1,6,4,6,5,4,3,2,1,3,2,1,4,2,3,1,3......如果从序列中一个接一个的取出数字,那么数字就看似随机。
问题的关键是从这序列的哪个点(数字)开始取数?这个开始的点(数字)叫做种子。
注意,如果从相同的点(种子)开始,将会得到相同的数字,这是因为我们是从固定的序列中取数字(所以叫伪随机)。
但这却是一个有用的特性,我们可以每次从不同的点取数,即改变种子!在6502上,8位或16位随机数是最常用的,函数返回一个32位的数字,范围0~2^32。
名词"线性叠加"听起来容易范晕, 其实只涉及二个内容:乘法和加法。
三个步骤:1. 为了取得新的种子(也就是从序列开始的那个点的数字),旧的种子和一个常数A相乘,2. 所得结果然后和第二个常数c相加。
3. 新的种子是结果的低32位(记住,这个函数返回32位数字)。
保留低32位很重要,用来获得下一个种子。
计算公式:种子 = A * 种子 + C此公式在几何图中表示一条直线,而且新种子由旧种子反复相加得来,所以叫线性叠加。
随机数函数的关键在于选择优秀的"常数A"(也叫乘数A),其实也就是选择了一个固定的数字序列。
"常数c",不像乘数A那样重要,但是它一定是个奇数。
事实上, c可选1,而且这是例程所使用的,因为它会简化计算。
注意,奇数(旧的种子)乘奇数(乘数A)是奇数,再加奇数(常数c)将会是一个偶数;偶数(旧的种子)乘奇数(乘数A),加奇数(常数c)将会是一个奇数。
8位单片机产生伪随机数的算法(6502版)
![8位单片机产生伪随机数的算法(6502版)](https://img.taocdn.com/s3/m/a5fd60116c175f0e7cd13775.png)
8位单片机产生伪随机数的算法8位单片机很多地方需要随机数,比如游戏的洗牌,可在timer中取数,但是随机数质量不高。
随机数是一个既简单又复杂的问题,这里的例子使用了众所周知的线性叠加法,没有完美的方法产生随机数,不过线性叠加法是一个合适的方法,彻底解决8位机随机数的问题。
伪随机数函数总是返回可预知的数字,像抛骰子,如果抛足够多次,那么我们得到了一个足够长的数字序列,3,1,5,1,4,6,5,4,6,5,4,5,6,1,3,2,1,6,4,6,5,4,3,2,1,3,2,1,4,2,3,1,3......如果从序列中一个接一个的取出数字,那么数字就看似随机。
问题的关键是从这序列的哪个点(数字)开始取数?这个开始的点(数字)叫做种子。
注意,如果从相同的点(种子)开始,将会得到相同的数字,这是因为我们是从固定的序列中取数字(所以叫伪随机)。
但这却是一个有用的特性,我们可以每次从不同的点取数,即改变种子!在6502上,8位或16位随机数是最常用的,函数返回一个32位的数字,范围0~2^32。
名词"线性叠加"听起来容易范晕, 其实只涉及二个内容:乘法和加法。
三个步骤:1. 为了取得新的种子(也就是从序列开始的那个点的数字),旧的种子和一个常数A相乘,2. 所得结果然后和第二个常数c相加。
3. 新的种子是结果的低32位(记住,这个函数返回32位数字)。
保留低32位很重要,用来获得下一个种子。
计算公式:种子 = A * 种子 + C此公式在几何图中表示一条直线,而且新种子由旧种子反复相加得来,所以叫线性叠加。
随机数函数的关键在于选择优秀的"常数A"(也叫乘数A),其实也就是选择了一个固定的数字序列。
"常数c",不像乘数A那样重要,但是它一定是个奇数。
事实上, c可选1,而且这是例程所使用的,因为它会简化计算。
注意,奇数(旧的种子)乘奇数(乘数A)是奇数,再加奇数(常数c)将会是一个偶数;偶数(旧的种子)乘奇数(乘数A),加奇数(常数c)将会是一个奇数。
STM32的ADC产生随机数
![STM32的ADC产生随机数](https://img.taocdn.com/s3/m/7e3e417c02768e9951e73847.png)
因为在做一样东西需要产生随机数,在网上找到一种方法,就是利用ADC悬空引脚产生随机数,所以做了尝试,把尝试的结果分享一下,总的来说,随机效果还算可以。
函数如下:
首先初始化ADC1,然后读取通道4即PA4引脚上的电压值,转换成16位的数字值后取低4位,再赋给8位变量led_mode_value。
将这个led_mode_value变量通过串口送至电脑观察,效果如下:
看来随机效果还算可以,23次取值,取到了8个不同值,这样的随机程度可以接受。
随机数产生过程改进版:
函数如下:
初始化ADC1之后,先取一个低4位的值,然后再取一个12位随机值加到第一个随机4位值上,得到一个和,然后再取出这个和的低4位作为最终的范围在[0,15]中的随机数。
通过串口送到电脑,效果如下:
23次的取值统计,统计到了14个随机值,随机效果提升。
PS:
STM32的ADC引脚对应的IO。
使用 MSP430 内部时钟生成随机数字
![使用 MSP430 内部时钟生成随机数字](https://img.taocdn.com/s3/m/4ea51be269dc5022aaea00b4.png)
使用MSP430 内部时钟生成随机数字
,但是,MSP430 时钟系统还是允许设计人员结合使用反馈法。
在要求进行FIPS 140-2 测试的情况下,这些方法可提高算法性能。
第一个反馈机制是,在每个采样位后使DCO 略微加速。
时钟控制寄存器在每个位后加上数字5。
这种相加或额外变化导致在每个环路时DCO 的速度均高于VLO。
虽然可以使用任何数字,但数字 5 可以产生足够大的阶跃变化,以至于DCO 与VLO 之间发生很大的差异。
另外,每次转换LSB 时,两个以前采样的随机位被按位加至时钟控制寄存器的除法器位。
这些位在到达计时器之前将控制用于VLO 的除法器,同时还改变了计时器测定的VLO 与DCO 之间的关系。
最后,每个得出的位实际上是 5 个环路“多数原则”的结果。
如前所述,每个环路都从CCR 生成其自身的LSB,但 5 的“多数原则”用于选择最终位。
通过这种方式,MSP430 MCU 能够以极低的功耗生成随机位的连续流。
这种位流可以用于创建随机数字;如果不需要对运行的应用时钟架构进行修改,将针对伪随机数字生成器(PRNG) 生成初始种子。
借助该技术,就可以生成通过FIPS 140-2 随机性测试的位流。
这就是说,该技术可广泛用于需要生成随机数字的各种应用领域。
特别是随着无线技术的推广,这种随机数字生成技术将有很好的前景。
另外,由于该技术采用目前的MSP430 MCU 架构内部信号,具有成本低与安全性高等优势。
tips:感谢大家的阅读,本文由我司收集整编。
仅供参阅!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机产生随机数的方法
随机数在单片机的应用中也是很多的,当然产生随机数的方法有很多,当中有一个就是利用单片机定时器,取出未知的定时器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不重复的随机数,程序中用了循环来判断是否和前面取的随机数相同,相同则进入,下次取随机数,不同则存入数组。
本文是资深工程师分享的单片机C语言如何产生随机数的方法,欢迎广大工程师评论留言讨论,一起分享知识、成长和进步。