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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑 ) J4 L% `% [% F( e
* m$ U/ F; k. n- Y4 k* O
srand和rand()配合使用产生伪随机数序列。
# X0 \4 |6 c! q9 f8 T; Arand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
/ d* a- Z) \! r  I/ h% l如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。) s9 h) |0 h3 [' N$ o
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。3 B4 {7 I$ D" ^( F" L' A
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。
; a' y, V; t4 ]+ a3 n6 Y当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。
0 n* s' }* |! r! i2 J1 X1 d我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。# ?: O; R0 p- n2 B1 q5 \* _
上个程序:ADC_Random.c9 c# ^  R. h8 L! j3 L8 u
  1. <p>#include "adc_random.h"0 ~& `" @) C& ?; \/ T- V, g/ D

  2. 0 y# k4 G( {, ?7 K
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>
    , J  M. C/ _! E. N7 x, z9 U
  4. /*初始化ADC*/2 V( Q* \7 Z: j( l5 ~
  5. void ADC_RandomConfig(void)
    - r& I9 e- y8 |* Q, U8 A( z5 P
  6. {
      I" ]+ x! J4 f0 ^6 d
  7. ADC_InitTypeDef ADC_InitStructure;
    * b* Y7 r% s) T; E  b, k$ W7 ]/ X- ^
  8. GPIO_InitTypeDef GPIO_InitStructure;( c- D6 I% s. g9 o) H, i
  9. + c8 F2 e9 Y- O4 C9 B& i
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);; `# j2 t) m3 o( V; Y
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);/ K' I$ Q1 A2 b5 l

  12. / j) N# w/ K+ S3 l% {. z
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;! \) W( ~+ w8 _) \2 g# e
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;. K; a) @9 g* _8 S' E; ?7 j
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    ; Z. e* `6 y8 ?9 }# m
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);
    / h: F1 T4 V8 I( x+ c
  17. : Y1 S2 m8 H2 {
  18. ADC_DeInit(ADC_RANDOM);$ V; Z1 n; z: e+ V  w* G& @: N3 i
  19. ADC_StructInit(&ADC_InitStructure);( S6 _2 L0 s) R- p) A2 N4 h
  20. ! ^" T% h+ M) Y$ g. `
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    : K5 t6 v0 l/ m3 b* p
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 8 s1 J* i3 z& {' D8 P) M* O
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;8 s0 ^8 B; }. p# ?* Q% i; n
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    4 l# T$ G+ G4 x5 l
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;( z/ u3 e( q1 ^
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure); ( h4 b" P! \. S& s
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
    8 J$ c' G: r/ Z. ^4 i/ S
  28. ADC_GetCalibrationFactor(ADC_RANDOM);
    9 _# M7 t$ Q* c2 M  k4 f
  29. ADC_Cmd(ADC_RANDOM, ENABLE);
    $ u2 l: e) R) a& r- h% x
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY)); # F$ l  I& l  Q# I- Q4 d
  31. }& R1 e# t, E4 w0 @/ e! H

  32. " ~1 _* s+ ^4 r4 N  @
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/# U/ P1 x! |7 o& _* a8 z- E
  34. uint16_t Get_ADC_RandomSeek(void)
    ' N: N0 d$ e7 ^8 ?& G6 e
  35. {
    " y1 H6 G* r) U  n' p8 ]$ ^
  36. uint8_t Count;
    * b. ^6 \$ }5 K6 T7 c! d
  37. uint16_t ADC_RandomSeek = 0;$ i0 S# c' T$ [
  38. ADC_StartOfConversion(ADC_RANDOM);3 F9 m9 S7 s* V3 Y2 T8 Q5 f" B7 |
  39. for(Count = 0; Count < 4; Count++){  `6 F' Y& R8 T- i! l$ @
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){
    / I8 R% y& |2 Z. c, i* L
  41. ;
    9 `- \6 Y7 g, J% v
  42. }
    + ^* ~# t8 o; h2 [+ `
  43. ADC_RandomSeek <<= 4;
    1 y+ B4 G7 C9 H) F) X1 ^8 q. f
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;/ n9 a( k7 x) C% j( x6 u
  45. }
    - n8 R; u  ]# W' A8 t9 V1 h
  46. ADC_StopOfConversion(ADC_RANDOM);
    - H+ @5 [$ E& P) M9 G4 l
  47. return ADC_RandomSeek;: i: s6 N% X! d' i
  48. }$ X  w' I+ [3 z

  49. " o" V' y5 E4 a4 g3 W0 x
  50. /*拿种子产生随机数*/
    2 _( V' C& Y# m
  51. uint16_t Get_ADC_Random(void)+ O2 Z( S9 U0 c
  52. {
    1 c' o- y8 q1 `6 ~# @) {6 h
  53. srand(Get_ADC_RandomSeek());
    6 O5 H7 w7 R* F% l" Z
  54. return rand();
    1 `+ r" e& k! K& {  Z  V
  55. }
    0 ~" C- O: n. U8 H) M8 V" F
  56. </p>
复制代码

! g/ }% b! d+ f/ Q: n
接下来再主函数中需要的地方调用就可以了:
/ X0 V$ ]% j1 A
  1. int main(void)
    5 @0 }; p5 o& P# o4 f6 y" J( ^6 R
  2. {/ l  C, ?: C: q
  3.   uint16_t RandomNumber, RandomSeek;4 A- _$ U' O$ E5 e4 l  N
  4. . B  S7 n! T) h" W
  5.   USART2_GPIO_Init();
    0 Z+ g9 m: {0 Y+ X, q+ C
  6.         , i# r, [3 B& F. ]; q
  7.   ADC_RandomConfig();3 @; W- Z: Y. i3 A$ t, W
  8.   
    & i' ?+ j! D& ]1 Q0 t
  9.   while (1)
    # Q% ]% h1 C" l% J3 T; G$ x( r
  10.   {/ H! M( ~7 m. j4 `
  11.     RandomSeek = Get_ADC_Random();6 D. P9 o0 R) T" H
  12.     srand(RandomSeek);9 ~' k8 j) s, G  `
  13.     RandomNumber = rand();. `5 R2 y: j* ?& P+ i
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);, r" M2 R# t- u; Q( i# _2 E
  15.     delay_ms(500);. u7 d* k. O! Y) t0 I# v1 F
  16.   }
    ; X! P! j* G* [: f7 h
  17. }
    . ?3 P; c5 n2 W2 x: \9 Q& n
复制代码
完整的程序:9 t& i  X$ Y3 t; A

* f3 |4 b1 T. A2 \2 {- B2 I3 R 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的输入怎么接?; r" k* q8 N- a) T8 Y
或者说故意把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
7 d4 s( r( I: p& D, Q  H4 ~( `这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...
& S" b5 [5 }4 c8 j' S# k1 i
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:14
* u& _! P" ~$ x0 [8 M) ~4 s表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...
  u$ y8 r6 R6 q7 C
嗯那还可以,可以尝试从多个通道采集,随机选择
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:27* s5 O7 {4 U' \% D  Q0 d
借用了 借用了

8 v5 [0 v( o  X& m2 `( q尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?: U) o; ]1 W- v, b% V% |7 s+ @: X
3 C8 ?' p# ]1 ~2 Q4 a
12下一页

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版