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

【经验分享】STM32F103单片机串口通信带奇偶校验位

[复制链接]
STMCU小助手 发布时间:2022-3-21 13:07
     在调试Modubus协议时需要用到串口的奇偶校验位,但是平时用串口时很少用到奇偶校验位,网上搜相关的历程也很少,将自己写的串口奇偶校验代码分享上来方便以后查阅。, g3 d0 T. B( q4 v

% I# V4 z0 m/ V& Q" |       如果用库函数的话,添加奇偶检验位就很简单,在初始化串口的时候,将默认的无校验位修改为奇校验或者偶校验,同时将数据位设置为9位。* A, v" t6 U' _) n" @* l' g1 g4 l7 e
. Q/ f& \: I/ s" U1 Q& d
      串口初始化代码如下:
5 h! ~+ Q9 ~- X: ~; Z7 M+ |) E
5 ]$ d/ s4 J3 N1 Q; u
  1. #include "uart2.h") L; H4 g6 x* E/ @" y

  2. ) q; x9 T$ J* z% A
  3. #define  CHECK_NONE_ONE_STOP    0 //无校验位  1个停止位  1有效  0 无效 ) t1 P  d% v- {
  4. #define  CHECK_NONE_TWO_STOP    1 //无校验位  2个停止位  1有效  0 无效
    4 Y/ ?2 P6 j6 o  c* a- h
  5. #define  CHECK_EVEN    1          //偶数校验   1有效  0 无效 6 Q) Z5 y9 X  E- m6 D
  6. #define  CHECK_ODD     0          //奇数校验   1有效  0 无效
    - N9 C# G, w' S# h. M1 `! P

  7. 1 u" D" v1 {& V  c
  8. void  uart2_init( u32 baud )
    # d/ h6 h# |0 x* L) n: z
  9. {. F8 t% Y# P# R9 N4 j# G
  10.     GPIO_InitTypeDef GPIO_InitStructure;# T) q" E- G# ~$ T! X9 G
  11.     USART_InitTypeDef USART_InitStructure;
    . W* W  j- g+ N/ c( T! q
  12.     NVIC_InitTypeDef  NVIC_InitStructure;
    / s6 _: g/ M8 s- v9 n2 W" w% E  m$ R
  13. , @/ E8 U; E9 Y9 d, G: ]
  14.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );8 }, [/ K( j1 X+ u
  15.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE );' ]( R# l6 l. h5 o. _; x/ G; p
  16. ! U- X9 A6 j7 o
  17.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    6 F' M( r0 b) S" m+ U) d
  18.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;4 B( v* Q, X7 A! I7 O, I" z2 q
  19.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;0 a+ [2 H1 c3 L" R* n. B% `6 c
  20.     GPIO_Init( GPIOA, &GPIO_InitStructure );; c: E$ i& \1 ^# N" {4 P0 j! t

  21. * b; n( O. J9 D6 q
  22.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    3 B+ O2 Q* J) E( m/ Y- F
  23.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    - K4 b8 |' x& v* d9 n- Q
  24.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    $ e6 n- I. N) T' z( Y  N: k4 B! t
  25.     GPIO_Init( GPIOA, &GPIO_InitStructure );- J. Y3 W0 k" F
  26. " j* p+ M( ?; [; K7 h7 x
  27.     NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;4 D5 b: }7 Z) |2 ?6 _4 i
  28.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;: P% @/ p5 b; v: S8 \3 s
  29.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
    - ?/ J+ N/ ?! [
  30.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    ) T& |8 _) E, ?* d8 [* [: `
  31. & h  X6 j5 m; \# T
  32.     NVIC_Init( &NVIC_InitStructure );
    # m9 c5 W' ]7 y3 j

  33. $ A7 k  m0 V3 K& }7 J  B4 L# |: q+ s
  34.     USART_InitStructure.USART_BaudRate = baud;
    5 v* ?/ x% P" O
  35.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;                //数据位8位
    8 g6 n, z! T0 g0 q, T  _6 [- ?
  36.     USART_InitStructure.USART_Parity = USART_Parity_No;                                                //无奇偶校验位6 S/ {/ U0 u* [9 @& O
  37.     USART_InitStructure.USART_StopBits = USART_StopBits_1;                                //1位停止位
    - b; P1 H. n! a  S+ ?/ j5 E, N6 m

  38. 7 Z3 s: u+ }+ ?  n
  39. #if(CHECK_EVEN == 1)                                                                                                                                                                                         //如果定义了偶校验  数据位长度要改为9位' Y) B: p, e; _7 y) R/ D
  40.     USART_InitStructure.USART_WordLength = USART_WordLength_9b;
    . c9 l0 M0 S% M2 B$ j. ~
  41.     USART_InitStructure.USART_Parity = USART_Parity_Even;
    3 e! L# u* c2 e/ ]% G8 ^  ]
  42. #endif0 m4 a6 U. Y! K" w( I% |  `& |
  43. 6 V9 _' V% O4 I/ z& G1 c; W
  44. #if(CHECK_ODD == 1)                                                                                                                                                                                         //如果定义了偶校验  数据位长度要改为9位  Y$ c& A0 ~* G9 k9 i2 E- m
  45.     USART_InitStructure.USART_WordLength = USART_WordLength_9b;( B& ]1 u3 i+ t: O
  46.     USART_InitStructure.USART_Parity = USART_Parity_Odd;. A; C  q' O( p* I, F1 C/ D
  47. #endif  }2 ^2 ^0 h) G! f0 [/ @+ s
  48. + z: D# C% e+ F- h" D( {# n7 A
  49. #if(CHECK_NONE_ONE_STOP==1)                                                                                                                                                                //停止位为 一位
    : _# {6 T0 _; w& H
  50.     USART_InitStructure.USART_StopBits = USART_StopBits_1;
    ' }$ a) k" u' b; q, {
  51. #endif3 j( E; q& A. ]  c) |$ W8 T6 {

  52. / z4 |$ L5 a, g  @/ u5 T  m% e
  53. #if(CHECK_NONE_TWO_STOP==1)                                                                                                                                                                //停止位为 两位                                                                                                                                       
    3 X3 N$ Q5 I6 d7 I! h
  54.     USART_InitStructure.USART_StopBits = USART_StopBits_2;* H% t& Q6 r; r  T
  55. #endif
    * v2 q, b9 X/ F5 }5 o: ~
  56. 9 `' {. E, n, w# }: L6 c6 k- p
  57.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    & U* i. D) e+ L& i3 }; {. E* r
  58.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;0 p5 S" n) R5 N% J

  59. & X4 k/ c1 W  j  O1 O% O
  60.     USART_Init( USART2, &USART_InitStructure );7 V( Y8 H1 C0 t& P+ |3 w# g

  61. 4 Q9 F' [: h' `0 l
  62.     USART_ITConfig( USART2, USART_IT_RXNE, ENABLE );
    0 S! Q( d. B3 |" w; g
  63.     USART_Cmd( USART2, ENABLE );
    5 L+ l7 D  g8 w& a7 m

  64. - V+ S; J* V' j
  65. }
    # {8 [* p$ x1 C, Q: p8 N) M6 `; D
  66. + }3 h0 g" }  \; S$ x
  67. void USART2_IRQHandler( void )" X# f- g) u: w: D5 o8 ]
  68. {1 [2 O7 W& E/ d- j9 V; c
  69.     u16 tem = 0;$ b3 s- X: G0 K5 j9 n1 R& \
  70.     if( USART_GetITStatus( USART2, USART_IT_RXNE ) != RESET )
    * R+ \' ^: e( f3 s
  71.     {& m& b3 Q% u# \
  72.         tem = USART_ReceiveData( USART2 );; l$ X) [3 B4 Q; v* K
  73.         USART_SendData( USART2, tem );
    0 D  a& A- D) f) Y
  74.     }
    , q" W) I  L+ g5 v

  75. ) {9 U  m* X( y& }: |( X$ m1 \: b
  76. }
复制代码
8 _' q8 M. \2 V7 y
通过宏定义来设置是否使用奇偶校验位,停止位为1位还是2位。如果使用了奇偶校验时,要将数据位设置为9位。设置好之后就不用管了,具体校验工作由硬件来完成。8 X' ?8 Y: @+ {- `! J/ Q7 b
' x" K7 L$ u% `# D4 h- m. l4 a
在串口中断函数中实现的功能是,将串口2接收到的数据通过串口2发送出去。
8 {$ W; P) L, R, H" Y4 \. r: G! w) r% f5 I/ |7 e6 B. f5 t1 o
在宏定义中设置为2个停止位,偶校验。
* A; q% E8 ]. F- l) U2 S
% Z' `, p7 u- c# c! _& e) h' d MP9O(P}C2QJ0@KQN(D]50FF.png   A! o) V- b3 K% {1 ^; T
2 A! W) [. K$ H  ^. x
串口测试效果如下:* s) U! ~6 W1 m* ^( {2 ]# F
- X8 {: r1 l  S" A# B
NBD~AV2W5MHGH7]5$RUQA)4.png
! ^: _9 L" P: e+ D  U; m) W
' F! m# l6 s! U* P. D% C如果串口助手设置和单片机发送不一致时,接收到的数据就为乱码。' T- y% _% K5 R6 e; W4 N- ^) i

" R/ P$ p( ^& r9 R! e+ g _91G6JWSIMDTH[~K2{ASC8E.png
: X& f! E6 Z; T3 N  x8 Q$ K2 Z
2 c) B6 Q; J! S0 `
( o. ]' \7 j7 ^7 n8 m
赞 收藏 1 评论0 发布时间:2022-3-21 13:07

举报

0个回答

所属标签

相似技术帖

官网相关资源

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