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

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

[复制链接]
STMCU小助手 发布时间:2022-2-6 22:00
  1. int main(void) ) ?% ^/ Z$ @2 x* a2 [
  2. {# v  Q) a; C' e$ Y% T: f
  3.     uint8_t a=0;//LED高低电压控制
      x' b( O1 I4 c0 M- `2 \: O3 N3 ^( h

  4. ! C6 p! ~( _# M, W( W+ @' D
  5.     /* System Clocks Configuration */
    0 q4 F/ ~1 _4 S8 Q& I; T  n( }% ^
  6.     RCC_Configuration();                                              //系统时钟设置
    + x2 g& W8 ~: U* ^% n) X% U
  7.     /*嵌套向量中断控制器- n& w) h# x/ c3 G/ [
  8.         说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */! c( a$ d6 k! w7 h7 N7 k, L
  9.     NVIC_Configuration();                                              //中断源配置
    4 z- I% w( w: ~* a6 _
  10.     /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。
    " U- W. x( c3 z) B3 T! C* q
  11.     在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B, 因此要对这个端口的时钟
    4 I; x) i5 E& P! w9 h+ _: W
  12.     进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/* a$ o/ p0 N/ P) y
  13.     GPIO_Configuration();                                              //端口初始化! O, s% J$ U5 L3 J6 e5 F6 F. m6 a
  14.     USART_Config(USART1);                                              //串口1初始化0 Z0 {# |. h, ]& D$ B6 O. M2 v

  15. 9 T8 s7 I5 y" j; w- ]
  16.     while (1)
    & B: Y4 Y! M7 p7 }
  17.     {
    6 B% X+ Z) P* c2 i- l6 \5 s
  18.         if(rec_f == 1)
    " K( D, r3 l+ _& k* o
  19.         {    $ U# Q2 ]" B: ?: [$ l' Q
  20.             //判断是否收到一帧有效数据                                             " Q8 B  m! L- E2 x! D$ z
  21.             rec_f = 0;
    # y! f! u; @4 v, R8 ^& Z  H- S
  22. 0 k7 y4 T4 Q: V, L1 x
  23.             for(i=0; i<sizeof(TxBuffer1); i++) //发送字符串
    % R& a( P. j  h4 }8 F5 D: c
  24.             {+ o3 p# ]4 S( Q$ Y3 j. c4 z
  25.                 USART_SendChar(USART1,TxBuffer1[i]);* X$ n+ n) ^2 u* m" o$ Z- F2 ^
  26.                 Delay(0x0000ff0);7 X) _" Z( w! P% s9 p
  27.             }
    7 N- w0 b2 w! X6 e5 R
  28.             /*for(i=0;i<TxCounter1;i++)//发送字符串
    7 b( C" w3 l1 i/ ^
  29.             {; t5 @- F: y0 o; Q/ X
  30.                 USART_SendChar(USART1,RxBuffer1[i]);* a! x) H* K5 U. T6 m
  31.             } */
    : q  i# Q8 E/ p1 Y# c2 V
  32.             if(a==0)
    5 y9 r# [9 F$ z1 y# h
  33.             {
    $ R1 A" e2 J( b( j7 j: G0 {
  34.                 GPIO_SetBits(GPIOD, GPIO_Pin_2);    //LED1  明暗闪烁5 I( j$ g+ V& w) V
  35.                 a=1;+ U$ d8 t9 p0 m1 V& ?0 Z/ n; y- T
  36.             }
    ; s! d$ L& L- D
  37.             else 5 ~9 \8 o/ I5 z4 [. ^+ E& j
  38.             {
    3 W/ n+ p+ f' o/ I( m$ d* A( w$ Z
  39.                 GPIO_ResetBits(GPIOD, GPIO_Pin_2);# p9 G) w% B* T
  40.                 a=0;
      n1 w/ D3 ]/ f5 |5 e
  41.             }
    4 M7 \5 ^8 T/ U! \
  42.         }
    ) X5 b1 {" R0 }& T6 o/ g
  43.     }
    $ ^- a0 z- R' h+ {8 u
  44. }
复制代码
main函数如上。
相关变量
  1. uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART1 DEMO";
    , R0 b! o6 X7 o, n& y
  2. uint8_t RxBuffer1[], rec_f, tx_flag, i;
    + j$ ]& @% W. |  p5 A, `# b
  3. & v7 X' E  G2 B0 J% N
  4. __IO uint8_t TxCounter1 = 0x00;( f& |/ t6 P2 z/ D
  5. __IO uint8_t RxCounter1 = 0x00;! t2 m) C7 m3 c. g6 `$ Y% [2 B
  6. 0 {5 S2 K& q3 s5 x4 ~3 ?$ x
  7. uint32_t Rec_Len;
复制代码

  d# z0 a. f/ d! j
串口中断函数配置如下所示:
  1. //--------------------------------------------------------------------------------------2 h6 e# f7 a& C" Q; i: v
  2. void USART_SendChar(USART_TypeDef* USARTx,uint8_t data)
    : ]  y3 L: H; O
  3. {6 D$ s7 G/ C3 G# g8 l
  4.     USART_SendData(USARTx,data);. B: a5 w- q+ i  @- j* ^6 F: j
  5.     while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);
    - U9 [% G& L8 \- W  n
  6. }' Z; V+ k: S3 f1 o" q
  7. //--------------------------------------------------------------------------------------" O8 \1 w- j2 p+ ?1 p% ^: ~
  8. void USART_Config(USART_TypeDef* USARTx)
    * m7 }- s% z7 }& G) V) |9 V! b8 G
  9. {
      s# t4 z0 l; x0 {" o
  10.     USART_InitStructure.USART_BaudRate = 19200;                        //速率19200bps1 {1 N- \5 u+ T, ?& N; @5 L) R
  11.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;        //数据位8位
    / e8 V  T' h. R8 J( d5 i
  12.     USART_InitStructure.USART_StopBits = USART_StopBits_1;            //停止位1位+ n8 f: h6 r5 G' w3 M5 z
  13.     USART_InitStructure.USART_Parity = USART_Parity_No;                //无校验位
    + W+ B) q' o3 U+ T1 ]
  14.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;   //无硬件流控
    6 @& I3 K% |2 p  }# m
  15.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                    //收发模式" Z) g2 D- ?& Y( Y" s

  16. " Q" G+ X2 p' l6 r0 r2 @
  17.     /* Configure USARTx */) l, W/ _5 m% ?8 f& P8 y
  18.     USART_Init(USARTx, &USART_InitStructure);                            //配置串口参数函数7 h) x% ~7 u+ P+ i3 s0 U
  19. 2 \) f% d8 g( O
  20.   d* P7 y& D, k: S
  21.     /* Enable USARTx Receive and Transmit interrupts */# e! k+ Q0 _5 O% `+ o% {
  22.     USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);          //使能接收中断
    - J0 [; W3 z) S1 k
  23.     USART_ITConfig(USARTx, USART_IT_TXE, ENABLE);            //使能发送缓冲空中断( b/ P" c$ {' Y" y4 ?

  24. 7 p5 a0 ]( R; Q5 E
  25.     /* Enable the USARTx */& E! D, C* O# [+ y
  26.     USART_Cmd(USARTx, ENABLE);
    5 k& f! D( n" y$ h8 u2 e7 P( Z
  27. }- e: Z6 v4 B0 O' l7 {
  28. //--------------------------------------------------------------------------------------% h. M: e: U& I6 S+ M; M! F
  29. void Delay(__IO uint32_t nCount)
    * d4 i: k. j4 J$ ]: M5 s- k% M7 E5 J
  30. {" L4 W: F' \& C- a4 L1 a
  31.     for(; nCount!=0; nCount--);7 J7 t6 t6 n" t. c7 g0 i) }* a
  32. }
    , \/ s3 O0 ?. U. W1 k4 @; O, z
  33. /*--------------------------------------------------------------------------------------7 M. D  l6 m3 c) d1 ^9 W" L
  34. 系统时钟配置为72MHZ+外设时钟配置*/$ ^( a$ @( P7 ]9 ]
  35. void RCC_Configuration(void)
    . g! W+ s4 B) Q4 |* R1 z
  36. {
    $ N4 M' x. V' D. w& A; z7 E
  37.     SystemInit();5 d5 C- t& x- g6 l
  38.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOD |RCC_APB2Periph_GPIOA, ENABLE);
    # w* j( ]" E5 X+ \3 M
  39. }2 G" Z1 p, k( _: {) v% L2 _
  40. //--------------------------------------------------------------------------------------
    4 }2 {. c3 f" |% g, ^* M
  41. void GPIO_Configuration(void)
    ( l8 u2 A9 E# H* o0 K- w
  42. {
    ' F9 ~8 y! b$ X7 A) S* F
  43.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                     //LED1控制--PD27 d# ?) B( }5 [6 k
  44.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;             //推挽输出) Z8 G0 ?9 s4 w: L
  45.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    " [/ u- V$ @) y7 O0 `, E0 ~+ h
  46.     GPIO_Init(GPIOD, &GPIO_InitStructure);
    9 l1 m( t- F$ \. J# ^) B) b2 v

  47. / m" ]9 V0 W& C# V% E9 S. F
  48.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                      //USART1 TX
    - ^# `  j  e: S% W; v& J
  49.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;             //复用推挽输出
    " p; W! G# m* `
  50.     GPIO_Init(GPIOA, &GPIO_InitStructure);                     //A端口
    5 E2 N& f( Y6 z0 V( H7 p

  51. . ^/ v& ?) Q5 l$ o' d
  52.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                  //USART1 RX. m' Y& e" ~6 a7 K- y  d( g# h
  53.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //复用开漏输入
    & Q' s! L3 K3 g3 ?& o
  54.     GPIO_Init(GPIOA, &GPIO_InitStructure);                      //A端口" W! S" u& j2 A- S. o, D: i
  55. }( L: `( B- N% ]+ d4 Z/ {
  56. //--------------------------------------------------------------------------------------
    # Y: q% {. z' p, }5 e8 z3 r0 L9 H
  57. void NVIC_Configuration(void)
    " T# L) p# W" S$ o. j3 z! S" o
  58. {
    5 U% k0 a: N3 O% X" W+ j6 m
  59.     /*  结构声明*/
    / @, @) J+ r, E, R' w% ~9 T
  60.     NVIC_InitTypeDef NVIC_InitStructure;
    0 U( }& C: D7 F7 I
  61. 1 F& t, f" X4 n/ A" N
  62.     /* Configure the NVIC Preemption Priority Bits */
    & V  o+ G, ~! |
  63.     /* Configure one bit for preemption priority */
    ' |' d; J6 H6 O' M
  64.     /* 优先级组 说明了抢占优先级所用的位数,和子优先级所用的位数   在这里是1, 7 */( u& W% r' X9 G
  65.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);+ {# ]9 U3 A: r) h, @* _

  66. 9 n$ ]6 {  |. T& g$ N9 n
  67.     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                     //设置串口1中断6 x* o' d( [/ p5 }; e) x0 E4 X$ q
  68.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;             //抢占优先级 0
    5 J# X; g/ y( r  a
  69.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                //子优先级为0
      \& o, q2 C' f
  70.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                    //使能
    " n+ H. v- B  C1 r9 L0 r& f
  71.     NVIC_Init(&NVIC_InitStructure);; r( u8 Q- ?6 m
  72. }
复制代码
) S2 J8 }; U3 S' M( b
在中断服务函数中编写usart函数。
  1. //串口1 中断服务程序: ^6 h2 h8 P! {. F
  2. void USART1_IRQHandler(void)      0 x  _4 C) U$ P5 J) p" k: n
  3. {
    5 E1 H* p' B. Z+ F: `& m3 L8 ~
  4.     unsigned int i;1 g0 Y4 u; {& B! [1 n; v
  5.     3 c) k" o! u6 y7 [
  6.     //判断读寄存器是否非空. _3 G( S8 P  g1 D9 a
  7.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)       3 W) C- S% F6 W9 L, H3 F
  8.     {( T5 Q; D0 S: J4 d+ [
  9.         //将读寄存器的数据缓存到接收缓冲区里
    . X" Q% ^. V( @% f% B
  10.         RxBuffer1[RxCounter1++] = USART_ReceiveData(USART1);   6 A2 R7 Q' `  V0 w

  11. 6 e" Y1 H9 `! A+ ~' c3 G, d6 c
  12.         //判断结束标志是否是0x0d 0x0a
    7 Y: f! P5 ^) J' K5 v
  13.         if(RxBuffer1[RxCounter1-2] == 0x0d && RxBuffer1[RxCounter1-1] == 0x0a)     8 N( j& \: A- e) _0 {" A
  14.         {2 h$ C& W7 n& s% i' w. d8 u
  15.             for(i=0; i< RxCounter1; i++)
    7 K0 K. ]( U- ]5 C/ n$ J
  16.                 TxBuffer1[i] = RxBuffer1[i];          //将接收缓冲器的数据转到发送缓冲区,准备转发& {9 j7 t* c$ e: |
  17.             
    ! m. r1 G: x9 {9 o
  18.             //接收成功标志$ t' _/ e- u; h; X/ F, @8 I$ `+ i3 q
  19.             rec_f = 1;            
    ) u. v( L$ ^3 [- ~: i
  20.             
    ; K, T" x, L  n. ^% O, ?! a' R
  21.             //发送缓冲区结束符/ Q% s- [2 o/ K( P! g7 q7 n7 h: n& z
  22.             TxBuffer1[RxCounter1] = 0;                                             
    : `0 b7 f% f; H1 c; g0 O% Y' h* @+ H+ j
  23.             TxCounter1 = RxCounter1;
    5 D* B* U- V# Y& i
  24.             RxCounter1 = 0;
    $ S  [/ |0 P" b! g1 W, `0 X% P# w
  25.         }5 R0 G( z. X( H& B# E* R
  26.     }
    % w6 q2 T1 A7 }" L0 D
  27. 2 C0 R) Y2 w: P9 L
  28.     //这段是为了避免STM32 USART 第一个字节发不出去的BUG3 F8 K8 [6 ~6 {- A
  29.     if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)                   ; E; m' O4 @" T4 F% `
  30.     {1 d, C. R' Q0 I. _2 x6 [; S
  31.         //禁止发缓冲器空中断,7 ?: S: u  o6 M# {# _
  32.         USART_ITConfig(USART1, USART_IT_TXE, DISABLE);                        
    7 n4 ~4 G- n7 ~+ I! D! |6 G
  33.     }
    . G  l- U% D' x# W* A
  34. 2 d8 }* R# |5 z* |2 a, a! i6 d' ]
  35. }
复制代码
& q, R  R4 T1 D8 R6 d

, x% d! c8 l) n
运行结果如下,在发送去不填写任何字符,直接发送,显示RT Interrupt Example: This is USART1 DEMO,说明前三个字符已经被占用替换了。
" x  X, g9 p! _! P. k5 z9 I
216878-20181003142931280-1140176473.png

& Q! E' q1 v  R
收藏 评论0 发布时间:2022-2-6 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版