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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑
' ~  y# Q! V# b0 {! g6 k
% k& i/ A' v- C5 d) Ssrand和rand()配合使用产生伪随机数序列。& H! {# a! |- |  m0 ^0 h: U2 S2 l
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。) s7 Z: r) B6 i4 f4 h6 u- t
如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
$ N, x9 y+ q  k# V' Jsrand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。
$ t, M+ K9 p5 d+ F  a通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。0 b! c1 I! f: |# \, r
当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。3 r4 a( w, e6 Q8 L2 ?( N
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。1 N8 V7 v: S) R6 d+ N( ^* @
上个程序:ADC_Random.c: w/ F! t  x  i3 r' b' Q# R
  1. <p>#include "adc_random.h"
    5 j) d1 v; p2 r" f2 h

  2. 7 |. _! U& J6 b* B" V
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>
    ' R% M6 `6 q% C! K! G/ s4 y% C
  4. /*初始化ADC*/
    / R/ p8 }% z. g- Z/ M6 A1 k9 e/ `
  5. void ADC_RandomConfig(void)
    # b& \% y1 g! |+ S- S! [- f: p5 Q
  6. {8 W  c' E1 W  s8 u( h) F! e
  7. ADC_InitTypeDef ADC_InitStructure;0 ]) f+ ~( r( _4 |0 t/ z
  8. GPIO_InitTypeDef GPIO_InitStructure;
    0 I- I( C/ n' x, r

  9. ( D, P9 O2 V# F* H+ R- k: Q
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);
    ! s* Z: H0 S+ n$ z
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);
    1 X% b' ?5 \" H" ^9 c
  12. " c* o4 l) D1 G$ {
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;
    / V: E( J# O8 w% k, R
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;4 X5 ]- Z4 U( V" `, ?9 c
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;7 J( a' R% h7 }1 d: e
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);
    ; a7 G! {* |" {7 v6 W3 k
  17. 9 j' ]$ |$ F' l$ C% L
  18. ADC_DeInit(ADC_RANDOM);5 i+ [+ W/ c$ S- }+ g3 `7 D3 H: y& O
  19. ADC_StructInit(&ADC_InitStructure);/ ^, g2 S2 g% b6 @/ }$ L

  20. 8 n. [) W# {& a, b7 v3 w( p) w
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;# _0 F( {; F8 E5 r& _' h2 a
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ( d" v" V( V' r
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    1 i& _; t( d* u( l
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    * E7 x7 x) ]. ]8 H4 Q& Y
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    9 E2 ?9 H$ o& p" }8 ]
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure);
    * K( e9 [% S* E( W
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
    + x' T: z% U  I& P; U; `
  28. ADC_GetCalibrationFactor(ADC_RANDOM);
    " }& W* @( r4 i9 z, k. m# [
  29. ADC_Cmd(ADC_RANDOM, ENABLE);   t6 F4 T- O' J  _- q% h0 P2 C
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY)); . j1 @$ N4 a8 l  R: ^
  31. }
    # a. R" A2 Z4 F# `# a5 o3 f  d
  32. ; J* l' P! Z/ S! y
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/
    1 u5 Y( p7 E& L4 T) j- H
  34. uint16_t Get_ADC_RandomSeek(void)" {# k, R6 Y+ c
  35. {6 _- @/ c- k' P% ^; k0 v' F
  36. uint8_t Count;
    " i3 f3 u  f4 i) j* C9 ~: g5 j
  37. uint16_t ADC_RandomSeek = 0;" A8 u: ~) |- V) g! }& n
  38. ADC_StartOfConversion(ADC_RANDOM);
    0 v. q- o$ v, {: i
  39. for(Count = 0; Count < 4; Count++){1 g! W5 S% s3 Q( Y2 V7 S1 |0 _
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){' L; K7 k8 D5 c
  41. ;
    4 B9 U0 I- [2 F. X  S0 B* t
  42. }3 ~1 C! ?! D! G* s  M1 I0 P( e
  43. ADC_RandomSeek <<= 4;
    ; f0 b+ }+ y" |
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;
    2 ?7 j7 p6 J% I0 ^
  45. }
    & ~! k- l0 J3 p1 r" f8 J" R
  46. ADC_StopOfConversion(ADC_RANDOM);
      X. Y, O9 w3 t: k4 E  {
  47. return ADC_RandomSeek;5 O( ?5 p7 m4 K2 X) M9 \- k
  48. }3 j+ \; [; v- I, u# q/ A6 x
  49. 4 w& E- M# [4 w+ q# v
  50. /*拿种子产生随机数*/3 q* Y2 n$ E( o
  51. uint16_t Get_ADC_Random(void)
    + [4 X" ^; [& b/ i- a* O7 {
  52. {
    : _9 z5 ]  D' k+ U4 }) ^
  53. srand(Get_ADC_RandomSeek());
    ; H9 X) A3 p0 L9 k; _% a( L
  54. return rand();
    / s% r$ d# B3 e  ?4 B
  55. }4 S9 S, Y' ?1 \0 S, C
  56. </p>
复制代码
1 H( J9 ]1 ?! J7 L8 I
接下来再主函数中需要的地方调用就可以了:
0 ?  h/ Z8 b  I3 ~3 @$ a
  1. int main(void)+ P7 c4 R. A) ^' n9 t
  2. {" o- m6 G5 A. p) ~: M# x& Q: |4 t
  3.   uint16_t RandomNumber, RandomSeek;3 G% \  }2 b1 t% s
  4. : \& y3 i# l- z. r0 ]9 L' \& [
  5.   USART2_GPIO_Init();# G3 W) ^$ H6 s+ Z+ h
  6.         # S' e# {  X7 [* [0 F
  7.   ADC_RandomConfig();( e1 G' x: R! H  X! m: p
  8.   9 X) \* W+ {- w8 t3 }- \% ~
  9.   while (1)6 `6 x& Z" m- m  @6 R% k
  10.   {) F8 x% M$ z% P# ]8 A9 \- ]: k/ _1 c1 N
  11.     RandomSeek = Get_ADC_Random();8 X" M7 a  R0 M" Y' q6 v
  12.     srand(RandomSeek);
    8 H; P& j5 @8 u0 x. U
  13.     RandomNumber = rand();, @$ x, v& K4 h$ j6 E+ w$ h
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);; V  }6 l/ B3 x- t. s- P
  15.     delay_ms(500);, o' W8 B5 N; v4 q, t
  16.   }/ ]  L6 A: N* w" ]3 ]
  17. }
    % B; X9 E' {" Q& V* G3 r$ Z
复制代码
完整的程序:
1 X2 x( u2 k  |
7 q  x+ `, i7 y 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的输入怎么接?
2 k/ M3 C8 f" o) o7 m' T或者说故意把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
) s2 C0 U. x; c2 P+ e/ k! D这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...
1 {; y/ h2 F- Q* G# c
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:147 Z' V0 G& V% t4 m: y+ `
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...

- C3 F' {- @) @2 k3 q7 E, Q; q嗯那还可以,可以尝试从多个通道采集,随机选择
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
0 l( q$ L* \0 C! D! d6 A$ B0 b借用了 借用了
8 M. b/ z  N3 x# L- Z
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?9 U) O6 X# F5 r- z& M4 N

' V# |4 F- N; q9 M) Q8 w
12下一页

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版