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

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

[复制链接]
STMCU小助手 发布时间:2022-6-15 14:00
01. 概述; |$ z" J- T8 ?
STM32F4 自带了硬件随机数发生器(RNG),RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数。
( p% m8 z: [. v2 y* u8 n4 h
. {  t' q5 n# C7 K相关头文件和源码在stm32f4xx_rng.h/stm32f4xx_rng.c。# s7 }$ |+ G! m7 n
5 s" \9 F) h: ~. {; u
02. 硬件模块
. B( G1 J) m+ O( Q( n+ B, f用到的硬件资源有:) t2 u% ~. |6 j3 g* m  d' t
1) 指示灯 DS0
+ P3 k) Z- |2 {+ l& l( W4 ?' c2) 串口
+ ]) U  ]% J% p, p3) KEY0 按键4 I2 a& D! v) x( |
4) 随机数发生器(RNG), k% j/ B" _! X+ @/ F9 f0 f
5) TFTLCD 模块* _3 Y, K2 D5 _6 ~/ T

% u5 Y5 o5 L" f2 Q8 u  S6 ^# T9 z03. 相关函数7 L' ]% H+ z) N
  1. /* Exported macro ------------------------------------------------------------*/1 M7 z7 H4 J/ G  D3 q& C; `
  2. /* Exported functions --------------------------------------------------------*/ 2 T# C8 x6 K' O9 t1 M

  3. . q6 m3 l* {. c( k
  4. /*  Function used to set the RNG configuration to the default reset state *****/
    * t8 D6 u& r0 E9 f
  5. void RNG_DeInit(void);7 Z6 c7 I# }  [

  6.   Y) j7 m7 r6 z2 D$ l0 Y0 }
  7. /* Configuration function *****************************************************/
    * C+ C7 }( f7 L& |
  8. void RNG_Cmd(FunctionalState NewState);
    , y- [, s- L" b# |

  9. ) x! Z$ X& u, l* f( i0 l
  10. /* Get 32 bit Random number function ******************************************/- I: q( J( B$ _3 q
  11. uint32_t RNG_GetRandomNumber(void);
    5 r. Q! o" |2 j7 q9 U3 [) H& V

  12. 1 _3 {0 G, I3 e6 P. V" n6 `% p
  13. /* Interrupts and flags management functions **********************************/
    0 D! `5 w: W& D5 K) l+ G: O
  14. void RNG_ITConfig(FunctionalState NewState);" T4 E2 ~2 s# W- T* k4 g( [
  15. FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);
    : d- N$ N* @6 h. x; W2 x
  16. void RNG_ClearFlag(uint8_t RNG_FLAG);
    * h$ f, F5 E' J6 Y0 t
  17. ITStatus RNG_GetITStatus(uint8_t RNG_IT);$ b. z5 W. E/ G0 k% ^" k
  18. void RNG_ClearITPendingBit(uint8_t RNG_IT);
复制代码
( o$ m+ P& B$ Z0 A6 D' F0 I) n6 p
04. 程序示例" `9 ^6 L' F! p6 o# W5 p& k
rng.h文件
6 H7 o+ p) x9 [/ Y+ u: B( {4 O
- ]0 ~: ^! S" a1 k5 A+ E% ]
  1. #ifndef __RNG_H__( S3 e; G1 ?) x: o/ I! ^
  2. #define __RNG_H__
    ' z2 M% R' f4 f4 e4 |8 ]1 j
  3. 4 }# ^2 b* K; `. J( x
  4. #include "sys.h"% [/ C) K7 ^' }

  5. 1 x6 |& ?( V2 n6 m& f" }  p6 o; w
  6. //初始化
    " a! N8 R- H  C  `! X8 @
  7. u8 RNG_Init(void);( X* F5 q6 s; P; d  F- p
  8. , u: E3 c# H7 t+ O  e
  9. //获取随机数
    - I6 _& e! q7 t4 l
  10. u32 RNG_Get_RandomNum(void);
    + R* r: \! e+ e6 m0 X( T

  11. 6 P* O/ c& R* E. D7 m9 A2 t) b
  12. //获取范围内的随机数5 F* e0 j% C8 P, z0 p
  13. u32 RNG_Get_RandomRange(int min, int max);2 h; R4 A: N! I- q5 ?$ _

  14. 9 ]# T, t" f( C
  15. " G+ X- l, j) O4 `' b% `
  16. #endif/*__RNG_H__*/
复制代码

8 Y9 [- f# B% Q+ n. Trng.c文件# H4 Y# ?* k7 o8 `: E+ {
1 p6 K+ M7 P& a
  1. #include "rng.h"! \" \2 f( h5 y8 Y0 ?  F9 Q6 g, o

  2. 4 W. g/ {- N  o- _) _8 l8 Y$ ?
  3. #include "delay.h"! X# X7 h, ^5 c3 U* D2 k3 X
  4. - t- G+ M5 n# d4 x; A
  5. //初始化
    $ y" _6 M4 d$ ~5 j2 ~
  6. u8 RNG_Init(void)
    6 p* }, ]9 m% q
  7. {$ X! W8 c7 l! O, ]6 t' r$ g& ]. x  E
  8.         u16 retry = 0;
    ; }8 \; |; W' Q, v9 O
  9.         
    ' K9 A' i7 r: {, [9 G
  10.         //使能时钟" Z" x. @( o$ n* V9 U
  11.         RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
    ! j" s5 O0 f1 U
  12.         ! D# g2 Y. }+ {6 J
  13.         //使能RNG
    9 Z( D2 u( A" |9 L  V" T. D0 _
  14.         RNG_Cmd(ENABLE);
    3 ]6 M1 X' H7 }# z3 Z6 U
  15.         " M8 a& k3 Y  A$ [
  16.         //等待随机数就绪! v  q& m4 x/ j3 Z
  17.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET && retry < 10000)
    4 O3 }5 D: Q7 l2 d( i8 L
  18.         {
    3 [  P! V" q9 D- v9 ~3 h
  19.                 retry++;; z% Y( O% U2 l% }2 l* o! }! m/ S
  20.         ) P0 {  W+ ]* i3 o; c. h
  21.                 delay_us(100);$ ^$ w# Y  ?, R/ \/ A4 D* L2 M
  22.         }
    , w: b- D) o5 C3 e5 _+ R
  23.         2 \( w5 E/ p; ]
  24.         if (retry >= 10000)2 S" K* k5 d1 A8 c3 M
  25.         {2 U8 N+ M, s* e+ I0 S
  26.                 return 1;
    0 `7 y1 r: {1 \3 ~
  27.         }$ D9 J8 Z0 u0 V/ B& }' P
  28.         
    ' f& z( e3 A# Y( m3 A1 Q7 S; L8 z
  29.         //获取第一个随机数丢弃处理0 M: S; s- N+ p" _1 L6 K5 b1 W* H5 J
  30.         //将 RNGEN 位置 1 后产生的第一个随机数不应使用,但应保存起来,; e( Q7 ~7 }* N# R
  31.         //与产生的下一个随机数进行比较。随后产生的每个随机数都需要与! r! `' G7 k; [2 L7 p+ w
  32.         //产生的上一个随机数进行比较。如果任何一对进行比较的数字相等,
    + b  u, J% n6 W/ u6 P7 m
  33.         //则测试失败(连续随机数发生器测试)。7 o# O( G+ X8 U
  34.         RNG_GetRandomNumber();. i" G$ b+ a1 F6 j3 Z- f: j2 h
  35. + s$ H- J8 E0 ?" V
  36.         return 0;
    2 e2 f3 R. O3 r* V/ L7 ^7 j$ Z
  37. }7 x. {. @7 h% @) C

  38. " Z0 w2 j, [' D1 Z' W8 S% @- c
  39. //获取随机数
    6 i- F: l; H0 }3 H. B* z
  40. u32 RNG_Get_RandomNum(void), I# H" l1 l3 r" e0 P- y. z
  41. {
    # O+ T5 D0 t8 M4 V
  42.         //等待随机数就绪9 e% B6 G& V) C( g# M
  43.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET), A" g' `% y4 R( D2 A4 ?
  44.                 /*Do Nothing*/;' A7 S) J6 v9 Z  p* F" z8 A( Z+ g8 i

  45. 2 O: L8 X! Y3 V0 ^" [) P+ Q
  46.         return RNG_GetRandomNumber();1 \: F- _6 K" ?/ q0 B
  47. }
    ( }2 k+ N8 `6 e* Y! E) g; }

  48. ) D3 `! h& o7 Y$ \4 L
  49. //获取范围内的随机数
    5 I1 I1 B$ `/ Q9 p1 j; j2 V' R
  50. u32 RNG_Get_RandomRange(int min, int max)% W) N% ~; |, p2 D, j: `8 A
  51. {
    , s: o# U  o% Y. H# ]7 w& |

  52. 7 Q5 Q) a* g6 D* U3 Y9 M
  53.         return RNG_Get_RandomNum() % (max - min + 1) + min;+ x# B9 Q* W4 F  H/ t5 Q
  54. }
复制代码

5 Y3 }7 H" x: Z1 o6 fmain.c文件% w5 t* X8 ?. q$ n

6 b4 \  v% X& {- `7 W
  1. #include "sys.h"
      n' A% c/ }6 x  {9 d# @0 q
  2. #include "delay.h") ]8 h' B4 R0 p+ Q# ^
  3. #include "usart.h"4 n% o- e4 J8 S( f$ }' Q9 g
  4. #include "led.h"
    3 g& E3 X6 ?& U8 T( ?
  5. #include "beep.h"
    % h$ H8 Q- e! d  O5 O
  6. #include "key.h"
    : N" U; L4 f4 g4 H5 W* v3 {
  7. #include "usmart.h"
    - w8 y+ b( {. U
  8. #include "lcd.h"0 ?& j" {: e& _6 [* t8 o5 H/ \* i9 ^
  9. #include "rtc.h"' y  {% d- Q& a% c, I: `# r
  10. #include "rng.h"
    9 h9 j- Y6 F5 ]& V5 ^
  11. #include "key.h"
    ! D+ R0 G; Y5 b5 E& {) v7 [. J

  12. 2 K. I5 m+ A1 K2 M
  13. //LED状态设置函数% Y  W" ~! @& y/ f$ r" b/ n5 q
  14. void led_set(u8 sta). Z$ u, T! C( S2 g# V& T
  15. {
    4 l/ B( @: O$ @9 S
  16.         LED1 = sta;
    - a3 d1 B1 W" R
  17. }, O. |: w, V  q& O: s& l0 x% }
  18. - S3 G; g/ A  P( v7 M  I- F
  19. //函数参数调用测试函数$ Q! n- {0 t9 I( {: V7 U
  20. void test_fun(void(*ledset)(u8), u8 sta)
    ; p. o+ ~8 e2 [. v1 v, R# u( @1 c
  21. {9 k5 G+ `7 U! w* S5 H1 O
  22.         ledset(sta);- i3 \! F9 H" b2 h: s' |
  23. }
    2 n4 {# G/ B/ K. o

  24.   c' l3 z+ ?- U' q% i( j
  25. int main(void)& x4 t4 u6 h+ l# u# K
  26. { ) d) y) t5 O( m* M' s3 I- H2 ]# D
  27.         u32 num = 0;/ s1 C2 K, U  ?, K: H! E
  28.         u8 key = 0;
    . X) b* C: G  g. ]: u/ h
  29.         u8 t = 0;
    7 a* c  C4 j5 ^0 l1 v$ p
  30. ) I( v: R- B  f5 Z
  31.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    - T  @& m' E" W2 I8 `: A) |
  32.         / p; J: m& A5 a( B% o; j
  33.         delay_init(168);0 M! `. a$ |' r
  34.         ( T2 O9 e+ t$ Y  T+ _  j7 g/ U6 l$ e
  35.         uart_init(115200);& c! h1 X9 T6 G0 G
  36.         6 b! ?' l, t, z9 d
  37.         usmart_dev.init(84);
    ' e6 ^, U+ [2 H0 Y! b
  38. 5 G6 O- M9 p: t8 G2 J% N3 _0 K
  39.         
    5 s) g  W" d+ @* J' `
  40.         LED_Init();
    9 B0 z) L9 q3 Z9 ]& B& P! a# A
  41.         / A( d+ o: l! W6 G  {9 R
  42.         KEY_Init();
    ) Z* y3 ~5 m; E# Q4 W
  43.         
    5 f2 Z+ R* L" t
  44.         LCD_Init();
    3 F) C5 O5 _; e
  45.         / i. m8 a& X7 _: m, j
  46.                
    9 o- u& f$ L" ^
  47.         POINT_COLOR = RED;
    ; [7 C; b9 r" w4 t5 h: U) l/ J
  48.         
    4 b5 z5 g5 Q* ~, S% s  C6 d: I
  49.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        8 N4 E4 g$ m, G* r
  50.         LCD_ShowString(30,70,200,16,16,"RNG TEST");        
    " S( P! _# I2 T4 E5 b5 h
  51.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");- J. p* r7 h: X3 D( y; V
  52.         LCD_ShowString(30,110,200,16,16,"2020/09/10");         - y/ j% Z% I8 F3 A4 K) r* m* w
  53.         + J2 t$ k7 C( u
  54.         //初始化随机数发生器
    ( Y$ S9 u' `" ]# y- W% P5 `
  55.         while(RNG_Init())
      d1 n0 z  d( j  s9 }" `4 [
  56.         {
    / |  X' l% Q3 O, r- @3 J  F( r
  57.                 LCD_ShowString(30,130,200,16,16,"RNG Error!");
    ) T0 m! x7 w: x/ ]* b5 s
  58.                 delay_ms(200);
    * F/ H8 @$ s. \# E" s" O2 o
  59.                 LCD_ShowString(30,130,200,16,16,"RNG Trying....");        9 M4 A( o; b: c- L
  60.         }' `8 [' b+ q$ N' o
  61.         
    6 P. A! c/ l- g$ g# I
  62.         LCD_ShowString(30,130,200,16,16,"RNG Ready! ");         
    0 y& u9 S9 V9 v
  63. 8 W  I% n; o9 z4 U: N, S1 _
  64.         LCD_ShowString(30,150,200,16,16,"KEY0:Get Random Num");         ; ~) S% x) L7 `4 u- o( k& F
  65. 6 o0 J$ g3 P- s, M6 ]4 m
  66.         LCD_ShowString(30,180,200,16,16,"Random Num: ");         7 z: Z& B- T. ?6 K
  67. 6 e( g4 h4 M! O5 A
  68.         LCD_ShowString(30,210,200,16,16,"Random Num[0-9]: ");         
    # l* k# d+ Q. J% |/ L5 k
  69.         
    % O* ~0 [; t/ W2 R  R
  70.         POINT_COLOR = BLUE;
    6 X! T1 e# J" V
  71.         4 a8 X- e4 q  n; x
  72.         while(1)3 `9 b. R& E3 M6 J6 L. C6 J0 e
  73.         {, i; @) N4 U" `- ]
  74.                 delay_ms(20);4 j6 {/ h' v5 f! r4 }4 y: S+ U
  75.                 ' n. T. G" h) A; S0 m  A1 ^1 ~& J
  76.                 key = Key_Scan();
    # _6 g- o* ]5 Q- i
  77.                 if (key == KEY0_PRESS)$ r& Y8 t0 E& p0 O% N. P
  78.                 {* q3 d8 I9 d6 f6 o: B! Q
  79.                         //获取随机数
    . k# w: _) R& e: |  N
  80.                         num = RNG_Get_RandomNum();
    . l3 Q: c+ Z  r; x' V9 F/ l1 b
  81.                         LCD_ShowNum(30 + 8 * 16, 180, num, 10, 16);        + v1 w) N8 Z* o2 S8 y  W  h; G
  82.                 }& Q$ J" w6 Z: N
  83.                
    * N3 g$ O' a6 ^- y
  84.                
    0 A6 Q1 B$ d5 K% r% m( L. \$ h( }
  85.                 if ((t % 25) == 0)
    2 d; [) v4 b6 A; H
  86.                 {' C5 V# |' T0 k
  87.                         LED1 = !LED1;+ r' V, j5 @6 U5 B
  88.                         //获取随机数; @5 B$ i& o9 O* E% Q
  89.                         num = RNG_Get_RandomRange(0, 9);
    " m/ B, ?3 z! U$ e; _$ I- _2 f6 I
  90.                         LCD_ShowNum(30 + 8 * 16, 210, num, 1, 16);                                ( s$ s3 i! k3 ^  @# T4 x: e
  91.                 }
    # \/ q" O! D! h6 ^! c# g* ]
  92.                 ! B8 h9 o) Y6 o+ c% l/ @0 c) [/ k  K
  93.                 t++;        2 C0 R. b" {0 X: l' f; ^
  94.         }
    * i5 E# M0 k' z8 d: \' T
  95. }
复制代码
9 j4 _+ V$ X( D/ o6 U3 m+ z
05. 结果验证8 D6 r) @) C% M# g% j4 }
将程序下载到探索者 STM32F4 开发板后,可以看到 DS0 不停的闪烁,提示程序已经在运行了。同时每隔 250ms,获取一次区间[0,9]的随机数,实时显示在液晶上。然后我们也可以按下 KEY0,就可以在屏幕上看到获取到的随机数,; K) Z0 v- |; z2 c" s" }( ]

3 I7 d- Q) K$ G+ `
$ M& [; K  x" I- V! J+ m# \
赞 收藏 评论0 发布时间:2022-6-15 14:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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