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

STM32F103C8T6工控板与LabVIEW的串口通讯实例

[复制链接]
STMCU小助手 发布时间:2022-11-19 23:00
串口通信(Serial Communications)是指外设与计算机间,通过数据线按位进行传输数据的一种通讯方式。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。虽然串口通信传输速度不高,但程序简单,能实现远距离通信且成本较低,通信长度可达1200米。常用的仪器仪表大多都支持串口通信协议。
5 y3 x3 c) S( C' J# O; b$ pLabVIEW的自带函数库中有现成的串口通信模块,方便快速搭建堪比串口调试助手的软件。
1 K) B4 f9 m8 `4 V% H% s  w+ u 20210113230435579.png 7 G/ \) Q/ @7 s8 p

. T& C5 v) T! l5 ?1 @, \( o2 v今天分享一个STM32F103C8T6工控板与LabVIEW的串口通讯实例,主要工作如下:
0 Q; s( D. `, u1 F. x% }8 w1)基于Keil MDK写一个串口通信程序,主要配置STM32F103C8T6芯片的USART1相关参数并创建串口1中断服务函数(对应引脚为PA9和PA10,可在手册中看到,如下图所示);
, ^+ ]: i, I7 @* k6 S1 x  [; O6 n
9 M" Z, M# p) J/ f9 E 2021011409272047.jpg
9 X/ C# V, M& B& l9 i
) `6 h2 |- z2 Y/ v2)基于LabVIEW编写一个串口调试助手,用于与STM32F103C8T6工控板进行实时通信,具体使用的串口通信模块位于程序框图的函数选板–>Instrument I/O -->Serial里,如下图所示。9 T) ?) Y7 N$ F& y9 s

! d* M2 U+ g7 F; c$ X 20210114093438675.jpg
4 q, J2 f# r; A( }
1 ]2 e. [7 L& K3)具体实现的功能为:从LabVIEW发送一个命令到STM32F103C8T6工控板中,然后STM32F103C8T6工控板不进行任何处理,将接收到的命令反馈给LabVIEW。; o9 b5 {3 b- T! v6 ^

) t& N  _' m& L7 R: x- L% F3 @& ]0 C硬件部分
, _, z- n- ?& s) k2 ?0 d( ]2 Z1)某宝网上购买的STM32F103C8T6工控板,价格50¥左右;
" d' G  R/ J" x2 d! P$ ?9 m2)某宝网上购买的232转USB数据线(如下图所示),价格15¥左右。
: W4 N- V, g7 R3 c2 }
- ?& A% G8 j9 L4 m( |- z- h 20210114095104289.jpg . v* W% V4 J* |
3 v. v9 O- p! T5 j) v  {( M" Y0 _
STM32F103C8T6工控板部分原理图
+ V  }' N2 [; s1)下图是STM32F103C8T6工控板的芯片接线,PA9和PA10对应USART1_TX和USART1_RX,PA9和PA10经SP3232EEN-L/TR芯片至9pin的接口处,如下图所示。8 k( t4 e% l2 h- @, g& b5 I- m# \* i
2 K& R4 I5 g: ]$ E* A& Z9 i' T, x  y
20210114094338842.jpg - h/ |( z( c, ]3 S! _% h! h
" [9 O0 ]* }6 h
思路

0 h' n2 }) _' S7 M& N% d3 O3 x3 o1)对于STM32F103C8T6,配置并使能USART1,使能USART1更新中断并创建相关中断服务函数;
/ k1 R7 _$ g. N; |, }8 L1 w9 Y2 Q2)对于STM32F103C8T6,在接收到从LabVIEW发来的串口数据后,运行中断服务函数,将接收到的数据传回LabVIEW;( W/ X+ ]  _8 ^" O5 A/ p3 ?4 z/ M
3)对于LabVIEW,配置串口通信,相关参数(如波特率、校验位、停止位等必须与STM32F103C8T6的USART1配置的参数一样!!!( W" B5 Z5 I, G/ {/ b
4)对于LabVIEW,利用事件结构的while循环,每当发送命令的控件发送一次串口数据时,并接收一次串口数据。
1 ]* l& `9 i* F/ F- X! G. ?8 J- F7 P( ^5 [, Y. {+ f  j
相关代码
' F" Y# q$ ?  s8 U- k4 K+ P, u  G1)针对STM32F103C8T6工控板
. h5 }+ y5 K$ y9 N  h* U1.串口初始化配置函数(头文件)4 N. B! {+ ~5 X6 x( z: V
该头文件只包含一个函数,即针对串口1的初始化配置函数,用于跟电脑进行串口通信:) v: ~# k  \4 O% S
  1. /**
    - I# |9 ^  x# Y9 `
  2. ********************************  STM32F10x  *********************************
    - g# H7 ]  l  z" d/ `# l
  3. * @文件名称: serial_communication.h, a: g7 G8 g0 |& G
  4. * @作者名称: 闲人Ne+ T$ H5 m5 D; Z
  5. * @库版本号: V3.5.03 Z0 Q2 a1 z& o" D
  6. * @工程版本: V1.0.0& h+ P( u0 g$ m% e! f
  7. * @开发日期: 2021年1月17日
    5 Y3 Q$ R) v- n2 j1 Y
  8. * @摘要简述: serial_communication头文件
    * D8 ^3 C% N4 m! i. W' m1 y
  9. ******************************************************************************/
    * b, G8 a+ {! a% B. J  d( Z/ Y
  10. /*----------------------------------------------------------------------------
    # O; q$ m- V3 B+ Z1 n  H! P6 }; G& u
  11. * @更新日志:
    ! {, {, a4 a3 T, @  S4 h% N
  12. * @无& f0 s- l' C1 H/ H1 Y: V. E$ _: z
  13. * ---------------------------------------------------------------------------*/0 _7 z; Z9 M" M9 u; Y
  14. #ifndef __SERIAL_COMMUNICATION_H- c1 q" Q* j, ~! Z- z
  15. #define __SERIAL_COMMUNICATION_H' K/ Q+ l5 c2 w( D: t% ^/ z; C
  16. /* 函数申明 ------------------------------------------------------------------*/
    ) g  z+ d* M0 \5 N* _4 b
  17. void My_USART1_Init(void);
    ! s  v; ?( [0 Y& M
  18. #endif /* __SERIAL_COMMUNICATION_H */
    9 n  O& f& Y4 ^# V
  19. /****** Copyright (C)2021 闲人Ne. All Rights Reserved ****** END OF FILE *******/
复制代码

9 L) i! t# d7 q4 p% F* K2.串口初始化配置函数(源文件)$ v( R* |0 J9 t- ]2 f2 s3 k
串口初始化配置常规操作,大家可作为范例参考:! r' w! J. e6 c) f! N' U! t
  1. /**
    ' ?" `3 N7 U! E% d5 r' m! P
  2. ********************************  STM32F10x  *********************************
    2 p6 u! s$ G9 ^# m. d
  3. * @文件名称: serial_commuication.c/ G* R; Z, J6 [8 Q, ?2 ^$ r
  4. * @作者名称: 闲人Ne
      u7 ]! X. P# _
  5. * @库版本号: V3.5.0
    2 P7 D- V$ K, ]) e
  6. * @工程版本: V1.0.0$ [- |0 `+ d" b* U
  7. * @开发日期: 2021年1月17日2 j) H3 U' W2 v( S* x2 M
  8. * @摘要简述: serial_communication源文件
    / N4 z! \; P! M; G' h
  9. ******************************************************************************// r7 ]4 M- B( [! }- \
  10. /*-----------------------------------------------------------------------------
      \" l7 Q8 T! w0 I' I9 y" `
  11. * @更新日志:& T$ h% {4 z, l( i: n8 O
  12. * @无
    2 {- q/ N4 F6 D. x
  13. * ---------------------------------------------------------------------------*/
    7 Y1 a0 G  \+ J3 C2 \
  14. /* 包含的头文件 ---------------------------------------------------------------*/
    ' w5 A1 F5 [5 A. \% z& G0 x
  15. #include "serial_communication.h"
    ; [$ ^4 j# _! F  q2 D/ C
  16. #include "nvic_configuration.h"
    + D, a' f. l3 H- {
  17. #include "stm32f10x.h"
    0 S1 ~) @% ]; ]" ~$ V1 x! @
  18. /************************************************
    ' X" {: c! ?4 N7 ]3 ^. }. V0 y- @
  19. 函数名称:My_USART1_Init()) D9 k8 @& j1 M* T' _+ C
  20. 函数功能:初始化USART1管脚配置,
    7 S5 x. F: Z+ k
  21. 入口参数:无
    - M1 I0 Y  X, e( z% k8 L
  22. 返回参数:无
    + v. J" e; X+ b
  23. 开发作者:闲人Ne
    $ C( `% v' _( n: r$ W
  24. *************************************************/" b1 c7 `" o( A6 Z4 B* J4 g
  25. void My_USART1_Init(void)9 w& p1 H1 G* P; U0 Y( J, R
  26. {
    $ s3 N; L2 O' r3 [
  27. GPIO_InitTypeDef GPIO_InitStruct;
    * |2 l: S' |$ Y0 h" t9 m. g
  28. USART_InitTypeDef  USART_InitStruct;
    4 n; V0 e3 ^) W0 l* Y
  29. // 第一步,使能相关时钟
    / \3 r" B, ]8 c( Q2 w+ T
  30. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);      // 使能GPIOA时钟# s/ v6 E) X' m9 l0 H, q
  31. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);     // 使能USART1时钟% v0 L7 y1 c0 W9 ^6 }0 X
  32. // 第二步,串口复位
    9 k* b7 U# @& l: p; F
  33. USART_DeInit(USART1);                                      // 将外设 USARTx寄存器重设为缺省值,复位USART1
    1 J8 u( ~3 M4 A
  34. // 第三步,GPIO端口模式设置,PA9对应TX,PA10对应RX4 g( x: J" i+ ~) q
  35. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;                 // 复用推挽输出1 ~5 f: p$ E9 n+ ]
  36. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;                       // 选择GPIO引脚9,作为发送端. _! o  @  L7 y5 j6 P. P! p
  37. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;               // 随意设置,不重要
    4 ?7 O* S1 E: ~$ G4 ?
  38. GPIO_Init(GPIOA,&GPIO_InitStruct);                                          
    . ^4 u/ O5 p% R% }$ z& W
  39. GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;           // 浮空输入/ P. m, A/ A# h0 c
  40. GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;                      // 选择GPIO引脚10,作为接收端
    : t+ w8 f9 @( K" ]2 x
  41. GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;               // 随意设置,不重要
    ) G9 H# r" I" J' `# z- B/ c
  42. GPIO_Init(GPIOA,&GPIO_InitStruct);  % }7 B; N2 _8 t+ h  G
  43. // 第四步,串口1参数初始化,在电脑上进行串口通信时,串口调试软件也需按下述参数设置
    7 I" D) Z$ G/ [0 o7 l2 W& D
  44. USART_InitStruct.USART_BaudRate=115200;                                    // 波特率为115200
    3 I1 s+ k8 _5 s& p; B- [: a, {) q
  45. USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; // 不使用硬件流控制
    " F% p: @6 D9 Q% `
  46. USART_InitStruct.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;                 // 收发都使能
    ( a2 M8 B+ ^9 i4 I1 T5 M
  47. USART_InitStruct.USART_Parity=USART_Parity_No;                             // 不用奇偶校验位                           ! Z! i0 `, q" o) A1 O( P
  48. USART_InitStruct.USART_StopBits=USART_StopBits_1;                          // 设置1个停止位
    ' K3 J6 ]) {# I, N9 D
  49. USART_InitStruct.USART_WordLength=USART_WordLength_8b;                     // 设字长为8,因为不用奇偶校验
    6 W9 I1 b, ]4 c6 t' g
  50. USART_Init(USART1,&USART_InitStruct);  4 W- o3 k8 {4 n7 d; V% K
  51. // 第五步,初始化NVIC,开启指定中断   
    * }! R4 Z8 C+ i
  52. NVIC_Configuration();8 X/ r( _2 b5 `0 D& m/ w. U3 j, c
  53. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);  // 使能USART1的USART_IT_RXNE中断,RXNE是状态寄存器USART_SR的第5位,意思是接收中断
    ' ]4 g3 z4 G4 _; v1 `+ @5 t
  54. // 第六步,使能串口  7 m! v6 W  u5 Q" O) n
  55. USART_Cmd(USART1,ENABLE);                     // 使能USART1外设
    ! ~5 c* p: Y5 E3 j/ [$ z# ~8 G
  56. }' y( Y( v6 K0 P7 k2 s
  57. /****** Copyright (C)2021 闲人Ne. All Rights Reserved ****** END OF FILE *******/
复制代码

. q! F- w/ {# ?7 k0 V9 V3.串口1中断服务函数
  d- ^; L" F9 x$ b+ y通过上面可知,在串口1初始化配置时,使能了串口1的接收中断,因此需要编写对应的中断服务函数。
% p% D0 s8 w" Q
  1. /**********************************************************************************
    ; v7 o7 f1 W# U- Q; r' e8 Z  z5 }
  2. 函数名称:USART1_IRQHandler(); B( @7 J' u5 b8 K. c2 p1 ^$ b
  3. 函数功能:USART1中断,当STM32F103C8T6通过串口1接收到从电脑发来的串口数据时,将所收到的数据再发回去。! F! x6 U+ q5 c
  4. 入口参数:无
    1 B9 Q) t) ^4 b( v
  5. 返回参数:无- ~# \+ ?9 c" M% b
  6. 开发作者:闲人Ne
    - w  N: v& V- |+ m, ^! m
  7. ***********************************************************************************/
    + T8 ?5 j; d& A# w$ S$ X- H$ S
  8. void USART1_IRQHandler(void)      // 函数名称是由startup_stm32f10x_hs.s文件里定义的                                             
    $ Z" J0 l) i  v6 R: f
  9. {  ]4 j% E6 `* G' X
  10. u8 data;1 W. }% y4 S" U$ t( P- `- n! `4 A
  11. if(USART_GetITStatus(USART1,USART_IT_RXNE))   // 检查USART1的接受中断USART_IT_RXNE发生与否                             9 ]$ U& f  `7 J: f
  12. {' f5 ~% m! z1 P# e6 P; j' x
  13.   data=USART_ReceiveData(USART1);              // 返回USART1最近接收到的数据
      j0 D! H+ f: v; [1 V
  14.   USART_SendData(USART1,data);                 // 通过外设USART1发送单个数据                                          
    ) {: w* U' u) D3 E8 g
  15. }
    5 \5 t, a' G0 v, ^+ N. x
  16. }
复制代码

( @" f& k8 b& H' _( P: A# d4.中断优先级配置+ G  W% p. D) k2 a! C
既然有中断服务函数,那么必须先进行中断优先级配置:
3 T$ J" x7 X2 S- m( e5 |
  1. /************************************************
    ! Y$ L0 j+ o; e7 b2 E  x
  2. 函数名称:NVIC_Configuration()
    & Z. g5 G2 `1 I% C* q9 B9 S4 F
  3. 函数功能:中断优先级配置
    , ?: d5 s+ N* i. [0 S
  4. 入口参数:无
    8 T' F! H$ C3 V) o& _9 j( H/ G* I# ~
  5. 返回参数:无
    8 y' m9 L# t; L6 i
  6. 开发作者:闲人Ne2 J. {& H) V- d: ~$ y. F, s/ ^" ], N
  7. *************************************************/
    . X1 `$ G' f. @5 j; L7 X
  8. void NVIC_Configuration(void)! X; O; r2 b0 g- b
  9. {
    9 V5 _' ~5 z5 g, K( \! }; Y0 \
  10. NVIC_InitTypeDef NVIC_InitStruct;
    2 C6 l% j5 K$ s# K3 _+ Y  \
  11. // 串口1中断优先级配置
    : r% x+ |' x% t
  12. NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;           // 选择位于stm32f10x.h文件中STM32F10X_HD中的USART1_IRQn, u  s+ s4 l$ `5 @8 R
  13. NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;             // 使能上述中断通道6 N' G; W) M% s( @  N7 N
  14. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;   // 因为没有别的中断,参数可设0~3之间
    $ U4 i$ T# v1 x; M
  15. NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;          // 因为没有别的中断,参数可设0~3之间
    0 i2 ~: T' r! x; C$ d
  16. NVIC_Init(&NVIC_InitStruct);            
    ' r0 C7 }  y5 c( n/ {$ M
  17. }
复制代码
& Y' e" g6 q, s' L5 d
5.主函数
. U# p  Q9 i+ A, P" A6 W$ U
  1. /**
    $ q9 o1 T( b! }$ g2 I
  2. ********************************  STM32F10x  *********************************$ N! j/ Y9 p; a& e3 E5 I' }
  3. * @文件名称: main.c
    . {5 i, C' [+ e# K
  4. * @作者名称: 闲人Ne
    5 C/ C, q/ g, M$ ?- \7 \: b
  5. * @库版本号: V3.5.0
    ) P/ t* O) z# G- @
  6. * @工程版本: V1.0.0, v2 f" g1 x0 r' Y' d* j" t
  7. * @开发日期: 2021年1月17日% g1 O6 ~  y+ }
  8. * @摘要简述: 主函数
    " u/ I% x9 i3 `( ^' B8 M( H& `
  9. ******************************************************************************/* g# e4 w5 ?3 W& B8 y$ y
  10. /*-----------------------------------------------------------------------------) P- A" i6 E+ _: i+ m
  11. * @更新日志:
    7 {! N- V5 O# y; O
  12. * @无; M' T: ]; \5 K* t' q
  13. * ---------------------------------------------------------------------------*/
    $ }2 B/ m8 p; |7 u
  14. /* 包含的头文件 --------------------------------------------------------------*/
    ( X  O1 b  r% t0 T" W
  15. #include "led.h"
    - o) y9 {7 s- z! O1 G
  16. #include "sys.h"
    ; L5 O- s8 g  @) q$ \# q: Z
  17. #include "delay.h"! ~, h7 @9 d) @* x, M1 Q
  18. #include "serial_communication.h"
    6 R8 w* w3 j2 S& @% \
  19. #include "nvic_configuration.h"% A. n! `; s  o( I
  20. /*********************************************************************************6 i! F+ o4 T6 x
  21. 函数名称:int main()
    0 h  o- R- J# _3 o. \* z6 ^) {+ h
  22. 函数功能:主函数,LED灯每隔500ms改变一次状态,表示系统正常运行,串口数据收发由中断控制
    2 V  X7 ^' Q# x6 z* o( K6 r
  23. 入口参数:无
      }# X9 {0 H7 [8 \& u, ~
  24. 返回参数:int
    " D4 `7 o- w1 r  k& [& s
  25. 开发作者:闲人Ne
    + `2 e/ o  x7 [1 Q# Q; n
  26. **********************************************************************************/: w- e1 k+ [" o* F' a
  27. int main(void)
    ) B) }1 A% v' W3 |# M3 ?
  28. {" [) X0 w2 ^( i3 s& k9 I
  29. delay_init();1 E- Y  c- S* \0 _
  30. LED_Init();: \, D: z7 G, C+ T# E/ G" P( ^3 h
  31. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);      // 中断优先级配置                        
    ) q' P) Z- L1 G: N# n
  32. My_USART1_Init();! o" Y4 w# A7 j$ V' q" H
  33. D1=1;         // LED1灭8 y. v+ T4 \* m
  34. D2=0;         // LED2亮
    1 C6 Y: Q0 k5 R" [, ]# C
  35. while(1)
      P, V$ c6 E' z0 T1 X' W1 d, a
  36. {, a- N% s: D* h& A
  37.     D1=!D1;  [/ [. V# Q# T5 }% [
  38.     D2=!D2;   
    2 g; J1 F- v5 a4 e6 p
  39.     delay_ms(500);4 P+ p' D7 Y  B5 G) G
  40. }$ O; M4 C1 v' j7 n/ a# p
  41. }
    $ P& P, ^* ]9 ]. j/ m- c
  42. /****** Copyright (C)2021 闲人Ne. All Rights Reserved ****** END OF FILE *******/
复制代码
& e6 F% S% T8 W1 U7 }# Z6 y" P
2)针对LabVIEW上位机
+ D$ E2 e9 {* ?9 h; b0 w+ m" xLabVIEW工程可参考范例:Continuous Serial Write and Read.vi,该范例是最简的连续串口通信范例,在程序框图钟进行简单的修改:即在最后的While循环里添加等待1000ms模块(如下图所示)
+ ^" c! ?/ D4 d) Q$ C
% d" Y: a# Y, `; O, f6 M- Q1 J 2021011723140520.jpg
* F1 R8 `; K6 O6 B( i
/ Z+ \: h! X+ L0 N- D% x# u3 F回到该范例的前面板,硬件连接好后,首先先选择com端口(如下图所示:COM21),然后按照之前在STM32F103C8T6工控板上的串口配置参数进行配置,如波特率设为115200等,其他参数默认即可。
" I# D, v3 I/ X7 \( W1 F2 q. m3 s  O1 V! L5 Q
20210117231454263.jpg
/ O; N5 p4 c+ p1 M3 I1 J* Q! {3 F5 p. ?( b
实验效果
+ U$ N: `" h" [8 g运行前,将LabVIEW前面板上的Write和Read控件设为真(即激活发送和接收功能),先烧入STM32F103C8T6工控板的程序并运行,然后运行LabVIEW程序,运行结果如下图所示:4 X& V( O4 j; X1 y
7 z. ~& {* i  S: K/ H1 y) _
20210117232107262.jpg
  ~- c9 x4 u7 X- R8 o6 G. d" ?% c; ~
当Response显示字符串的控件每隔1000毫秒接收到一次串口数据时,则证明串口通信成功。# Y) b2 n! r$ q; f+ u

( m" b! Y! |6 I4 p7 q' N8 k经验分享
* b7 O" F$ J5 T2 [; }2 [0 A1.在进行嵌入式开发时,利用仿真器Debug程序是首选方案,当然利用串口调试助手查程序的问题也是工程师比较喜欢的手段;
7 o  ]5 n( e+ {5 X4 F& w2.可以利用LabVIEW,串口通信为一些嵌入式开发板开发定制化的上位机软件:如开发板的功能是采集一些实验数据,利用LabVIEW为期开发一个上位机软件,通过串口通信获取开发板采集的数据,然后记录,生成报告等。这对于实验室一些非标测试的项目,开发的成本是很亲民的~+ B" k# s; ?5 F' A" ~
————————————————
! k* q2 H, `, o( a0 J% H* `版权声明:天亮继续睡
( a5 L: D, }! R
  a5 d- }/ ?0 u; S
6 x7 e/ z9 ?& H  y1 V
赞 收藏 评论0 发布时间:2022-11-19 23:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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