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

STM32CubeMX开发之STM32F407USB实验(CDC虚拟串口)

[复制链接]
STMCU小助手 发布时间:2023-2-2 15:47
前言( u- u, @( _' s3 A  t
本次实验以 STM32F407VET6 芯片为MCU,使用 25MHz 外部时钟源。
* g+ z( f% ~" k! r) X# YUSB通信引脚 与 MCU引脚 对应关系如下:: W- @8 j' G# H# ?6 C

' Z& ]$ N8 \+ l: {
(N[{M2V35~IJUGMBT21MCSS.png
$ Q3 |4 k7 g  |2 w& Q

+ ]; H' M# a: {7 n( M1 h原理图
* y  c- u7 B* |- z) V2 r3 M/ o
$ V, N/ e0 V5 v: b' Q7 q
0ffe931f944e409aa3ef895ad8d377aa.png 9 l3 W" ]: g, _8 s( \6 V1 z
. I( w1 T8 V6 j) G$ v+ {

5 n% K4 K6 q/ t; {/ M9 F一、使用STM32CubeMX----新建USB实验工程3 G6 r: V4 u$ {2 ~+ W; o
步骤1:打开 STM32CubeMX 软件7 x8 i% l% n6 C. n0 _7 ^
具体 STM32CubeMX 界面如下:
0 Z6 \) H/ ?; x4 e$ m4 h8 ?. n8 u  |  l
5e3baed520ec4265a0fa5d86e128a87d.png
  O& d0 X+ p6 t! b$ v! z5 t, \; Q6 s6 S" y( U8 o4 @6 S) e
步骤2:选择 从MCU开始我的项目
1 Q9 A0 \# v( i4 J* D5 _. }
" P+ \7 @$ Z8 H4 ]
b78fbedc12aa48528cd6ee408cb781a5.png
. [9 ~; j0 V) F
+ i( R: Q+ g+ U5 I) s  U步骤3:选择MCU芯片/ i' c# D5 Z5 n' z
我们本次实验选择 STM32F407VET6 芯片做 MCU。
4 B) Y0 T& `8 H) V" p& s% o: S/ G3 J* ~& V7 M) J, a: Z
fe3160420fda4e639189697407f7a41e.png 7 }7 ?' u2 B9 P( L

8 F# P" M7 x* Y8 O" ~+ P# M8 s8 f6 U
1 z6 s0 Z& Q2 G0 o* P3 Q
进入工程编辑,具体界面如下:- U' m6 I" m* P. d$ P: @0 I6 Q

2 ?4 \2 Y9 d/ c0 r
2b36307036d54321854c09041aef8af2.png
4 ?+ y  D2 Z) V3 r1 G# o& [  {0 u. t
步骤4:设置烧写方式为 SWD模式
* {1 d# k. S5 i6 h7 Q这一步必须选择一种烧写方式,否则烧写一次程序后,芯片中就没法再次烧写程序了。需要硬件重启才可以重新烧写程序
  E3 H1 W( D' c7 h9 [5 O
( B% ^/ w* P! Z) `) `6 m
772505d02fc841edb6087325c6d5a918.png / ?4 f, R' }; B6 ?% D

4 m7 a! n5 Q* }/ ?8 S2 I步骤5:设置时钟源
) F* r+ g& B3 ^3 q9 J5 |: W设置外部晶振为芯片系统时钟源。* i! _! _: w) G3 U$ i
1 @  ~8 r  W, ^0 }
9d4935492cd940f8a8f9d70b24ff5d5c.png - K3 ^1 _- O& }
$ {/ z4 q$ q( E! O$ Z6 |
步骤6:USB通信配置
. J0 F, S" I; L8 z激活 USB 设备0 C) P0 o' b& P3 w; c

- Q# @# ~6 z* _) l4 i
3a7889bcf93246759229dfbd0756c59c.png
, T# {2 E* |, Y1 @
# P- q. ~& ?" S( C
选择CDC模拟串口
: q$ _: l, S$ ]3 s) D7 A! a: W, P5 t( G; s! Y
9eeb84778149413c92046fb8a6851e37.png
, Q. B8 c; @3 c4 z: x" `$ t' x$ O3 \

7 S3 o) M: Q. Q$ T0 u7 r( Y1 g步骤7:设置时钟
  M/ b6 B6 i* a) k  e( \3 y- e, t因为USB的时钟需要 48MHz,所以时钟配置如下:- b& p" D2 O5 f) d& B$ C, {

1 h6 W% {1 ~8 ^. c: {/ v! v
30ac6a7ae6ef4897bc2ceec484b379ce.png
4 q* }5 s+ G, M0 v6 J! `9 C' c, J; T/ i+ h; a
+ e! {- D; t) B$ [
步骤8:项目编辑- T1 G* `; s; T1 T: p
堆设置大一点,否则识别不到USB。# u3 l5 T  }+ L4 q# r, Z4 Z
3 R! o5 y/ X* L/ N+ O$ f* A
c636c3e66e534d3da4e2d2c6b9165e7c.png & R% O) X' H  T7 Z
) x+ i& x6 _  P8 y" [$ Z" o9 U
步骤9:代码生成编辑% J7 z; B& y# v

- z% M( v6 t: H: D. x
61eaf4a2790c4e5a89ab2b777d2b2b24.png 1 P6 w; X0 w) s) `* j0 f

9 ]9 H! }; c" \1 o步骤10:点击 GENERATE CODE 生成代码
" q  l+ x8 g9 [# M! H! q
# I8 S& i# D" z& o4 B
9fe5104095df4ce9b3e59e948637ae60.png & I1 r% f  u7 [4 L% C, V9 _7 {
: r" O6 }6 }6 ]% {; v9 g
新建的工程,已经生成,接下来就是对工程代码的编辑。+ c% O# a1 p: x% c

) Z& I  z4 [3 B
1 Y# e) [7 r) I$ N8 n2 Q4 q3 b
二、使用keil5----编辑程序* e& X/ j# i2 L3 P) m" s! g7 Q' r9 ^
想要使用keil5打开工程,需要电脑先安装 keil5编译环境,具体操作流程。
9 |, |0 A% f( i" g
5 t$ A7 i) K! ^; p8 p! P, Z
步骤1:使用keil5打开工程% J( y+ B4 A+ |% b0 Q; @
点击工程文件中的MDK-ARM 文件
* I9 c% J/ }0 J3 d6 M- x
1 p8 @& [8 {$ E$ R! u
bade50b163404970a35f8f80ffdba501.png
' ~# ^4 }4 G5 q& a& F+ Y& x

& i* z* d) @5 ~/ s3 q打开keil5工程
& h* l4 _( ]  d! B6 F: V% w) }9 S2 C& w+ `* G- Y! w
7b083045873c4683a9f445d8d99ceea0.png
3 W3 x4 _/ Q2 `
! v& |( b8 M; S5 N( m0 j
步骤2:用户代码编辑位置) N9 {- x9 k/ r% c* [7 l
用户代码 要写在 USER xxxx BEGIN xxx 和 USER xxxx END xxx 之间。
+ L: N6 X6 C" d4 L这样下次使用 STM32CubeMX 重新生成代码后,自己写的代码不会被删除。
* z3 \! G! r0 P/ z% N/ ^% e7 ?, B: o: q! N
bb60a691bb4145209db966d0f63aecb3.png
) @8 E5 z$ `2 q6 n1 K
1 R7 c' g1 @9 {5 d
步骤3:查看USB虚拟串口的端口
+ t+ v, P% {: X. a首先编译程序,然后烧录程序到开发板,具体步骤如下:. `0 o9 P/ H; G5 u* L# B3 Q6 q1 q6 c

; ~8 F# E' A3 z* M% I8 u# i. U8 ^6 ?烧写完程序后,连接开发板和PC端电脑,然后在设备管理器中查看USB虚拟串口的端口。, J" Q8 O0 Z2 r
有以下端口,就说明USB虚拟串口功能实现了。" G9 g: Q( A! ], h7 W# |& `
9 T  F  Q1 C; A
fadf11a591f849f5988973bd07bade02.png
; ^7 U* S5 f7 _* S7 h- [
* S6 S" h' C) [步骤4:USB虚拟串口发送数据) L" _0 ?1 c' M! g5 L- a
在 usbd_cdc_if.c 文件中有 USB虚拟串口发送函数:
0 P+ j, ~+ N9 a1 N1 z! ~. W
  1. /** USB虚拟串口发送函数
    2 P% U  [" t2 m  r0 W) _
  2.   * 参数1:Buf 要发送的数据缓存区' s% |& Z' J; B9 U
  3.   * 参数2:Len 要发送的数据个数& y5 \2 `& G- }$ y! v
  4.   * 返回值:USBD_OK-成功,USBD_BUSY-忙碌, USBD_FAIL-失败
    0 o2 ^3 b7 L1 h: N- c$ {& ]% H* u
  5.   */2 l2 y6 u3 `/ r& X7 `
  6. uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);# D3 o0 Y4 C! W# l6 b' ]# a
复制代码

1 b: g8 h0 @/ \7 H* n, }% A将头文件 #include "usbd_cdc_if.h" 添加到 main.c 中。
% f  l. n  m' W! b
2 W1 G) `8 s; n+ b 5d05ebcf2a534b6ea8319fe615bf3766.png
0 L- g% H% x* U6 n

$ v4 }4 J1 x4 @在 main主函数循环中添加 USB虚拟串口发送函数
  C: f' ?4 I+ u
  1. int main(void)
    1 h. C# w6 @8 Z- W- ?1 W
  2. {* @6 n- T3 q+ ?% l
  3.   /* USER CODE BEGIN 1 */( E. R9 t4 V. w$ `7 j
  4. ) i* n+ n& D. `8 L( ^7 L- B
  5.   /* USER CODE END 1 */
    * h) Z  S1 U; C4 R! W- e0 E1 d

  6. % F' ]$ d* d* S+ I' e7 A
  7.   /* MCU Configuration--------------------------------------------------------*/3 l9 w6 e# N  c, O. j& ?3 M' ^
  8.   D5 t# j& K2 g* C
  9.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    1 r+ [2 [) E9 {% b1 p. }5 a
  10.   HAL_Init();
    4 H8 o  \: k+ ~$ J; ]

  11. 6 `4 d6 L' Q$ ~2 F) ^  v! P" N8 o
  12.   /* USER CODE BEGIN Init */2 T& @/ q7 P" B( O

  13. & W, P% i! N& \; X
  14.   /* USER CODE END Init */6 T5 ~1 q: j+ \& K: L2 e/ q

  15. : P: _  s/ E* b) m0 B- z
  16.   /* Configure the system clock */' b/ \6 x0 N: ^! F5 C) P) H
  17.   SystemClock_Config();
    ' N+ u7 c3 s! g0 J  m3 g( x

  18. - d  K6 z2 P' S) ]- x+ }9 O2 v
  19.   /* USER CODE BEGIN SysInit */% |1 k4 \# Y4 f1 l0 _8 `0 c/ A
  20. 4 J" h" M5 ~% V! g$ [1 }
  21.   /* USER CODE END SysInit */
    " U0 O) X1 L5 A0 U. Z! g3 R7 b

  22. . @& X6 H1 {& u2 G0 D4 ^6 W
  23.   /* Initialize all configured peripherals */
    5 |* R: n  P1 A" A+ q
  24.   MX_GPIO_Init();
    # d3 R4 W( P% S3 [, _
  25.   MX_USART1_UART_Init();
    - Y' e9 k& k! a: A! p1 L, n; W
  26.   MX_USB_DEVICE_Init();% ~: f- Q& h- R' ^
  27.   /* USER CODE BEGIN 2 */; X4 `* M. x( X. b7 }# d" ?- H
  28. 0 F% P4 {7 G7 B1 z$ Q+ a
  29.   /* USER CODE END 2 */' P8 y+ G% S% a3 |: x8 F( x1 c

  30. 5 `" F( P9 N- q1 K4 }
  31.   /* Infinite loop */1 W$ o3 w5 O# X
  32.   /* USER CODE BEGIN WHILE */7 D- f2 ~% F, e  B6 y& Q
  33.   while (1)8 Z" }3 n) \* t3 Z( w
  34.   {
    , O) u5 }. G! L' u' G" U
  35.     /* USER CODE END WHILE */2 k4 V! [8 |2 \4 X
  36. 0 `+ [2 P; s; G. o$ {
  37.     /* USER CODE BEGIN 3 */
    / T" m2 @( T/ r0 p( ]) @
  38.         CDC_Transmit_FS("工欲善其事,必先利其器。",strlen("工欲善其事,必先利其器。"));+ I1 U) P$ l! m
  39.         HAL_Delay(500);
    8 N0 k) ]/ W8 O) u
  40.   }
    ! O+ H% A6 ^5 J$ A9 q& ~
  41.   /* USER CODE END 3 */
    ; g" ^( |5 Y% {
  42. }
    # b( d/ l# z3 P& l$ L# \: x3 o6 j
复制代码
% p: k- ~! Q* ?1 G9 v2 O
使用串口助手打印数据如下:
5 X1 i3 a+ l  t4 f( `: U8 H# p9 A1 N( S" H
3ee5814c820741cb8577affb9e366334.png
7 _) M2 z/ }. i# X' V2 g2 f  Z) q/ h8 k6 y- d4 n$ V* g3 n, C8 v
步骤5:USB虚拟串口接收数据4 t( e) I/ ^  m6 D" n7 J0 V
在 usbd_cdc_if.c 文件中,有 USB虚拟串口接收函数:
4 C1 P. x+ Z* g* u0 i* f
  1. /** USB虚拟串口接收函数
      I. `  N& Y0 W
  2.   * 参数1:Buf 要接收的数据缓存区
    1 V: q2 q. E4 j6 @
  3.   * 参数2:Len 要接收的数据个数9 Q1 e# c2 E2 M3 n! J, v/ R$ {( n
  4.   * 返回值:USBD_OK-成功,USBD_FAIL-失败5 p  @9 b% c5 D
  5.   */
    2 Y1 f8 |3 b* m4 `) P1 U
  6. static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len);
    5 l3 j- D& y' E+ T
复制代码
7 e, ]6 X$ j% Q
在USB虚拟串口接收函数中添加 CDC_Transmit_FS(Buf,*Len);,将接收到的数据发送出去。
0 z. H  y* C. U1 m! m3 F9 x/ x9 o4 L) x: q
875ea12e40464964bbc66cafe0485039.png 7 j7 s9 m0 F/ O/ W) s* h; }# G

- m/ D; m8 g. q使用串口助手调试如下:
/ s( W4 f) f% T2 O' K4 [
  D' f8 A& p5 v3 l( r2 h, u' d& F
f77e04111a7c46a096fbde3cb91a19c9.png : ~+ \6 R( T7 G. {+ \' s0 A( C, a
# D4 G0 [  o. P
————————————————1 H* R. I0 I# ]+ E3 O0 D5 q. v
版权声明:根号五5 N3 @9 D! Y) j4 l
/ h1 ^; \) Q3 A* A) W8 {' |6 A3 ]6 ~

* _/ v8 X$ v% y! G$ z' U
赞 收藏 评论0 发布时间:2023-2-2 15:47

举报

0个回答

所属标签

相似技术帖

官网相关资源

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