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

STM32F072使用ADC产生伪随机数

[复制链接]
lkl0305 发布时间:2015-1-25 23:08
本帖最后由 lkl0305 于 2015-1-25 23:17 编辑 ( E$ j8 T! q0 O) U: V! s( o* G
9 c' u6 B5 I; v+ P
srand和rand()配合使用产生伪随机数序列。7 }" O( j: J0 B) }" s8 V
rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
# S0 N3 A( k7 d& H: v, x4 H如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
6 k$ \" V7 |/ @: E! x, ]/ G' Esrand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,从而实现真正意义上的“随机”。! O) x" `  h# j: t" t$ c
通常可以利用系统时间来改变系统的种子值,即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列。! ~7 l4 [: n! {0 M+ H
当然,STM32 F2和F4系列中有硬件实现的真随机数发生器。- g' T9 a2 G3 l. S8 b
我这里使用STM32F072的ADC产生随机数。读取某个悬空引脚的ADC值作为种子来获得随机数。也算是一种方法,我看其他人也用过,拿来共同学习下。
; ~+ z. I( _# A9 V+ i/ a上个程序:ADC_Random.c
3 }! q& C) I7 y2 W' Z6 U
  1. <p>#include "adc_random.h"% e; S1 B' U9 D# C& o$ w0 S
  2. ( V1 \& ~" _7 I3 M5 t; U
  3. uint16_t Get_ADC_RandomSeek(void);</p><p>5 k+ A1 Y' h, t) _( y* a' Z2 ?) L
  4. /*初始化ADC*/
    * F4 l2 E/ `7 I+ I+ S% o4 x: ^
  5. void ADC_RandomConfig(void)
    $ Z$ ?8 s( a3 u
  6. {  f# y# [4 Q4 D$ K
  7. ADC_InitTypeDef ADC_InitStructure;
    8 z! l2 G8 ~5 l- l# c) F* @
  8. GPIO_InitTypeDef GPIO_InitStructure;) q5 v2 \! l) m; l, O- s* M* {

  9. 1 y4 e6 w0 V; W) n+ U
  10. RCC_AHBPeriphClockCmd(ADC_RANDOM_GPIO_CLK, ENABLE);
    1 u% T3 t7 Y* G. ?
  11. RCC_APB2PeriphClockCmd(ADC_RANDOM_CLK, ENABLE);
    , @$ K' x: _( p9 w4 V& Y9 C

  12. % o1 ]5 [% P2 z# _; V* ^
  13. GPIO_InitStructure.GPIO_Pin = ADC_RANDOM_PIN;
    8 b2 S- z& }$ {+ @( D' E0 p7 @
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;' ^5 [% A- V; F1 K! o+ V; s
  15. GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;+ Q  b; s! U$ M! D; H9 U
  16. GPIO_Init(ADC_RANDOM_GPIO_PORT, &GPIO_InitStructure);$ y, e$ _" v$ h' o

  17. , S) i  [& r3 @
  18. ADC_DeInit(ADC_RANDOM);! T& `8 q4 x) P9 L
  19. ADC_StructInit(&ADC_InitStructure);- A7 y7 i# @) h6 Q$ i" c3 V
  20. 2 W8 _0 V/ W  ?1 X
  21. ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    1 F: b1 w# o" |) ]" v9 ~6 r% o
  22. ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    % v% S: W5 ?9 h! O
  23. ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ! r: V' V8 c6 Y# ^( C* N7 E
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ' V! K- D# R& t
  25. ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    5 G; L- D4 N. T+ D3 D2 X
  26. ADC_Init(ADC_RANDOM, &ADC_InitStructure); ) ^- ?# R/ L8 @/ g5 V& i
  27. ADC_ChannelConfig(ADC_RANDOM, ADC_RANDOM_CHANNEL , ADC_SampleTime_1_5Cycles);
    % v- K/ V. U; m( t
  28. ADC_GetCalibrationFactor(ADC_RANDOM);3 m8 W3 N( h  ^% L  {; G
  29. ADC_Cmd(ADC_RANDOM, ENABLE); 9 u) ~, D4 g' K' W. [) B% o
  30. while(!ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_ADRDY)); / V, w& x% ?9 o  t- [; `. Y" l
  31. }
    3 V7 c4 J8 G/ M! e, d( @6 X

  32. " F4 H1 P" F, p/ N. b5 n8 z! g
  33. /采集4次ADC的值,每次取采集的第四位,拼成16位作为种子*/
    " E) L9 g% l7 g4 B. y
  34. uint16_t Get_ADC_RandomSeek(void)
    * l: j5 W( ?# Q( Q" }
  35. {
    * l0 N3 p5 ~0 Y8 k6 D- R8 @
  36. uint8_t Count;
    / S: }" X0 v( q
  37. uint16_t ADC_RandomSeek = 0;' h) |& `+ W1 l1 L) D$ \$ |' o
  38. ADC_StartOfConversion(ADC_RANDOM);
    , n* t8 o% Y% {* T5 [
  39. for(Count = 0; Count < 4; Count++){- D( Q; r! Q; s/ e% Z* {" H  C# S9 O
  40. while(ADC_GetFlagStatus(ADC_RANDOM, ADC_FLAG_EOC) == RESET){
    # `+ l$ ]4 w- @4 j6 Q( U3 A
  41. ;
    7 M$ G7 k/ s0 ^& t! z
  42. }
    8 H4 q3 K, E$ [+ s; a
  43. ADC_RandomSeek <<= 4;! U, f+ H, _% \
  44. ADC_RandomSeek += ADC_GetConversionValue(ADC_RANDOM) & 0x000f;
    * F1 I8 Y# J# _& D4 a* |6 M( R, r
  45. }% }7 k+ u! E1 ^" i! G7 y8 B9 V6 v  q
  46. ADC_StopOfConversion(ADC_RANDOM);$ }3 _# S$ s/ U6 z% [+ R
  47. return ADC_RandomSeek;
    2 _0 n+ O1 l) U& P* q
  48. }+ n% D% d) L# f' l( e5 B

  49. # [& r, z; t( l! F4 a
  50. /*拿种子产生随机数*/
    , C* m8 O( N" [7 {
  51. uint16_t Get_ADC_Random(void)/ N/ Q9 S% @) |5 k4 U0 V
  52. {# T* O8 X/ r7 }7 k
  53. srand(Get_ADC_RandomSeek());# `' H$ @2 v3 F2 V! ^
  54. return rand();
    4 t( [% F6 e. W& F7 B9 }! f
  55. }
    0 S5 g0 s2 L) m( X% B
  56. </p>
复制代码

$ M7 m9 l  p, p/ @0 v& j
接下来再主函数中需要的地方调用就可以了:% ?7 K& L4 b7 W
  1. int main(void)
    8 E7 C8 P+ A% ]4 ]) Y" }5 {7 \
  2. {
    6 F1 [$ `2 K3 S. n% d
  3.   uint16_t RandomNumber, RandomSeek;* S5 a3 C5 c2 n3 p* r7 t) a
  4. % x6 ^) `2 O3 p1 I4 o) M6 H$ ?
  5.   USART2_GPIO_Init();
    " e) X+ a. U' s" [7 w! M, n; f/ f
  6.         
    $ o3 n2 t+ c  N2 C0 @( U
  7.   ADC_RandomConfig();
    9 D1 `( ]4 X6 v6 @: F
  8.   : o: s: F9 F. E( k
  9.   while (1)3 c( v" }1 `6 a) {
  10.   {, d  K! _+ j) _
  11.     RandomSeek = Get_ADC_Random();2 p4 a  c* F2 ]: Q% x* l4 ~1 ~
  12.     srand(RandomSeek);0 c% t8 j  v8 v: e8 l  S1 n
  13.     RandomNumber = rand();! A' l. n7 _7 l" V8 R
  14.     printf("RandomSeek = %d\t\tRandomNumber = %d\n", RandomSeek, RandomNumber);
    : Z( E" w9 ~+ C! B! E2 n+ d  n
  15.     delay_ms(500);
    2 P- Y6 N# s& S: {
  16.   }
    ' m1 Q3 H# r# \6 }
  17. }
    ) O# f  {/ F7 |+ S9 y
复制代码
完整的程序:, W0 ^- @; ~, e! a6 J3 ~

% w6 X* l. B4 L% ^) ~  z# P/ _0 { 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的输入怎么接?* ~0 X0 L' e+ ~+ ?/ s/ u9 ?7 p
或者说故意把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& D2 d  m( ?# l
这个随机数还没用到过,不过ADC的波动也是在一定范围内的吧,恐怕不够随机呀,不知道最终效果怎么样? ...
6 U& ?! ^- ^$ l0 n
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计一下看看。
星辰一方 回答时间:2015-1-27 08:28:15
lkl0305 发表于 2015-1-26 23:148 [2 P! @7 |) O2 F/ L3 O1 u& C
表面上看没有什么问题,随机范围很大,我大致看了些数据,最小几十,最大快到FFFF(65535)。有时间统计 ...

. N$ r7 l" O- a嗯那还可以,可以尝试从多个通道采集,随机选择
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+ _9 J, A# J( |' g
借用了 借用了
, Z& a/ P1 P; y
尽管拿去
zhangdaijin 回答时间:2015-12-25 07:05:39
淇少爷 回答时间:2016-7-22 09:54:28
感谢分享
绚丽多彩 回答时间:2017-11-9 18:34:53
谢谢分享,我想用这个产生个序列号,作为ID来用,不知道唯一性怎么样?$ K' ]# ]# p* j! \# X0 Z0 I6 n! ]
) ?- C( X+ L+ V* [
12下一页

所属标签

相似技术帖

官网相关资源

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