你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑 6 R6 m7 x. z3 K' o7 o* [

* \- J8 x1 n1 Osrand和rand()配合使用产生伪随机数序列。# i5 E: t( g& g' ~/ j0 D* [6 r! i
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
% n$ z2 O- d  i8 X  v: t- A如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。8 K" @7 i' X5 Q/ l
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。7 f# M1 i2 C9 c3 ?1 H& }- X
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。
7 y5 M. T) s4 A9 N! i# I% ^当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。1 E& w6 R; C3 S, \
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。7 D& u3 b* a$ _* j" \
上个程序:ADC_Random.c1 r* }+ o/ X& Z$ o# y8 E6 v+ G, Z
  1. <p>#include "adc_random.h"
    9 j. r4 }, n7 x/ ?
  2. 9 r2 f2 E5 X- i  v
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>8 u0 b# U: K+ R
  4. /*初始化ADC*/3 H/ }1 |+ c; T8 P
  5. void ADC_RandomConfig(void)3 C1 Q9 d. g4 `* W3 v0 q  ]
  6. {. c$ O' c# {: C( i, a! b; l
  7. ADC_InitTypeDef ADC_InitStructure;6 m* k! S2 A: l3 s! I
  8. GPIO_InitTypeDef GPIO_InitStructure;
    ! l; F& E, n. L0 W1 {0 F

  9. 7 J$ e% ^3 X+ P: I- L: E# q5 ]) e
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);
    . q: v0 o+ _' j  ]
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);
    - Q/ H* f8 U, V+ r3 T

  12. 8 k( R8 G" F$ b' j  p8 [1 ~
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;( Z; r# Z+ p8 Z: b5 O6 \" _
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    " q+ `% S: [! y! }( ~
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;0 C* q4 _* U: J) l; K
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);
    * l) u& n4 @1 E- R8 M( M
  17. $ R' Z. ^) q6 [; M5 S" a- T! l
  18. ADC_DeInit(ADC_RANDOM);
    8 ^4 V/ _) J$ U1 b- ^4 H, k
  19. ADC_StructInit(&ADC_InitStructure);
    ' Z9 b# Y+ F$ y+ _4 R# c3 w' u. h& N

  20. $ l, |1 d; Q+ ?/ J' v
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;) S- {$ ~8 s* b' O0 m
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ; d1 q. \  x6 Q: R  p. d% u9 i
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;  `* T* K! I4 d0 B+ r7 H; B7 `
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;) W# u) E: {* z% F: F
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;* p' g1 F& P( P( F' ?
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure);
    4 Y  h1 Q- e! d& j
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
    $ t/ N& s  q! ?) @( ]/ r% D7 u
  28. ADC_GetCalibrationFactor(ADC_RANDOM);) w) d0 G7 T- ~, k
  29. ADC_Cmd(ADC_RANDOM, ENABLE); 9 B7 U* E4 \- O+ J) M
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY)); 2 s. A1 z' n$ ?; S* v( i
  31. }3 m5 q- F" i+ q2 ?
  32. + u: _7 ~2 I. C: ]+ D8 z
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/
    4 |$ D5 ~  }* t2 a" Q* a% ?
  34. uint16_t Get_ADC_RandomSeek(void)
    : Z/ \! j7 P" t# I) [8 b9 @. @
  35. {0 f* ?# r& u! O4 @+ f$ {
  36. uint8_t Count;
    5 ]* Z% F, P! {$ M/ O+ H+ m6 G
  37. uint16_t ADC_RandomSeek = 0;
    , Y  Q# T" v( K: d+ m: {5 N
  38. ADC_StartOfConversion(ADC_RANDOM);5 ~  w: n. c( j
  39. for(Count = 0; Count < 4; Count++){
    3 R2 W( z. K% y2 c4 d! Z
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){/ k# _/ Q7 f) K4 e# A; Y1 x, d; o% @
  41. ;2 n/ i2 G( j' M! G
  42. }" }+ |. j& L2 F. ~8 ~& G- J
  43. ADC_RandomSeek <<= 4;+ r% h. ?  N  p
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;6 q% X- [+ w& Q& g- K
  45. }
    ( o: D' I. C$ ^5 W5 n0 ]& L
  46. ADC_StopOfConversion(ADC_RANDOM);
    ; o8 Y) {) y, s- N; Y
  47. return ADC_RandomSeek;/ T4 g1 b& f1 [
  48. }4 a( j- ~: Z+ O) a

  49. & r8 ?1 C; ^3 T" l" h9 b6 K. r
  50. /*拿种子产生随机数*/0 u8 j) o5 s9 \" N. q/ j- ]
  51. uint16_t Get_ADC_Random(void)
    6 |! l; r1 x4 t5 S
  52. {" s& b8 \) y* ?
  53. srand(Get_ADC_RandomSeek());
    " [, l2 b' S5 u4 c
  54. return rand();
    0 i, R" ]3 ^0 c: C1 ^3 X+ L
  55. }0 v# @8 g/ G; x/ C' ]( o4 K% U
  56. </p>
复制代码

# i& f4 m+ x9 X& d
接下来再主函数中需要的地方调用就可以了:' h/ R$ m  D: H; X$ h4 x. b8 Y- d
  1. int main(void), Q0 C2 \6 j; w0 n; Z; N
  2. {
    7 U7 F' g0 T+ t4 I
  3.   uint16_t RandomNumber, RandomSeek;
    ; ?1 F7 l4 q; H. a3 F
  4. 5 L# G8 w- y% {* m' E
  5.   USART2_GPIO_Init();
    ' [' M0 Q9 r7 g! c
  6.         
    7 k; W% T, Q9 \& }. r3 @9 y" f7 M
  7.   ADC_RandomConfig();
    * g9 S, |" F; f$ z2 `( O+ x0 Q1 f6 K% d
  8.   : u" L' i7 }; A- ?, \
  9.   while (1)0 z6 l: p) P( U& L- o& S
  10.   {
    ; b) S  h8 @; J
  11.     RandomSeek = Get_ADC_Random();$ C8 M, S/ o8 T& H
  12.     srand(RandomSeek);
    ( b. {8 O7 }. [* C5 C8 I# F
  13.     RandomNumber = rand();
    3 j2 d: \1 [3 v9 v8 c/ F
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);
      h) z- U" ^5 ^; M4 d) i
  15.     delay_ms(500);& e( |8 p/ F" Q+ Y! a( L  P
  16.   }
    # \+ w- H+ U1 N
  17. }
    , L8 N- ]" K3 I9 X+ k# }
复制代码
完整的程序:% n0 O( A$ k6 N/ q4 |3 z

( W; }! G% Q" O* z" n3 D ADC_Random.rar (4.6 MB, 下载次数: 475)

评分

参与人数 1 ST金币 +2 收起 理由
一叶清风 + 2

查看全部评分

赞 1 收藏 2 评论15 发布时间:2015-1-25 23:08

举报

15个回答
MouseCat 回答时间:2015-1-26 00:30:42
AD的输入怎么接?
7 A6 f4 E' M! e. H1 U$ N* o或者说故意把AD的输入做的不稳定?不然每次相差一到两个字,那产生的随机器是不是也相对固定?
feel-376797 回答时间:2015-1-26 05:08:06
悬空引脚的ADC值
拼命三郎 回答时间:2015-1-26 08:06:24
stm32.jpg
星辰一方 回答时间:2015-1-26 08:38:24
这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样?
埃斯提爱慕 回答时间:2015-1-26 08:55:59
提示: 作者被禁止或删除 内容自动屏蔽
党国特派员 回答时间:2015-1-26 09:58:59
这东西不错,学习了。
lkl0305 回答时间:2015-1-26 23:14:40
星辰一方 发表于 2015-1-26 08:38
5 O% f8 A% s- _) E+ p5 O3 Z这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...
& v" H# j* }- Q8 R# |
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:14- i  F# F5 {* s7 B! L- D
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...

" ]2 u4 a2 _7 ?4 e# `6 e! [嗯那还可以,可以尝试从多个通道采集,随机选择
stary666 回答时间:2015-1-27 11:23:26
1066950103 回答时间:2015-12-24 17:27:11
借用了 借用了
lkl0305 回答时间:2015-12-24 22:15:49
aADu 发表于 2015-12-24 17:270 U6 ]: Z  A0 |* |
借用了 借用了
8 V3 u6 k4 ]3 g
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?
8 P4 A0 l" x4 w8 ^
# b4 c  m1 E1 e
12下一页

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版