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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑
% L5 @0 ?! E' _, X" n, c) R+ u- H' F! W& k/ Z% I/ e
srand和rand()配合使用产生伪随机数序列。( t' I" y0 M8 y! l; i( X; D
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。  O& d3 r3 [* d, v! [
如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。. J' U- t: c8 i9 g' R5 w% P8 p
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。
+ @4 e1 e. @& _通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。3 m; G3 `1 s4 j
当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。* _' _; f& z9 p" H" F4 ~9 b- s
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。" [- l$ p' r! P: w: D* S# Q
上个程序:ADC_Random.c8 c" V5 M: W2 u6 M7 c
  1. <p>#include "adc_random.h"2 v- E1 Z7 v, j" H$ y7 R

  2. ' j" C5 x4 Q* ^) T# C9 ~
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>% B  S1 m% V' `1 i9 q. z- X
  4. /*初始化ADC*/8 }1 x9 z# u2 @$ w6 B: |. `
  5. void ADC_RandomConfig(void)
    ' K1 `: Q% M/ S- v8 Z. T; {7 ~+ N
  6. {" z: e/ @) t1 q& }# ?- `
  7. ADC_InitTypeDef ADC_InitStructure;
    / h% a& ^' I# N* `( d
  8. GPIO_InitTypeDef GPIO_InitStructure;
    + q  l* w2 ~$ {- K& Q% O

  9. 7 X- ?5 `) t% d$ A) _! d
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);
    $ N& ~. M* S# F& T4 i3 K
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);0 {$ L  o( i" s. ?; V

  12.   p( L" p+ |2 Q' ^1 L" z
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;
    # U$ j2 s  x( R( O0 z
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;! r7 P3 x- I4 D4 w  M6 `/ Q
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;) s2 R5 _- ]1 |5 u
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);- O6 T! a1 @$ J, F) V, `

  17. 7 u) O0 |1 A: @- }6 q. j! O$ j
  18. ADC_DeInit(ADC_RANDOM);
    : R% K* r4 s7 c% w& r
  19. ADC_StructInit(&ADC_InitStructure);* Y2 _2 I) A5 z0 ], l

  20. % R% b9 I3 `) x; ]: L" S
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    " o! n( V, f" k! c' v; M8 ^
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    * g- P" K  Y/ |* j$ I
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;+ q- B5 r% v" k
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ]( I+ q6 M1 A: Z& R5 ?6 |
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    4 A" [" ?  u; [4 z8 O
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure); * j. ?6 M! S/ a9 M0 u  i( |
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
    % t; V# k* Z3 t( i9 F
  28. ADC_GetCalibrationFactor(ADC_RANDOM);! C1 }) v4 q! V8 a" P0 F& n' L
  29. ADC_Cmd(ADC_RANDOM, ENABLE);
    # z6 \8 M% V$ a7 {
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY)); 3 {6 l/ R1 K4 Y0 k
  31. }
    & u( E0 l& m6 T0 y4 p7 C/ G4 u6 c
  32. % d: G6 [3 H) }" q7 I, K
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/: W# u$ Z% @5 ?" X
  34. uint16_t Get_ADC_RandomSeek(void)
    " L' H8 {$ [9 r; t; H
  35. {- y3 y1 d( J' I+ y1 J; M
  36. uint8_t Count;
    ( ?0 t6 \" ^% S
  37. uint16_t ADC_RandomSeek = 0;! H1 w7 z2 `2 Q" ]
  38. ADC_StartOfConversion(ADC_RANDOM);
    - X7 G' w, Z0 F! E; Q. A
  39. for(Count = 0; Count < 4; Count++){6 W( A1 k" x) |0 E+ j5 [& W1 P3 H3 |
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){0 v" u$ _# [  c$ l% E& b/ G* A3 o
  41. ;
    " J8 C9 {! Q! d5 b: V  y( `5 ?
  42. }
    / z: f+ C3 Z5 x! g4 {
  43. ADC_RandomSeek <<= 4;1 F$ \6 j4 I6 z1 U# K0 L
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;1 U2 I! j3 O3 j' }) B7 p" `" u: \
  45. }
    3 X1 S' y; T8 G% x
  46. ADC_StopOfConversion(ADC_RANDOM);
    . u! [1 k* D! x# N
  47. return ADC_RandomSeek;8 I) w! \* R2 c  y
  48. }
    3 C8 }2 T5 \9 k! P! |4 E& [

  49. 8 ]4 \. o3 M/ p) z) n& A, |
  50. /*拿种子产生随机数*/) [& n8 J" b/ N. h
  51. uint16_t Get_ADC_Random(void)( t1 z! v8 [4 ~9 O) M1 W
  52. {2 Q$ D5 R8 z8 w: ^0 T" @' X
  53. srand(Get_ADC_RandomSeek());
    + g4 r) T( z1 w. l% z
  54. return rand();
    + B0 ]; v7 G6 M
  55. }
    ; r9 a- K; D+ |4 h2 N8 {# m
  56. </p>
复制代码

+ g5 @+ \. G, b
接下来再主函数中需要的地方调用就可以了:
# k5 x8 j* u2 K0 R
  1. int main(void)+ O5 ]3 V1 B! }2 M7 S
  2. {2 \& \/ K8 |9 s; H! J+ v+ K
  3.   uint16_t RandomNumber, RandomSeek;9 M  F: ]# r9 ?% X4 g3 w" [% S

  4. ' G0 {- I/ b1 T* {2 u1 z1 q
  5.   USART2_GPIO_Init();) \5 p  ~/ O4 p- v4 v5 y
  6.         ) d* i( d, m$ i3 U
  7.   ADC_RandomConfig();
    ) B$ u' x% j9 M* q
  8.   1 ?. l' F) W0 J7 {1 a7 c0 \( R/ S
  9.   while (1)
    9 A) `* l! U6 r; n- i% w
  10.   {
    * O, I; h" `4 D! F( a8 ]* F2 @
  11.     RandomSeek = Get_ADC_Random();. k0 x. [0 c  p1 y' N4 _
  12.     srand(RandomSeek);
    & D4 o1 ]5 }! z! e* e
  13.     RandomNumber = rand();
    6 I. R5 s: ^% l/ r( p2 g" g- v  q
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);
    $ M+ x  O9 D/ v+ [1 ]0 Y
  15.     delay_ms(500);
    4 Q( V9 F4 x$ C$ ?& m' N# p
  16.   }; d: J" k4 p& Q5 x3 P
  17. }3 o5 J, ?1 ?, }1 y
复制代码
完整的程序:
( Z/ o6 ^- h( g- N1 f+ A6 W3 E, O% ]- a. {: j
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 V% ^$ l3 |/ n- Z; w) r或者说故意把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
: F6 s  }# f, V* h5 `6 A( Z2 v这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...
. D8 Q: x2 a4 s9 [  J
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:14& s! t+ |8 U. g5 j# J( G
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...

5 R* ^  F& S% X& }  q* R7 j! v嗯那还可以,可以尝试从多个通道采集,随机选择
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
7 K2 i0 \7 }9 [6 v借用了 借用了
! Y# v6 t! C6 r# \1 \
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?
) O8 O- R; d2 {9 B" C5 D/ P$ G2 K6 m3 ^* m/ x5 Q( u
12下一页

所属标签

相似分享

官网相关资源

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