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

【经验分享】STM32串口中断实例二

[复制链接]
STMCU小助手 发布时间:2022-2-6 22:00
  1. int main(void)
    1 v& Q1 S- n* }/ C6 E* B& w2 b" P
  2. {
    - c; f  r) Q( ~0 x& q% ^1 C
  3.     uint8_t a=0;//LED高低电压控制
    * x) N& j2 K) Y

  4. 7 r+ \. ?& ~) [1 p  E% @; a- D
  5.     /* System Clocks Configuration */
    1 b7 K! A( h5 b9 t3 P
  6.     RCC_Configuration();                                              //系统时钟设置- [5 O0 m) h; ]+ C
  7.     /*嵌套向量中断控制器
    4 J$ X; E! G* f& q
  8.         说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */
    - {7 L$ [4 O4 O
  9.     NVIC_Configuration();                                              //中断源配置% M$ `. ^! c' W! r
  10.     /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。
    - [# t+ B, Z% f" {9 N% J$ u
  11.     在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B, 因此要对这个端口的时钟
      t4 c" _. B8 e; m1 Y0 ~/ C
  12.     进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/
    4 G4 U6 K9 _3 s
  13.     GPIO_Configuration();                                              //端口初始化+ H5 L6 H1 m2 _( e5 f
  14.     USART_Config(USART1);                                              //串口1初始化
    9 I4 A/ X2 r' ?
  15. ( q! Y2 i# N! `' a) f) J0 ], v
  16.     while (1)/ X  D- ?5 l) ^; `- u1 K7 {; F# E6 w' b+ S
  17.     {
    3 T5 }& A5 p$ v3 @
  18.         if(rec_f == 1) ; L" h8 i# j5 |( O4 k
  19.         {   
      D1 J% D. A  D6 N6 R, `
  20.             //判断是否收到一帧有效数据                                             
      S5 B" h5 M! O$ l' O
  21.             rec_f = 0;1 G" F5 Z( q  D% Q, Z5 s% F

  22. 4 B# R; w2 _0 N' X1 R$ j
  23.             for(i=0; i<sizeof(TxBuffer1); i++) //发送字符串
    # {; i9 j. \1 E! ]& b2 W
  24.             {+ j+ m  i* P7 Y( {! X. l8 s
  25.                 USART_SendChar(USART1,TxBuffer1[i]);
    2 H7 S8 G2 z2 P7 s7 e
  26.                 Delay(0x0000ff0);5 @3 [, _+ ?( M$ N: {% k7 B
  27.             }/ ?! q( y# P$ [5 n# j4 g
  28.             /*for(i=0;i<TxCounter1;i++)//发送字符串5 v- m5 Q/ T( s* L3 W
  29.             {* x: A0 H# g: c2 k+ f# b2 G! e
  30.                 USART_SendChar(USART1,RxBuffer1[i]);
    7 }- O" B+ r' C( l, y6 c" ?+ m: D
  31.             } */
    6 M" v* k0 k* B% G
  32.             if(a==0)
    3 Q. H/ \% I6 b( o: Z% U$ b
  33.             {
    7 o8 Z# j& K, n# o
  34.                 GPIO_SetBits(GPIOD, GPIO_Pin_2);    //LED1  明暗闪烁; \/ v3 c, N. f1 B: b
  35.                 a=1;9 G1 C* T* A: S) X" j0 S* W% \1 [
  36.             }) h  _7 B9 V9 {( z$ X
  37.             else - B/ T; S- X! t6 T8 K" e7 \2 v
  38.             {; j2 h$ Q( y" R3 S! J4 n' x
  39.                 GPIO_ResetBits(GPIOD, GPIO_Pin_2);7 c4 `) d. {) J: T: y- p
  40.                 a=0;
    * z8 f8 U3 B; j0 k
  41.             }
    . k) q6 c0 d1 L. _' J% q
  42.         }1 R9 L* }% n) t7 m& |" N+ h
  43.     }2 F3 G% X& U, g. m  j/ F
  44. }
复制代码
main函数如上。
相关变量
  1. uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";
    ' G  s( T. ]4 F3 W
  2. uint8_t RxBuffer1[], rec_f, tx_flag, i;( P0 v$ r. q- S/ q

  3. 4 \7 ?$ q% `, k9 t/ Q( s
  4. __IO uint8_t TxCounter1 = 0x00;8 Q1 m8 ?: i4 F" `3 T3 a5 [
  5. __IO uint8_t RxCounter1 = 0x00;0 Y: H$ I  c$ a2 A, r3 e1 A; f

  6. 4 ]& z; J- ~9 R9 K# s6 r; e
  7. uint32_t Rec_Len;
复制代码

# M$ O! q; t7 A0 s! d
串口中断函数配置如下所示:
  1. //--------------------------------------------------------------------------------------
    , ^; f8 L3 y! l+ h, }" w/ u" i; L
  2. void USART_SendChar(USART_TypeDef* USARTx,uint8_t data)
    % r2 H1 o( @3 I( s4 D1 X- I/ e
  3. {
    $ w, J. Q. d1 n; q7 }
  4.     USART_SendData(USARTx,data);
    + i! ~/ X2 b7 h1 @8 g
  5.     while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
    / P- V% M8 }/ s* q6 i0 T: I
  6. }
    & ^4 {  S+ ~5 e- Q/ b) A9 ^
  7. //--------------------------------------------------------------------------------------
    : S/ N5 @7 L3 \# V1 Q
  8. void USART_Config(USART_TypeDef* USARTx) 3 r: P/ `9 ^2 O: k
  9. {5 q' l! _" b" ?- @3 z7 }$ s: z- J
  10.     USART_InitStructure.USART_BaudRate = 19200;                        //速率19200bps, r; R$ b' |7 g) O- l: E* d! C/ x
  11.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;        //数据位8位
    + i8 Z" |5 Y% H0 Q2 J( W- _
  12.     USART_InitStructure.USART_StopBits = USART_StopBits_1;            //停止位1位
    7 S3 j% r- S' y& h( P$ ~
  13.     USART_InitStructure.USART_Parity = USART_Parity_No;                //无校验位/ P' f) n  e6 s3 b% I- o& K
  14.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //无硬件流控
    ; M3 F4 N+ \! B* e# j* o( B% t4 T; M4 w
  15.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                    //收发模式$ s& g" q) o4 m; c5 J
  16. - E5 [$ \* m+ j" [. v! Q' }
  17.     /* Configure USARTx */
    5 X, t6 c( s9 u5 ?0 e" l
  18.     USART_Init(USARTx, &USART_InitStructure);                            //配置串口参数函数
    1 r5 ^7 n( }" f! Z

  19. # Q( z' l* j, C2 n1 U6 N6 N2 o
  20. 7 T4 y& ?6 o% C. h9 J" D
  21.     /* Enable USARTx Receive and Transmit interrupts */
    ' |( g% c; p- B3 L/ Q; q, q
  22.     USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);          //使能接收中断
    4 M, B& s: H& X$ o3 K1 x; M
  23.     USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);            //使能发送缓冲空中断
    ; R9 {+ k0 O5 _- D* i
  24. # ?+ I* ?1 T+ k9 L" D
  25.     /* Enable the USARTx */' f) P* J$ U- x) O1 i, _( C1 Z
  26.     USART_Cmd(USARTx, ENABLE);
    $ s' D! z+ A8 v# F1 K
  27. }
    / X' ^9 g7 E5 @) t
  28. //--------------------------------------------------------------------------------------9 q5 \9 k% I; R$ {* o
  29. void Delay(__IO uint32_t nCount)
    - u: H9 v- W% l1 t0 o: p' z( D" S% N
  30. {9 E" Y' w$ z( q8 P( K) K
  31.     for(; nCount!=0; nCount--);' ]' B9 M7 J% R
  32. }& t9 X$ h6 I. v5 T
  33. /*--------------------------------------------------------------------------------------
      Y8 e! [+ b# E+ d7 f+ Z! }+ |
  34. 系统时钟配置为72MHZ+外设时钟配置*/5 D: q. j+ o3 a! b/ y/ E% p3 m
  35. void RCC_Configuration(void)
    4 u. L9 j& s2 W7 j: G* |' I
  36. {
    & e: b! }& w' C% r+ S
  37.     SystemInit();5 w6 x3 q. }* H' `' z$ J3 A* p
  38.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOA, ENABLE);2 e, ?2 O4 ?! \
  39. }7 A$ ]2 A$ L. G6 ]; M. G/ b
  40. //--------------------------------------------------------------------------------------6 `. B, i2 L6 t& v
  41. void GPIO_Configuration(void) / B4 Y0 ^* j! m
  42. {" K) s/ @* K; S+ w* H9 m+ ~1 L/ \: [
  43.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                     //LED1控制--PD28 N4 [5 [; O! l, o7 h+ F
  44.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;             //推挽输出% @. D( U/ t+ {( G& }5 r
  45.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;) [8 [8 R$ U2 D
  46.     GPIO_Init(GPIOD, &GPIO_InitStructure);
    " l9 w+ Z) y: i# s- m* S
  47. ( b3 ?5 z" p% t0 T4 u1 J
  48.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                      //USART1 TX0 g% x* s, w& K! b
  49.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;             //复用推挽输出3 n, \  {/ C- U9 J: i/ J" b; p9 H' ^
  50.     GPIO_Init(GPIOA, &GPIO_InitStructure);                     //A端口2 K/ t  P3 Z8 l

  51. : B# w  Y5 f4 `8 z
  52.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                  //USART1 RX
    ' f5 {. o7 k; t
  53.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //复用开漏输入
    & N" w3 ~' E& l6 e9 E1 G( N
  54.     GPIO_Init(GPIOA, &GPIO_InitStructure);                      //A端口
    5 B4 ^0 J, `4 k0 p
  55. }5 [+ y  `! D2 c! H# O
  56. //--------------------------------------------------------------------------------------
    0 Y% o: c0 L! E* d( U; J
  57. void NVIC_Configuration(void) 9 C' l: j- r6 \9 z' |! r: y
  58. {
      _9 M; m& r3 u8 j. g
  59.     /*  结构声明*/) }$ i+ h$ ]8 O2 H: {% ]6 S
  60.     NVIC_InitTypeDef NVIC_InitStructure;
    , E# k9 H; z; w  H

  61. 1 g6 R  h; W3 }- ]  r+ w, G  D
  62.     /* Configure the NVIC Preemption Priority Bits */
    7 Y* L7 ^4 w8 @4 C
  63.     /* Configure one bit for preemption priority */, r% u' G5 b. k2 P
  64.     /* 优先级组 说明了抢占优先级所用的位数,和子优先级所用的位数   在这里是1, 7 */
    0 X9 g7 j+ s; w* `1 ?3 h, x0 B( S
  65.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);8 K" A7 ^# j2 w% \; `, w, X
  66. 3 F+ d8 e9 F, e+ y
  67.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                     //设置串口1中断
    1 a( k% O+ I1 d' W
  68.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;             //抢占优先级 0
    : b5 B; x6 A3 j' I
  69.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //子优先级为03 w3 `; B1 p- r  [, i* k
  70.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
      f* R, S8 J8 j0 n2 N" a6 x' _3 ], ~
  71.     NVIC_Init(&NVIC_InitStructure);4 V; d6 F' S# x" S' l' a' O6 a$ U
  72. }
复制代码

+ A& m. q/ v2 X/ d# X# F& \
在中断服务函数中编写usart函数。
  1. //串口1 中断服务程序3 o. n& Y6 v* L$ n) N
  2. void USART1_IRQHandler(void)      2 Y0 P+ V. x0 Z& R& a: V3 q
  3. {$ Q: x" w' p6 _% U& l2 p
  4.     unsigned int i;" Y4 ~9 Z* e# c
  5.     0 F5 V! Q1 c7 P' C$ V
  6.     //判断读寄存器是否非空
    0 e# ^' G5 G3 E, P5 F0 W4 z3 c  Q
  7.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)      
    # w: j  A* Y" g. U1 Q" l
  8.     {5 b5 U6 l8 b2 r' I5 ~0 B( l/ H
  9.         //将读寄存器的数据缓存到接收缓冲区里* V7 Y) q0 S" o, Z* P. `
  10.         RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);   ! h9 M1 b0 ~( w$ R& S4 y

  11. ; s' E' i5 p- H" i
  12.         //判断结束标志是否是0x0d 0x0a
    ; Z0 k) p4 \6 Y% W% K
  13.         if(RxBuffer1[RxCounter1-2] == 0x0d && RxBuffer1[RxCounter1-1] == 0x0a)     / _0 ^& J/ f9 f$ Q4 e+ {4 O
  14.         {) \) i4 Z' k$ `& e
  15.             for(i=0; i< RxCounter1; i++)
    2 I6 v- ^2 E, ?  C, s6 q
  16.                 TxBuffer1[i] = RxBuffer1[i];          //将接收缓冲器的数据转到发送缓冲区,准备转发3 t# _3 G, j" k7 w: ]; p
  17.             & H  o# {- b& Z( e2 k* S" c; y
  18.             //接收成功标志" t, s' S9 S/ x8 O
  19.             rec_f = 1;            
    : A0 Y6 p' G& ?0 Z, D# x( }  h
  20.             5 j2 l  \3 W6 e9 \
  21.             //发送缓冲区结束符4 O: C/ {" T# B
  22.             TxBuffer1[RxCounter1] = 0;                                             & Z1 H3 X8 J3 s
  23.             TxCounter1 = RxCounter1;
    3 j# j  [; y4 Z; D9 r
  24.             RxCounter1 = 0;
    + J: f% `" B3 Y: Y' F0 f2 K
  25.         }
    . o* v2 C' L  e
  26.     }. Y4 I% K* w; m5 d
  27. 9 O# o! N8 T- J% G9 t: k
  28.     //这段是为了避免STM32 USART 第一个字节发不出去的BUG
    6 d3 z5 P+ k/ ?  n6 m2 T; R
  29.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                  
    , j$ u: ^' h& m* H
  30.     {$ q2 @6 I4 F) y, a4 t+ |& P/ D+ ~
  31.         //禁止发缓冲器空中断,
    9 o. D+ z5 S4 [) h- D
  32.         USART_ITConfig(USART1, USART_IT_TXE, DISABLE);                         # E8 D3 L3 U+ d6 ~/ V  `; F
  33.     }: A/ E& b! X8 W! ?. |

  34. . W% G. Q6 N3 r7 m8 {3 W
  35. }
复制代码
* C, n, ]- m. I& U

/ D8 p5 C. t$ G7 v" \
运行结果如下,在发送去不填写任何字符,直接发送,显示RT Interrupt Example: This is USART1 DEMO,说明前三个字符已经被占用替换了。
8 y0 E; y! S1 ~4 A* {( @$ X
216878-20181003142931280-1140176473.png

  z, E( s  N# P8 U7 c) l5 H% `
赞 收藏 评论0 发布时间:2022-2-6 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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