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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑 ( W* \0 B4 _) k2 Q/ @! v

- a+ J8 P- u* C1 G3 k% E5 n/ [srand和rand()配合使用产生伪随机数序列。
  C6 K& E/ H* g; V9 hrand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
4 q* ^( l$ a3 ]* Q5 y如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
8 {0 ]1 u1 Y/ s8 dsrand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。0 ^1 [$ b0 J% R3 v  g- M
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。- V) z- Z+ U+ E! k; W" U3 `
当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。. g2 W" O' D% g: K: J8 q: e
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。' j7 J% u4 T6 x6 Q  g
上个程序:ADC_Random.c
! H5 j$ t, s# E/ `8 Z
  1. <p>#include "adc_random.h"
    ' U* N9 @) ]* a) X# T

  2. ! ^7 J# o* e0 P' |
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>
    ) G7 j& \# A3 T: e' l" p
  4. /*初始化ADC*/& o- z0 @6 T6 c( F
  5. void ADC_RandomConfig(void)
    * J1 n+ A* O; m& q
  6. {/ [  ?: R9 y" S" @
  7. ADC_InitTypeDef ADC_InitStructure;
    " R8 P% r4 f% E& `
  8. GPIO_InitTypeDef GPIO_InitStructure;5 L* R9 D) u' ]9 e

  9. : Q" M6 ~3 ?/ e/ B/ N# M3 B, B" L
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);. I) W9 p+ X0 \$ E5 U; M
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);
      N/ ?1 e- I3 [  _4 V7 {
  12. 3 R, n( n1 X! ~4 R, j
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;" W+ }2 k& _; O
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;: d0 n+ x$ y6 f+ A3 n$ e  f
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    * X: w% i. M' M2 {3 x2 i
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);* `- N& e0 @! {; ?+ @, L' Q4 G

  17. ! x9 ]6 v  P! t2 E# h/ Y+ B
  18. ADC_DeInit(ADC_RANDOM);" o4 \* u& v& F! @
  19. ADC_StructInit(&ADC_InitStructure);
    8 Y1 p, r- x# ?+ _8 R1 r& g% }

  20. ( k% |7 r/ D/ P* q5 _
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;0 \3 Y2 S, ^+ W$ O; L$ f* m
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 9 X1 s4 O9 t5 ?0 x( q
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;0 h9 W, s+ p/ X' @, o0 ?
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    7 t4 p3 ?1 S8 n3 E8 i5 N5 A
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    0 u- J+ |% u* e& N, i5 F( [
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure);
    ( e) U5 ~) x3 j% b" c$ w" T
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);% D  z( ^2 z5 Q/ C: p, b
  28. ADC_GetCalibrationFactor(ADC_RANDOM);
    ; |" a0 D  {8 g) y6 o# |; f
  29. ADC_Cmd(ADC_RANDOM, ENABLE); & j5 e7 W6 G! J. _) N% E2 S- H
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY));
    1 G4 B% }3 W# o4 {6 A
  31. }
    8 u( @; t) Z# Y: T5 a5 c

  32. 5 D: e' H  S, c6 o! H7 x
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/
    1 u% Q/ G: s9 J8 I) k
  34. uint16_t Get_ADC_RandomSeek(void)/ L. [; n3 Q4 Y& y1 J7 z
  35. {
    2 i- m3 @) C- z- f" p# d
  36. uint8_t Count;/ |2 S" O  |( T; o) j
  37. uint16_t ADC_RandomSeek = 0;
    ) t: N! @) \: L- e
  38. ADC_StartOfConversion(ADC_RANDOM);
    6 \: Q  d" h' c3 c6 {3 N
  39. for(Count = 0; Count < 4; Count++){
    , F7 |7 s! D9 i& g% [% j  \
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){' s& d( ?& S2 r6 n
  41. ;% E/ t- J5 i8 r4 ~- b
  42. }  {0 v% }  U2 [
  43. ADC_RandomSeek <<= 4;
    / W- U6 p' x- E2 U
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;! m8 u' m7 m9 U4 w! {
  45. }+ S& t, G4 V' k9 o& z' k5 @+ j
  46. ADC_StopOfConversion(ADC_RANDOM);4 U& `! N, [4 a: m) e1 m* [3 `
  47. return ADC_RandomSeek;
    3 E' y9 e1 z  ~5 a& T- b
  48. }
    # e; W' L  ], Y7 h& P/ E3 A
  49. : r* R0 E0 z! X2 ?' f5 [8 x
  50. /*拿种子产生随机数*/
    " u. ^6 H2 S& G8 ?$ L2 q
  51. uint16_t Get_ADC_Random(void)
    ; ]7 U$ y" e" Y: d* A% d( [9 e
  52. {
    . U1 {* U. v( p; T1 r( V
  53. srand(Get_ADC_RandomSeek());; G; O$ V  D1 ]4 a
  54. return rand();; ^# ^2 a7 Z3 y1 N2 h) w- u/ T$ A
  55. }
    5 a) B1 v) M+ U" P# u" v" Y
  56. </p>
复制代码
% {4 u- _& {3 g* q& ~
接下来再主函数中需要的地方调用就可以了:
4 G0 R! O% Q" A. ^
  1. int main(void)
    9 N4 Y/ ?0 s1 V4 ^. n- Y
  2. {
    # e5 {  N7 B) e6 Y% B/ e
  3.   uint16_t RandomNumber, RandomSeek;2 c& [- n% \; ^5 Z9 \! e8 [
  4. ( \7 t9 O3 G7 j
  5.   USART2_GPIO_Init();
    2 J, y4 T7 p" ?
  6.         $ T) R( C1 S5 M4 w- g
  7.   ADC_RandomConfig();
    8 ]/ ~6 r) O! n/ y; j; N
  8.   ' O. a% D: ]# S
  9.   while (1)
    6 n7 {" m0 B$ j" m5 Z
  10.   {
    6 ], w5 E- a7 p8 k7 z* H6 z
  11.     RandomSeek = Get_ADC_Random();
    8 z" a% H, _" ~9 j% M4 i: B$ Q
  12.     srand(RandomSeek);
    ; t/ A  K/ b( p6 G& r. d
  13.     RandomNumber = rand();
    0 k4 g* x6 z; T9 c1 M* r2 |5 ]5 ]
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);  q! {# m# G4 _1 p1 ?
  15.     delay_ms(500);% L$ U5 B: d$ M1 _/ v
  16.   }
    6 y) a( w; K' M9 i- @: Q; @/ e- S2 A' j
  17. }
    / r: c. {( d) Y, @+ r3 Z3 L
复制代码
完整的程序:- n* ~, T; W% s$ Y2 t* Y

3 X8 }; b4 I; \3 ?) n' [$ ?* s3 { 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的输入怎么接?* I8 _9 N1 X3 h2 V( s3 ?7 H$ }
或者说故意把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
2 V  e+ `! N9 A4 j/ @这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...

$ E& h, V6 K3 h8 A7 N表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:14% l2 {8 k( z7 k5 s, t: \
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...

8 A) F1 A  G. J2 d. f9 d/ }嗯那还可以,可以尝试从多个通道采集,随机选择
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. c* ~5 @5 W( X1 I# v7 _, k
借用了 借用了
+ p! j1 Z" c& j. F, i4 k" P
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?
2 X* F6 M, D- d* z7 U) P! A9 w( _0 Z
12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版