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

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

[复制链接]
STMCU小助手 发布时间:2022-6-15 14:00
01. 概述" W& o* P9 @7 G' g% B+ H
STM32F4 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。6 Y* b: u+ i. U# Q8 U. l0 R8 k

% h& i9 G% a$ |) O0 b( }0 q3 M相关头文件和源码在stm32f4xx_rng.h/stm32f4xx_rng.c。1 }" y7 v' G7 E, y& q
; t$ U) K# X3 J+ a* p0 `% _
02. 硬件模块
$ {: H0 \6 s# E! u+ [$ e; z用到的硬件资源有:
! i" x. A. z+ }( ^1) 指示灯 DS02 b6 ~  G( N& j, _
2) 串口
/ E3 j: e5 S+ L/ E3) KEY0 按键
$ L0 u' ~0 V9 D# H( k5 k4) 随机数发生器(RNG)
3 S5 Q) q! R0 y5) TFTLCD 模块
7 ]  f; g1 L# ]5 ]0 l8 v) V1 u( B% c) k! x- e3 B
03. 相关函数+ I7 h6 s0 K7 v; N8 q: e( C; S; H
  1. /* Exported macro ------------------------------------------------------------*/
    . P: }7 @% q  l- f" G$ l
  2. /* Exported functions --------------------------------------------------------*/
    5 y# C6 c% @2 U9 F

  3. + E/ l8 l" O2 N4 A* K
  4. /*  Function used to set the RNG configuration to the default reset state *****/ 3 U* U7 `& i+ D3 ^8 x
  5. void RNG_DeInit(void);
    / z0 a) ]0 `$ Z4 m% ]6 C! u

  6. ! A6 U  Q* @; A( A* f+ d' z% s5 t+ z
  7. /* Configuration function *****************************************************/: w8 g" |: C( M3 O* \" {* ^- F
  8. void RNG_Cmd(FunctionalState NewState);- r, Q9 _- Y& \- E% R3 x: s
  9. $ @8 \0 l4 m( W/ D
  10. /* Get 32 bit Random number function ******************************************/
    ! ?5 M  g7 o8 k4 \
  11. uint32_t RNG_GetRandomNumber(void);9 p* D& K! K" |* C
  12. * V: W- }4 J" D0 k
  13. /* Interrupts and flags management functions **********************************/6 ~; `: E; B6 x% W% i: k
  14. void RNG_ITConfig(FunctionalState NewState);
    " v( H9 Z2 M4 Q2 y0 u
  15. FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);5 p4 f: D2 O0 U8 ?; t. F7 m
  16. void RNG_ClearFlag(uint8_t RNG_FLAG);
    % D7 B4 [: O0 H7 L1 p" ]
  17. ITStatus RNG_GetITStatus(uint8_t RNG_IT);  a6 D7 w, ]) e6 G6 o# K
  18. void RNG_ClearITPendingBit(uint8_t RNG_IT);
复制代码

0 S$ Z& k; A* C* s5 e04. 程序示例2 w! }; X. f6 c# w- B
rng.h文件
0 z; s" D9 G. W7 @( `) }7 k9 ]9 R+ R. r2 k! N4 s9 d% z
  1. #ifndef __RNG_H__, e5 J1 i" M8 s# p' t, H7 F6 U1 g
  2. #define __RNG_H__
    0 ]4 j% v1 u0 ?
  3. - E* y! Y. \9 V: l5 }
  4. #include "sys.h"0 V% j$ ]+ ~- r" I6 C! r' q( x

  5. , j( L: v9 d" I; O8 J
  6. //初始化* T, [7 I5 x/ p7 ?: u& @
  7. u8 RNG_Init(void);
    ! W/ S: U1 t# ^, p* {

  8. 7 D. k6 B: ], h- g( i5 B5 {
  9. //获取随机数
    ' `+ q( y* N( E7 Q* d4 b
  10. u32 RNG_Get_RandomNum(void);
    ' F  c6 y- i, E

  11. ! G0 i; F. N: r$ U/ F
  12. //获取范围内的随机数
    - {0 Q7 D& k7 k. T& x
  13. u32 RNG_Get_RandomRange(int min, int max);% r: Z; j( \& R& i
  14. 0 P- }; [, W5 E
  15. ) g5 U. w9 Y# F" B( I4 e
  16. #endif/*__RNG_H__*/
复制代码

0 Q7 s/ ]0 }& a5 Arng.c文件6 E1 }! o& H2 T; |8 i
6 N4 E% ~" ^' o" N2 K7 F
  1. #include "rng.h", C: o4 c4 T$ o- P+ H3 x0 k

  2.   D7 c* ^5 `5 Q7 F! @% f
  3. #include "delay.h"
    - V+ x3 C9 P& v$ Q9 ^1 R
  4. 0 S% I' A7 U1 S0 o+ |2 e
  5. //初始化  S) D/ p0 k% M; E1 C6 C  u& {( ^: b
  6. u8 RNG_Init(void)
    0 _3 a3 N0 M1 {' b- t+ ^
  7. {2 t4 k* z# U2 }3 Z- O  @
  8.         u16 retry = 0;
    # _8 P6 {/ w* f/ \+ Y7 H
  9.           w6 J2 M& D4 N5 }
  10.         //使能时钟* Z  B1 m* ^( b: A, Z+ S; P
  11.         RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);* I0 J& Y* O% e* w# f- L
  12.         3 Z' o2 }) u, W  p8 }
  13.         //使能RNG. Q4 ^* m/ T/ F6 C8 s! a
  14.         RNG_Cmd(ENABLE);; i. q9 ~$ U, V
  15.         
    * d' q' e, x: {$ U
  16.         //等待随机数就绪+ A7 d6 O3 G* E9 \
  17.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET && retry < 10000)8 A$ s6 Q2 m% |" A# a! Q3 p
  18.         {
    - U5 b. N0 _1 _. G% A* ~3 ?# V! m
  19.                 retry++;
    0 g* v/ [4 t& s0 w2 X' ^! p8 c  g
  20.         
    + T6 L; s0 Q4 @0 [' j9 q# F
  21.                 delay_us(100);0 S' }- U1 P# M  X) `
  22.         }
    / k& h, k. x, u' z% K& o
  23.         ( O" m  {2 _' r4 ~. T
  24.         if (retry >= 10000)
    , P+ U. }: P8 q7 S! Q; U9 c* F
  25.         {  P" l# m. U6 s3 H& W4 i7 s5 u
  26.                 return 1;
    0 N2 E+ d/ g- r& I( O7 K
  27.         }
    & D) k, W/ d9 z) A3 y6 J* X& E- K1 h
  28.         
    , j; s& ~; n! ^9 K+ I1 v+ I. q
  29.         //获取第一个随机数丢弃处理) p/ `. q7 I& {5 w) b6 G) t
  30.         //将 RNGEN 位置 1 后产生的第一个随机数不应使用,但应保存起来,
    * t: \' \$ B2 B$ n" I2 m" V$ N, ~9 v
  31.         //与产生的下一个随机数进行比较。随后产生的每个随机数都需要与
    1 A: @2 P- j: Z: b3 @# N7 A4 ]% _
  32.         //产生的上一个随机数进行比较。如果任何一对进行比较的数字相等,
    * L5 Z+ P8 S% [1 N- I
  33.         //则测试失败(连续随机数发生器测试)。1 I/ q; @3 |+ R% T3 Z  ^
  34.         RNG_GetRandomNumber();) X: `4 u6 h1 R) u8 E9 w) g

  35. , t* X3 n' ^" c  ?% Y. C+ c- q$ w
  36.         return 0;0 b. ?/ R8 }" e  f  ~
  37. }2 ~& r) v8 }# D; @7 m

  38. 2 n6 _2 B& j# V, |: U, K
  39. //获取随机数7 }) W- W9 z! H, G: l( c5 z4 M! ^
  40. u32 RNG_Get_RandomNum(void)/ @. Q- r' r$ y+ T5 Q8 z
  41. {6 ?* y  _+ Q( W9 p( I9 R6 X/ B- Y, F
  42.         //等待随机数就绪
    0 l  l. G( h, _* Z
  43.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET)
    / J) R$ Z% Y% S1 l; i- m
  44.                 /*Do Nothing*/;  \8 i6 J6 X3 C  c) W- ], i

  45. % t- L+ V' n# k- b/ a  _5 o; Y
  46.         return RNG_GetRandomNumber();
    " X  x( J6 n; s2 y! f, R6 }* c& P
  47. }: {2 J9 q' O- f5 `

  48. 6 s: B1 |, {' s! ]: Q2 d
  49. //获取范围内的随机数
    / N/ W2 n3 O9 {( n* e- x
  50. u32 RNG_Get_RandomRange(int min, int max)
    0 q8 P9 w2 [4 {, |
  51. {
    / Q6 u4 [/ A% u9 E
  52. 2 f! i4 c' p$ v0 L+ f# P3 Y" H
  53.         return RNG_Get_RandomNum() % (max - min + 1) + min;
    . L, e4 ~, m( _3 k
  54. }
复制代码
4 ^9 P% ]# z& K3 W5 n+ w7 x
main.c文件  g/ E  b, f7 j$ c
' c5 |; [3 w6 B* l: j  F% J
  1. #include "sys.h"2 b( s4 y) W( {; I/ p
  2. #include "delay.h"
    ! u7 `* B% `: k: U3 X2 T
  3. #include "usart.h"
    4 K8 }. s& ]: c
  4. #include "led.h"
    / q! p2 c9 C# j* r! F
  5. #include "beep.h") s" X- j4 @( k) d# W% v2 a/ e
  6. #include "key.h"7 ]& m  @3 |. |3 ^; z5 q! s
  7. #include "usmart.h"
    ' r1 C& W  r' @* s4 R) }- ^
  8. #include "lcd.h"
    & n( u" a( q  {
  9. #include "rtc.h"
    ( n) u* w# a6 X; w
  10. #include "rng.h"* P5 k2 G/ C8 Y
  11. #include "key.h"6 o2 y* o) L, ~) J
  12. 7 ~: S+ P1 X9 a5 ^( f
  13. //LED状态设置函数- s# x' y( h9 F/ ~0 Z
  14. void led_set(u8 sta)
    $ M6 [  e% a% l  ]) `) z0 G" p( y
  15. {: D1 ?2 r' Z- E. y7 C: P8 r  n
  16.         LED1 = sta;
    , _; \3 @( c8 Q1 ~
  17. }
    & y3 E7 p$ ~/ C) P0 R- z9 v4 z& N

  18. 7 j* e" [0 `9 I; H
  19. //函数参数调用测试函数& V) J' g/ X6 I. w' {5 z
  20. void test_fun(void(*ledset)(u8), u8 sta)+ z& F& }! n$ F# L& b. h$ d0 f; w3 j5 @
  21. {" [; i  ~/ u  ~, Z
  22.         ledset(sta);
    + s+ \$ P( |+ F) p0 g! O- e
  23. }
    + x# W; c; `2 R. g$ u/ i* K

  24. : ~% A$ ?. O, m
  25. int main(void)
    & T$ i+ ~) ]6 W0 R2 F. g. E
  26. { 6 |' V& h3 d: @* w  [
  27.         u32 num = 0;) d/ d7 {6 j. B  `" _
  28.         u8 key = 0;
    , u) n5 g* L& g: m; z
  29.         u8 t = 0;
    * E: @1 b: q  I6 Q  e5 i# [
  30. & B1 V( S7 E; Q! e
  31.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    8 k% P6 o* h" x: m6 V4 m
  32.         
    & {5 e+ y% P! c* i  U1 ]
  33.         delay_init(168);
    . ]$ {6 K  _4 i2 h2 w% D# W3 {
  34.         : r. u5 Z$ H- m/ `7 |
  35.         uart_init(115200);
    ) A; ?2 g  {& `$ e& Z. C
  36.         
    * Q' y$ }; K' `0 I- I2 Z
  37.         usmart_dev.init(84);/ g& [, f+ l5 S$ n/ n: e, H
  38. / v% }: _' T2 q
  39.         
    9 S; M* B' Z7 k  H7 G
  40.         LED_Init();% x! t9 S: m+ j& E& h2 E) f
  41.         5 @  n' _& x0 Y7 `6 T2 z  T/ l
  42.         KEY_Init();
    5 y8 L$ M+ H5 F8 M7 x
  43.         + e( s, G0 }4 H6 k5 \
  44.         LCD_Init();
    5 P" Y& M7 a/ u/ W
  45.         
    9 k+ s1 j! H( g8 T
  46.                
    ) ]  i3 w) t* ]1 Y: S% S
  47.         POINT_COLOR = RED;
    0 M+ Y3 y; F5 W1 T3 O
  48.         
    9 }' s9 a+ t# w1 }: v8 D$ [+ h- m4 w6 R
  49.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        1 _# g$ A6 R6 Q4 z' S8 _6 ^) S
  50.         LCD_ShowString(30,70,200,16,16,"RNG TEST");        
    9 Z8 |- }' \3 u6 j5 _1 ]
  51.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");% J; j& X- ?5 {; `) _
  52.         LCD_ShowString(30,110,200,16,16,"2020/09/10");         " \9 {2 \6 j/ ^3 f; c. ?
  53.         
    4 d  C7 ^% B7 Y
  54.         //初始化随机数发生器1 g$ T+ ]# T- f2 N
  55.         while(RNG_Init())
    7 i. M% d$ V; s+ [
  56.         {
    ; P3 v* P  `$ T# ^
  57.                 LCD_ShowString(30,130,200,16,16,"RNG Error!");
    ; b, T; n) o+ w0 X! c) @
  58.                 delay_ms(200);
    * y* h1 q" m6 \7 d
  59.                 LCD_ShowString(30,130,200,16,16,"RNG Trying....");        ) c* N2 x, o- w7 v: b. s3 P
  60.         }5 y' ^/ u1 U4 @5 ]9 x; ^1 O
  61.         
    % Q. N% K- V, l6 ]* Q& a* ?
  62.         LCD_ShowString(30,130,200,16,16,"RNG Ready! ");         
    - W/ K+ A- L1 ]

  63. 5 b+ u$ o4 R1 _# i8 V8 R' o
  64.         LCD_ShowString(30,150,200,16,16,"KEY0:Get Random Num");         
    , p* l6 U, a) ^1 G4 o# N
  65. - m6 A8 R0 O1 \0 H: {2 ~3 Q
  66.         LCD_ShowString(30,180,200,16,16,"Random Num: ");         
    7 a4 C5 I8 o3 I# ?2 Y8 X7 x* g% R2 n

  67. : N7 I; t6 J  j6 f4 ?0 d
  68.         LCD_ShowString(30,210,200,16,16,"Random Num[0-9]: ");         
    2 v3 k; E% J" M6 D
  69.         7 w& w; B- g0 K) Y" \* j3 w
  70.         POINT_COLOR = BLUE;
    1 n3 z1 t; R4 u8 D. G- x
  71.         
    ( o1 t1 M/ p, t0 i- m
  72.         while(1)1 z! @: g& e) I. H! H# k, @
  73.         {
    1 j9 P) Z- f0 e7 Z
  74.                 delay_ms(20);
    ! i0 e! t1 T  x. G: K! v+ j3 J7 s
  75.                 * K# v; q9 H6 E0 f; [; r
  76.                 key = Key_Scan();# D: H* d5 p% n. }3 z
  77.                 if (key == KEY0_PRESS)
    3 U; {  m# ~/ N8 p; Q4 x' O
  78.                 {$ _: Y( t9 S4 f, _" d9 A
  79.                         //获取随机数
    # Q  y2 F0 ?! n- N4 `
  80.                         num = RNG_Get_RandomNum();
    # e8 H7 P% ]) _: C/ v. J
  81.                         LCD_ShowNum(30 + 8 * 16, 180, num, 10, 16);        . x; d7 ]3 e2 _2 E: {
  82.                 }. O( j  b. q7 d1 _7 q
  83.                
    7 b+ \# v4 @, K
  84.                
    # z! L* z$ a, j& A' a- x* }* c* b
  85.                 if ((t % 25) == 0)
    2 T  \) b% Q4 W. K$ d. W. n
  86.                 {
    2 Y. \3 a+ |0 G& [
  87.                         LED1 = !LED1;& x5 w+ V" t1 f, O( l2 t
  88.                         //获取随机数, W" S9 Q$ p& q# o
  89.                         num = RNG_Get_RandomRange(0, 9);
    ) h' T8 H' R, r+ u# e1 W) v) e
  90.                         LCD_ShowNum(30 + 8 * 16, 210, num, 1, 16);                                & V7 W7 Z: s  R$ P# k% M
  91.                 }; Q2 M# j2 }  p% _
  92.                 + {: Y' x. X. z/ `2 D+ Z+ {/ ?; }
  93.                 t++;        
    & y# R& a5 T8 D
  94.         }; m" K& i' M. \) u! J; u+ i
  95. }
复制代码
9 C8 O- L$ k0 P# W0 W  |7 p% J8 f/ e, k
05. 结果验证
2 _* Y- T' c2 [' e) D将程序下载到探索者 STM32F4 开发板后,可以看到 DS0 不停的闪烁,提示程序已经在运行了。同时每隔 250ms,获取一次区间[0,9]的随机数,实时显示在液晶上。然后我们也可以按下 KEY0,就可以在屏幕上看到获取到的随机数,) |+ E0 R0 ~1 E9 R) ]2 |* f8 n0 I* k
+ L* x/ H: S1 b* q

0 F% f. K4 o# _; n1 z( `" y" r( F
收藏 评论0 发布时间:2022-6-15 14:00

举报

0个回答

所属标签

相似分享

官网相关资源

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