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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑
9 R! ?- O) R  ~8 D/ V0 s/ \3 c6 i0 t7 C; X
srand和rand()配合使用产生伪随机数序列。
! V/ X& b, Z+ A: x7 m5 mrand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。$ n! K) [  C4 m/ @' l
如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。1 ^" v! A6 q5 @" f9 @$ P8 a
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。- Y1 {1 D. E. z3 W+ E
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。
& N# |4 d% P! G/ R8 F当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。% g$ K; q( I, E3 l/ a
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。5 P3 V- i& \$ k) `; A: l# ]. `- F
上个程序:ADC_Random.c
, @" M+ s- ]" l. `0 Y6 \
  1. <p>#include "adc_random.h"# M4 {6 F6 d# l" [: t
  2. ! A5 [' C4 }6 m( d6 ?% k0 u3 X
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>1 t" ~! W% X; Y2 v
  4. /*初始化ADC*/- O* V% P) N" ~0 k# w, p9 }" s
  5. void ADC_RandomConfig(void)% I2 N0 F1 k- q$ O0 [
  6. {, V4 t7 ?8 @- |% x) {7 F( k- u) l8 J
  7. ADC_InitTypeDef ADC_InitStructure;
    , |( W" ]" J4 ~) L5 w4 g4 [$ \$ q
  8. GPIO_InitTypeDef GPIO_InitStructure;1 S; p6 G8 S: h0 F% B! r

  9. 6 H) c: {' F' {1 {" S' V
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);7 y2 `2 y. E/ a" ]; i- ~
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);" G6 ]: S8 y. O

  12. & F' J7 o& J7 N
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;
    " d7 I- |! z) x/ u. O9 N
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;" A8 f$ l: o' P/ d- d! d
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
    ( \+ u/ X( m0 ?" f- P
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);
    ' K( ~) M8 i8 w9 S* D( D1 h

  17. * |- g' L& C- j. @7 E
  18. ADC_DeInit(ADC_RANDOM);# O1 |; t) P: a8 h/ J7 @
  19. ADC_StructInit(&ADC_InitStructure);
    & d5 G7 X$ k$ ]6 j: b- W
  20. ( v4 ]5 h0 g5 @2 M: e" e8 b
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ) x* P, f" p1 Q  Y
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    . Q3 l+ x; O% k8 `
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;6 f& l6 v( z% r6 p
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;+ Z) R; g& r0 R. E7 U$ q6 a, g
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;# k& X4 m% Z$ @: @% s- @
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure); 4 R5 x' ~3 J  h! s9 Z& \
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
    5 H9 m) e) Z  B; ~" s0 D: v
  28. ADC_GetCalibrationFactor(ADC_RANDOM);( C4 h* B6 G! @6 ]" W+ v! S/ U
  29. ADC_Cmd(ADC_RANDOM, ENABLE); 8 V: K8 Q- a  v5 z6 f. j$ O
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY)); 4 N$ k8 F: X, `: K3 I. v. T
  31. }. j8 z' I  y! m' e1 d1 c6 S3 ]

  32. 4 [; c) c$ g1 f4 q5 P* G! Q
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/' J# X$ P  H! p2 ^) M: L
  34. uint16_t Get_ADC_RandomSeek(void)! t% k" t/ X5 R4 v1 {# k" x
  35. {# w' h: i  f/ d% x+ _% p
  36. uint8_t Count;' p5 O5 {% N4 ^- `/ }" z- d% c
  37. uint16_t ADC_RandomSeek = 0;
    ! L' a1 }: M1 g4 ^2 ?7 W8 i
  38. ADC_StartOfConversion(ADC_RANDOM);
    / Q+ f& V& R% H8 D/ O1 S
  39. for(Count = 0; Count < 4; Count++){
    ' d' ]& R; t+ x% b, ^% \
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){
    * l9 k  }  v( R) e# H' h6 J& A
  41. ;$ s4 S  [* c) U+ z  n% l
  42. }$ }" V4 a& K/ H
  43. ADC_RandomSeek <<= 4;
    # ~: j3 f1 O* l) \: ^+ \2 k
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;
    ; J4 o( B; U6 V* p& H
  45. }6 P' W, G) |) a7 X
  46. ADC_StopOfConversion(ADC_RANDOM);
    7 ]% N# `% _- g
  47. return ADC_RandomSeek;
    . C4 J8 I/ |! r! o2 x
  48. }) M, R& O8 e/ }+ _9 L- a4 G7 m
  49. % E/ i  P! Y, t
  50. /*拿种子产生随机数*/5 r* g4 `  N( |
  51. uint16_t Get_ADC_Random(void)' A- C( z" k& \! J% P, x
  52. {
    ; d: @% I) n2 [$ x
  53. srand(Get_ADC_RandomSeek());
    1 @/ M) \8 n' i$ J1 z$ M  r# q
  54. return rand();
    * }) t) F3 B- |* J# ?. X
  55. }) Q0 c1 H, z1 [9 [% _+ H$ y/ y1 S
  56. </p>
复制代码

% d3 C" S" ~* ?% o! B# T
接下来再主函数中需要的地方调用就可以了:
0 L3 G, W( }9 D. v$ c; |8 L3 M
  1. int main(void)0 K. k& ]) H! \/ e& [
  2. {4 f3 W, y+ ~% A7 U$ ?" ]: F
  3.   uint16_t RandomNumber, RandomSeek;
    1 M8 t* J& U+ P( o
  4. - s) [, V. t/ S3 d# z3 h9 d
  5.   USART2_GPIO_Init();. U( n6 ^+ Q5 k) v8 d: G
  6.         
    ' S; y1 V# U5 ^4 Y9 V4 \0 u. u
  7.   ADC_RandomConfig();
      c/ Z" u3 _8 k; Z$ t
  8.   
    ' `7 O8 m# S3 z
  9.   while (1)
    5 b7 a# K, {8 j2 G
  10.   {
    $ q8 N" p. t$ O) e
  11.     RandomSeek = Get_ADC_Random();+ d$ a  k% u$ Y( C
  12.     srand(RandomSeek);
    " t, r: H3 U7 x, U& r% ^
  13.     RandomNumber = rand();$ E) j' u  R6 Z; j% ~
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);
    + B& B8 Y# k3 L* e0 I
  15.     delay_ms(500);. p, h# ]) T3 i6 A2 v
  16.   }
      R4 Y8 M) a* @2 R+ Y" r- A
  17. }
    ! m0 D% S9 R, |8 J! k$ ~' M6 o
复制代码
完整的程序:6 c, [) a: D- a* q; ^

* c6 x5 y+ b  ^: m 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的输入怎么接?
; U% J( @$ Z& g# M+ m" C! U' r8 R3 W或者说故意把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
' H% J; `  f' M1 b这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...

+ G* Q4 e7 e. X( m9 ~表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:148 a* |; t4 Y6 d& f% l) `% N/ f+ {
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...
+ o; E' {- y6 z
嗯那还可以,可以尝试从多个通道采集,随机选择
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
& M1 K( b0 r! q8 H2 E借用了 借用了
/ ?+ t. Z7 D5 `) M# [8 u# @6 L& F8 o
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?
0 X/ D1 L/ M$ F/ O  w# \4 U; Z( Q9 Z
12下一页

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版