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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑 ; b, j; G  i# O0 M* J6 N/ e

! V9 J0 I+ K: r" p' |srand和rand()配合使用产生伪随机数序列。
" d* J" x0 h; P# vrand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
. n2 w4 {7 J: ?5 N( x6 v2 z5 }如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。7 d2 W( q  v  V+ q
srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。5 }- [& U; u. A+ B# r+ k
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。1 V' ?& Z: w! ?1 _! D3 F
当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。! M  x6 Q$ r  o% O' T2 R
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。
; P# L' ]; a1 t上个程序:ADC_Random.c
# x3 t0 |  B+ F4 L/ D" @; {/ x
  1. <p>#include "adc_random.h"  ~( X+ J9 P3 F3 y( C1 A

  2. ) e/ }9 Z8 p! a* R: k4 c
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>
    & ]' ~# P, i# q7 i8 C5 G' G2 j
  4. /*初始化ADC*/
    6 t7 G  Y& ]! x8 ]# E% d- a: n) J( c
  5. void ADC_RandomConfig(void)
    $ G. S9 @1 i+ L2 x
  6. {
    0 L: _5 C2 [1 w' [! W
  7. ADC_InitTypeDef ADC_InitStructure;' f, Q' ]8 v6 \& i6 `( R! R- j
  8. GPIO_InitTypeDef GPIO_InitStructure;! c0 \1 t( `8 S/ O  h
  9. : w1 O* U' x5 z# t
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);
    ) i( v5 l! ]3 ^$ ?  S5 z5 S
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);& N1 B( P1 e" I, ^5 ^- o
  12. ' `# ]* N0 w6 r: ~! S# b8 g
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;
    - S! {/ {( v3 d4 Q7 X! n
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    ( Y% B! E' E; ]8 z/ I
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;2 h) H+ F. x( Q  _9 K
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);/ S" E8 V8 H" P  T
  17. ) s9 r1 r( n; e% Y; e! `+ U* z3 ]
  18. ADC_DeInit(ADC_RANDOM);" M6 u% j4 c: z* m( g- R! s) r
  19. ADC_StructInit(&ADC_InitStructure);0 e9 k6 r" T' N- B6 p1 q

  20. : ]) L. E6 u! G' h  R  W
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ! D7 Z8 H  F- W- J6 G: J- u
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ( ?; q2 z" q! n
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;8 }% }7 F/ e# b: E6 V# f/ _" a3 f, \
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;$ f! ~* H9 O# e0 u7 S, t4 K
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;5 I, {! B" Z3 ~$ W' `* ^/ }
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure);
    6 V& k" L$ ?4 Y1 W1 h7 W' a
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);& O+ G' }4 j( i) l
  28. ADC_GetCalibrationFactor(ADC_RANDOM);
    + L3 \$ O' D" V3 ]0 @4 A4 M* A
  29. ADC_Cmd(ADC_RANDOM, ENABLE);
    5 {) I% r" R/ L& G+ b9 D5 D% Y
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY));
    , H; ?7 r1 {- j' H' a8 d. y7 X
  31. }
    ' o# [5 u& G( k% i' T6 L3 X! U& i
  32. & D) x* ]/ w: d" i
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/% ^* u; Z& f! [5 V; a; A) U5 ^- L
  34. uint16_t Get_ADC_RandomSeek(void)
    0 i8 z5 d# ^" O3 G. a8 l9 F
  35. {
    & x) P! X- l. E: S9 F- t
  36. uint8_t Count;
    " n4 y, I$ Y5 K% g, m/ g* b) L
  37. uint16_t ADC_RandomSeek = 0;
    * `( ^3 r+ K8 O8 n" W$ F( N
  38. ADC_StartOfConversion(ADC_RANDOM);
    ) W8 S& S. x4 Y/ c* Z
  39. for(Count = 0; Count < 4; Count++){4 [5 ^1 J/ {- Y( _' }1 A
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){' W. y2 x6 J' k6 C0 s
  41. ;0 k/ F" N5 Y  t: R! K& n
  42. }
    : w+ A5 ?2 K% x' C
  43. ADC_RandomSeek <<= 4;
    0 ^0 q% y" x/ ]
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;1 ^+ ?" ^& P4 e
  45. }) ~. |2 _9 A! p3 i! Z
  46. ADC_StopOfConversion(ADC_RANDOM);. ?6 p& T# K% s" g0 b8 }2 `; q, m0 V
  47. return ADC_RandomSeek;
    " F) i3 \# R) a
  48. }
    : `! L* |, p* e3 n( B: X

  49. ( E, ?1 B) ~7 w) o
  50. /*拿种子产生随机数*/
    5 A/ b; a: N! N: L: v3 B9 w
  51. uint16_t Get_ADC_Random(void)( e# G# \3 X7 N/ x
  52. {
    ( r, u1 B9 D  ~( j$ {
  53. srand(Get_ADC_RandomSeek());0 G2 v0 P- [( f0 w% F9 y' e) {
  54. return rand();8 K8 f- E' ]- A) y3 i3 V
  55. }
    # @$ a" i$ k/ y0 S* X% {
  56. </p>
复制代码

5 }; m! ^+ [2 A( q+ s! |& Q) |
接下来再主函数中需要的地方调用就可以了:
/ ~. e; n. r9 e( r* k4 @( A- R
  1. int main(void)
      t, p" g6 Y0 l6 o" _7 |
  2. {8 |: i$ G! ?! K) I% [
  3.   uint16_t RandomNumber, RandomSeek;
    1 `7 I' n0 W2 g: B. t  l
  4. ' X* W+ a: Q4 P/ Q2 d
  5.   USART2_GPIO_Init();, f9 @# @5 j2 L2 H4 y% L
  6.         , @( K# e( g+ B% F! z  L9 u$ v
  7.   ADC_RandomConfig();8 f3 w' Q8 c; _* W5 C- [4 Y
  8.   
    & u2 r# O! |8 p8 J2 c1 @
  9.   while (1)% S5 V" @' k* Z+ m5 I
  10.   {( R# f3 ]7 q- h$ T! l$ N
  11.     RandomSeek = Get_ADC_Random();+ o. \/ r% }* `6 L$ V" W
  12.     srand(RandomSeek);; V6 \- ~8 J$ A# t3 G0 C
  13.     RandomNumber = rand();
    : H7 @2 u' g/ Z0 X* k5 }' _4 ?5 {
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);+ E( U$ a' B- L+ b
  15.     delay_ms(500);
      V/ n' G% c8 A( s% c; T# M: g
  16.   }) m. ~6 |7 Z- C% f' D6 r2 ~
  17. }
    1 r2 |3 ~. K5 y
复制代码
完整的程序:2 Y0 M/ E! ~( h8 ~/ w
6 v5 R1 P+ u2 F
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的输入怎么接?- H  s3 @' {5 |
或者说故意把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
; l9 l, m1 Z+ l7 W: \这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...
3 y4 c) B: d9 z
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:14
/ g, p3 U! x$ S8 K2 ^8 t/ J表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...
, \9 X$ Y4 X5 w3 c$ s; I4 M0 W
嗯那还可以,可以尝试从多个通道采集,随机选择
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: \, Y% |2 n  E& p" k4 y4 m0 P
借用了 借用了
) n$ O* N- w5 Y6 }3 d2 |  R
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?& r2 L! C/ C9 t  {5 ]0 u! F
" x. j, v, }3 O2 a. I
12下一页

所属标签

相似分享

官网相关资源

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