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

【经验分享】STM32 硬件随机数程序示例

[复制链接]
STMCU小助手 发布时间:2022-3-30 11:00
01. 概述/ W4 F6 n. }$ J8 R* K
STM32F4 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。1 Y: G, @6 U, M% |' Z! ^+ Z

( |! |1 ~% l- a' J相关头文件和源码在stm32f4xx_rng.h/stm32f4xx_rng.c。, d$ ]) u% x6 l' Q

% O' d/ E+ B: m+ A! ]1 v0 Z% E+ a! U: N02. 硬件模块
7 J/ F) g: P" T5 i( Z, d. E- t0 e+ n$ ~用到的硬件资源有:
# \4 b+ j1 {/ L. g9 W! M$ Y* R' I  ?1) 指示灯 DS0) G& b8 j  ]- T3 H& L
2) 串口$ O. u: S7 n2 ]. Q' d; ^
3) KEY0 按键  \% y4 k9 h. j) j
4) 随机数发生器(RNG)
4 P: C/ J" b. `- l2 G) D7 c5) TFTLCD 模块
) W: w# K/ @0 ~
# y' z1 \7 [( v03. 相关函数
4 e, q8 ^& ~4 h' r4 l  F5 l+ w: u5 p( G  |
  1. /* Exported macro ------------------------------------------------------------*/
    : u3 d" A  x8 _1 L6 N+ p2 ?2 p
  2. /* Exported functions --------------------------------------------------------*/ * w  N8 o* R1 C- r6 E

  3. 3 ]' Q  j; f, K( l3 m
  4. /*  Function used to set the RNG configuration to the default reset state *****/
    ) f! O  j, i9 {! ]2 p/ f
  5. void RNG_DeInit(void);6 M, Q' }7 Y( E! A( E" F8 t6 J% v

  6. 9 \2 X) K* x* v) h
  7. /* Configuration function *****************************************************/
    ! [( E. p" j5 h
  8. void RNG_Cmd(FunctionalState NewState);( m3 m4 ?' u( A! E

  9. " |( Q4 \, e2 i3 e$ g. K; T' z: e
  10. /* Get 32 bit Random number function ******************************************/
    6 S0 K  p" B' N
  11. uint32_t RNG_GetRandomNumber(void);
    ; |1 h# U9 F! C3 |. A

  12. " j- o- N, _7 t- t- Z# k
  13. /* Interrupts and flags management functions **********************************/
    $ ?) o6 ^9 {5 F- ]- E: K2 T
  14. void RNG_ITConfig(FunctionalState NewState);; b2 h: J/ Z/ i4 ~6 l
  15. FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);3 N% O4 p, P7 I
  16. void RNG_ClearFlag(uint8_t RNG_FLAG);' |7 a' p& k* z& m
  17. ITStatus RNG_GetITStatus(uint8_t RNG_IT);0 e  C/ s9 c3 q; s
  18. void RNG_ClearITPendingBit(uint8_t RNG_IT);
    ) O! G0 O+ `/ F0 o
复制代码
' }) U" ?9 H; J2 `3 ^7 F
04. 程序示例
7 e9 P: U' F. q$ zrng.h文件
* F1 C/ m0 s) H2 \9 I1 s$ `. s  f
, ^) F6 l8 y. J( Y5 M& A9 G
  1. #ifndef __RNG_H__
    , S; W* {, u" a7 i' ^4 y
  2. #define __RNG_H__
    / P( d; s' N0 x6 M3 i9 ]% y
  3. & J" S* D, f' l" H5 i
  4. #include "sys.h"! w9 }8 p; v7 a4 Y# ?8 S/ q" c

  5. ) @0 m7 J4 J& {
  6. //初始化
    4 `  D. C. g% M" \
  7. u8 RNG_Init(void);5 m3 A8 r5 L4 g  {
  8. % `, {% f. F" I) Q
  9. //获取随机数3 I; L, G* [- i- V, p
  10. u32 RNG_Get_RandomNum(void);
    - q! \0 Z; P, {: y4 f
  11. $ P  `2 o. m2 p3 E& A
  12. //获取范围内的随机数+ P3 R, H6 y: w$ ?/ a
  13. u32 RNG_Get_RandomRange(int min, int max);
    * u5 o* w+ ^7 O$ [* h

  14. 5 U" i6 F6 n5 s* f& z, h

  15. * u9 N2 ?5 ]: O+ q: Z7 R! l3 r  b& ]
  16. #endif/*__RNG_H__*/
复制代码
$ ]' i2 G" x+ {
rng.c文件
: ]3 A4 t4 `0 Q* Q- k
/ @0 b, ~! S( ~
  1. #include "rng.h"% b8 x. W% N: P) C6 M
  2. + _$ I  S  n) C7 m/ I
  3. #include "delay.h": G2 o  u* {+ P% H

  4. % k0 l5 k1 t3 t* n) S
  5. //初始化2 M: a* F: ]1 V; f5 A: G. k
  6. u8 RNG_Init(void)
    & G8 `/ f1 P- S4 }8 U" [
  7. {
    , p# F' l% A. @1 b( g
  8.         u16 retry = 0;" s$ H. D2 w1 i8 k0 E: J3 G4 Q! j
  9.         
    " M; H, F! L7 }, C
  10.         //使能时钟
    * k( A7 d+ e; `- M0 ]9 F1 S6 z' J
  11.         RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
    6 S: \/ J% p  C# b- D! a) z
  12.         , r+ X. K$ y+ V8 j8 K" L
  13.         //使能RNG/ @  f) e& f: C' C  l/ t1 y
  14.         RNG_Cmd(ENABLE);
    - g$ |6 B8 m$ s  o
  15.         : a2 d' B& F% x% K- C' \
  16.         //等待随机数就绪5 Q" p, @+ A" S$ R0 l4 }
  17.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET && retry < 10000)  B7 B  v1 A% h1 ]+ M+ _
  18.         {2 p- ^7 V7 ?/ h) ]" x0 ~: _
  19.                 retry++;
      n) ~. x" Z% @/ U9 l" q3 Z
  20.         
    : @1 ~8 W5 p5 L! ~& E6 V2 E3 W
  21.                 delay_us(100);
    # H9 U6 T! a5 D, d) V
  22.         }
    , W+ J# M1 j( ^2 p6 P
  23.         
    . l$ f, c! P  q- |* \1 p
  24.         if (retry >= 10000)1 r& m- u# u$ s' d2 d
  25.         {; o' d& u3 T. D# E
  26.                 return 1;1 ~  R; w+ `! E' E& C( p# d
  27.         }
    + C! B+ d- M8 ]' T, n# S8 G& P
  28.         ; s! x8 e- A2 [: N# \$ K
  29.         //获取第一个随机数丢弃处理
    " [9 S4 l' h9 P7 |. r. b
  30.         //将 RNGEN 位置 1 后产生的第一个随机数不应使用,但应保存起来,
    ( F: o' W9 |! u4 x; R" V# E' ^
  31.         //与产生的下一个随机数进行比较。随后产生的每个随机数都需要与
    & ^2 @2 f/ \! g: a8 p7 o
  32.         //产生的上一个随机数进行比较。如果任何一对进行比较的数字相等,
    & h6 c5 l" @$ A7 d2 Y
  33.         //则测试失败(连续随机数发生器测试)。
    . G6 z* \5 _, E/ i7 R+ |  f  Q: C( x2 c
  34.         RNG_GetRandomNumber();# y& L# P/ }6 N/ k5 K& f- \% A

  35. " i$ i% v4 w$ A
  36.         return 0;9 D  d3 F' `5 N5 V5 h4 X' x
  37. }! d( B- b3 t/ l+ q4 F. A+ r

  38. ) J0 c9 ]3 M' i& l& E/ L! s
  39. //获取随机数
    6 g$ m; k0 p/ r, {1 ^2 e2 t0 _
  40. u32 RNG_Get_RandomNum(void)
    ( t- |/ C4 s0 r* w( o
  41. {
    - y" i" U; a" g7 y2 i8 j% k
  42.         //等待随机数就绪3 u" Z: M3 ]; D+ F) K4 @! ^3 y
  43.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET)+ }' I0 R: D$ b
  44.                 /*Do Nothing*/;; ?6 w- k! E2 m9 T- p% M, A# Y5 m

  45. + e9 m8 X) a% E' [3 Q
  46.         return RNG_GetRandomNumber();
    6 t' i# s$ i1 U' R6 ^
  47. }
    " e. q# |9 w6 }

  48. * @1 E/ K4 I8 }' u0 q6 C
  49. //获取范围内的随机数4 J" N) R& m. ]2 H1 J
  50. u32 RNG_Get_RandomRange(int min, int max)
    4 K9 N6 V8 h" h3 q& s% E2 f3 h  k) g
  51. {' z1 j1 u. b* P- j% A, \5 v

  52. " t, B- z; ^- R  s  {, c
  53.         return RNG_Get_RandomNum() % (max - min + 1) + min;
    8 y& j; O: c6 B- v
  54. }
复制代码
! h3 i/ P0 \) q! `0 }- m, }$ ^
main.c文件0 {* ~# N$ g' U! A

7 m' s; V. u. E2 }- Y/ E
  1. #include "sys.h"5 H& h, c3 X  m
  2. #include "delay.h"3 G3 V) F5 F3 n' [2 e- t
  3. #include "usart.h"" p4 k: M# |" W, n9 E% w4 O1 I, T& W
  4. #include "led.h"
    . r, _+ K3 R& F( L
  5. #include "beep.h"0 `+ S8 y" U6 v- `1 i8 S! g
  6. #include "key.h"
    , H8 z* f4 H* T$ m4 h4 B, ^0 i
  7. #include "usmart.h"
    0 J) h/ O3 E  v. o& ?
  8. #include "lcd.h"& p9 f0 A+ U+ P( O: f9 H* @
  9. #include "rtc.h"1 d! ~  W  |: z4 P! U! E7 i
  10. #include "rng.h"( e, O  P7 M" V
  11. #include "key.h", D$ j; o/ U8 t8 {! X- f% h
  12. + y" r9 O/ Z$ G9 `9 m( D
  13. //LED状态设置函数2 f1 o8 E  u7 ^) H9 {1 ~
  14. void led_set(u8 sta), q9 m+ `; L7 T
  15. {
    # {" [' @: L( @  n2 ^. P" `
  16.         LED1 = sta;
    % \# N/ g, [! q' }( N* i
  17. }9 Z  i# W( k9 ^
  18. ) |8 i. ?  p5 P6 G; A, q
  19. //函数参数调用测试函数8 Q8 a( p# M1 v$ X$ F* p9 p1 @% W- s5 ?
  20. void test_fun(void(*ledset)(u8), u8 sta)# }6 p; o; |9 }% Y  A
  21. {$ C$ Z1 Q% F; Z7 q. K- q5 M) F% S9 T
  22.         ledset(sta);9 {% |. w1 p* M  c' O7 w
  23. }
    $ q' {, P+ ^( O% W
  24. & T& g, A8 |& V2 z3 e  Y! D
  25. int main(void)) E( W  C+ l* A7 @' }+ e
  26. {
    * d# V$ j8 w4 Y! ?6 ~  f
  27.         u32 num = 0;
    . Q0 [0 E, G) ]/ V1 U1 J
  28.         u8 key = 0;
    / r3 g2 ^9 L* o0 G2 i
  29.         u8 t = 0;) n( i8 j5 y" b1 M: `
  30. ' s( \+ }3 w$ }9 f
  31.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    8 q. q( W8 ~7 W( l/ i6 l! P
  32.         0 f: t: u7 W7 b  O  r' `  f: B
  33.         delay_init(168);
    ) l. _5 `1 t( w' m) q3 a
  34.         
    ! A5 w* k) |! D5 H% F: J
  35.         uart_init(115200);( _: m0 `5 P* E# ^3 a) Y. L! I1 u
  36.         . j4 v; |# \% t* B
  37.         usmart_dev.init(84);
    - P. N# S7 N: K. H9 s  f4 Z

  38. / d$ W) x( B' s; r) ?
  39.         
      l4 {' X% D: A
  40.         LED_Init();
    , |* s9 B5 r3 t& }! m
  41.         " w, d; [7 p- W. q
  42.         KEY_Init();
    * m1 v" T1 l& ~7 N$ L  f  s! `
  43.         / p9 t( ]( V* q( Z  R! g' J
  44.         LCD_Init();
      t/ B, I1 C% ~$ U" ^5 m2 V
  45.         4 a* n5 t  A6 L" s
  46.                 5 g) X# m# Q& M  z4 ^
  47.         POINT_COLOR = RED;6 Z8 s! J/ q8 D9 P. e! @, U
  48.         2 C/ ^1 k9 l0 \- h, d
  49.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
    ! T4 \" `. a& i0 s: C0 W
  50.         LCD_ShowString(30,70,200,16,16,"RNG TEST");        
    ) u8 ~( q, O3 o: V8 C
  51.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");1 |1 N9 ?, u3 @2 {3 X. c6 G
  52.         LCD_ShowString(30,110,200,16,16,"2020/09/10");         ; x9 C# K- c4 n' Z0 l
  53.         4 G/ v1 }8 M1 O6 O
  54.         //初始化随机数发生器
    ; p4 Q; v6 L( _0 s/ u% q  W# n
  55.         while(RNG_Init())
      {! N* U3 g* W6 ]) d; J, v) x
  56.         {5 ?, }1 P, b- z" {8 S5 ^) X0 u1 b
  57.                 LCD_ShowString(30,130,200,16,16,"RNG Error!");
    ! g- V, h( u/ E3 r0 X& C
  58.                 delay_ms(200);
    & B0 d4 L$ g* ?, c  W" W
  59.                 LCD_ShowString(30,130,200,16,16,"RNG Trying....");        
    8 u) r5 u- c. ~8 B% W9 @" C! C
  60.         }
    $ G# I5 h4 I* l$ Y3 X$ n$ W- N
  61.         8 @8 ~7 y3 x+ e9 c& X# _
  62.         LCD_ShowString(30,130,200,16,16,"RNG Ready! ");         - Y" n) X9 i* d' |! D

  63. & p  _0 L7 N/ Y7 |) r8 Y
  64.         LCD_ShowString(30,150,200,16,16,"KEY0:Get Random Num");         2 j  D- ^5 Z, x8 H

  65. : a7 B) k# e! P$ Y: z
  66.         LCD_ShowString(30,180,200,16,16,"Random Num: ");           B4 f2 `5 p) K
  67. # {0 M7 t6 s$ y" W0 v: S" h+ \  i
  68.         LCD_ShowString(30,210,200,16,16,"Random Num[0-9]: ");         
    + x. ~; S* F6 g0 ?6 x3 u
  69.         
    * W1 k' N1 [# X! ^% {
  70.         POINT_COLOR = BLUE;) F9 O9 m6 ~) L* e
  71.         3 x0 Z3 ?/ y9 y( j+ K3 \
  72.         while(1)
    + _" o& B7 O3 `! V8 W
  73.         {
    ; w8 z/ L6 U" q+ d) P
  74.                 delay_ms(20);
    % y" M2 _, E& u) ]0 U: J! V
  75.                 6 }5 i* ~+ e6 z- y/ O
  76.                 key = Key_Scan();" K7 G! [. p- _# }7 ]
  77.                 if (key == KEY0_PRESS)% M& D7 Y  U% ^5 c
  78.                 {
    % k4 \4 C' N/ R
  79.                         //获取随机数1 |9 C0 i. B: m' a
  80.                         num = RNG_Get_RandomNum();" c3 \2 w; F9 l3 K1 }' s
  81.                         LCD_ShowNum(30 + 8 * 16, 180, num, 10, 16);        ) y- c, u! W$ Q, L2 P( t- v7 g1 q2 ]
  82.                 }. F! I- s" ^1 i  U( F
  83.                 & p) l9 V* \+ h1 T1 P
  84.                 / _3 ]; _( [9 m# P' {# T
  85.                 if ((t % 25) == 0)
    ! |7 Y( H- \; l+ ^6 ^
  86.                 {" M2 y7 g+ T8 K7 K6 \$ s+ l+ ?/ G
  87.                         LED1 = !LED1;
    9 p: ^; P/ q) |  M, x: [) |6 s
  88.                         //获取随机数
    ' B( l# ]/ p/ E* T* h
  89.                         num = RNG_Get_RandomRange(0, 9);8 W) h: r2 M. i. R7 l" D
  90.                         LCD_ShowNum(30 + 8 * 16, 210, num, 1, 16);                                
    ; |3 k7 S+ s" D* [. _
  91.                 }
    % [0 u) u- ?1 w% I8 I
  92.                
    + t8 k0 [5 {1 E# O3 q' s
  93.                 t++;        
    ( b/ }  Q" U! `5 B& f8 J9 v
  94.         }
    " K. z6 A6 m% C+ y8 E0 G
  95. }
复制代码
3 a( I, G! ?9 R# }
05. 结果验证
! t. C' [1 a2 Z, |& b3 _1 V1 E将程序下载到探索者 STM32F4 开发板后,可以看到 DS0 不停的闪烁,提示程序已经在运行了。同时每隔 250ms,获取一次区间[0,9]的随机数,实时显示在液晶上。然后我们也可以按下 KEY0,就可以在屏幕上看到获取到的随机数,
/ W: f# |+ C6 ~; M! e/ T, T3 |7 l, I5 z$ m- T: p% b. w

# E  D+ y1 O* q9 Y$ G4 K$ u* _; I
赞 收藏 评论0 发布时间:2022-3-30 11:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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