找回密码
 注册
关于网站域名变更的通知
查看: 511|回复: 10
打印 上一主题 下一主题

STM32F103 外部中断程序中GPIO口输出不正常

[复制链接]
  • TA的每日心情
    开心
    2024-11-5 15:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    跳转到指定楼层
    1#
     楼主| 发表于 2024-10-29 11:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    本帖最后由 cynic 于 2024-10-29 11:19 编辑 8 L  B. B  f! g) ^5 `3 [

    7 L; P6 n! A$ @; }1 v7 |+ Y单片机:STM32F103C8 外部晶振,倍频到72MHz& }8 m. n, o' i3 k3 R3 u" W
    功能: PA0口输入125HZ的方波,PA5口在检测到PA0的上升沿后,输出周期为20us的双脉冲,
    % |% R% T8 k; U5 g& a; r
    : k9 ], p- U& F代码实现: PA0配置为外部中断,检测到上升沿中断后,在中断程序中设置PA5脚的输出) ^4 e& @+ L: e6 b1 l5 E4 O$ n
    1 y& ?# j  c, e( m
    问题:在输入波形每次上升沿都能进入到中断,但PA5脚并不是每次都有输出,3 k; o, U& y8 D- j# p9 R
              如图,黄色是PA0的输入信号,蓝色是PA5输出信号
    5 G; O+ m$ `+ Q' ?6 b6 T$ {3 u
    ( P# s5 L2 H$ p) S- d  t 8 @! D' M6 [7 y' \1 ]
    当把外部中断程序修改为每次检测到中断后就翻转PA5后,PA5输出就不会中断,每次PA0上升沿就有输出
    4 j) }# r( T0 P$ z5 |! d # L/ D; ^1 C" Y
    代码如下:
    4 d6 L0 H. Z/ w) z/ b( j
    1. #include <stm32F10x.h>" d8 T9 K  L2 c, I
    2. #include "stm32f10x_conf.h": ?8 B2 g( I, U9 H! e- b% A8 ^: C% z
    3. + n# B6 l7 g6 X* |; k, _

    4. 3 }  n- I7 V) Y" B& O8 m
    5. int main(void) {
      9 ~, I3 Z9 y5 {% ?
    6.         , k' C5 }$ c9 q5 @9 x. ~& i1 p
    7.         GPIO_InitTypeDef GPIO_InitStructure;
      - [9 y7 r  Q4 S
    8.     EXTI_InitTypeDef EXTI_InitStructure;( h8 d' y+ R& R
    9.     NVIC_InitTypeDef NVIC_InitStructure;        
      $ B3 F. u% J2 W0 F: e8 q& U
    10.     // 系统时钟初始化" d7 }% T! @' e% |: D/ N. q" @
    11.     SystemInit();
      , S* R- v3 `% g. k5 a  D& N

    12. : i) r) n" U9 G6 D  N9 e6 u0 ^
    13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  // 使能GPIOA时钟
      2 y! b5 l0 T/ {7 u! C
    14.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  // 使能GPIOB时钟
      . W4 ?# y9 C% `0 ^- V( H
    15.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);   // 使能AFIO时钟4 X8 w8 Q) C( r. R
    16.         
      3 t7 x& N$ ?& m7 W6 n* j
    17.     // 配置PA0和PA5        
      ! c% v9 i. t5 d7 ~
    18.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  // 下拉输入1 U% L: R) w' ?! M7 D/ l' K
    19.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;      // PA02 Z1 L+ ^; o* P3 \
    20.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      5 D1 ], f2 z3 i% ?# d
    21.     GPIO_Init(GPIOA, &GPIO_InitStructure);
      ) L" h9 W6 m1 v9 w& q1 _5 f( w
    22. $ I& @8 j8 Q3 @  E2 M3 j
    23.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  // 推挽输出
      % z; |. ~) o- m
    24.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;        // PA5# N& T- w8 ^' Z" A7 ^  z4 E( W5 _6 _
    25.     GPIO_Init(GPIOA, &GPIO_InitStructure);
      9 M* {1 Q$ n; [# r) s& o

    26. 8 `$ e' j$ n  e2 z( }& P4 d
    27.     // 配置AFIO) `8 c& H5 o  O. B7 Z9 G; ~
    28.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);  // PA0 -> EXTI0
      & ?' b3 E* L( p2 c. r, x
    29. . V" ~* t: n' J$ `) p
    30.     // 配置EXTI
      8 ?, e8 o  e, N+ [
    31. 9 @5 g; }( l( n+ g" Y
    32.     EXTI_InitStructure.EXTI_Line = EXTI_Line0;+ N. }) L/ R4 _( O7 v3 U; l
    33.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
      ! A6 p: u* ?/ P2 }
    34.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
      4 M8 m% l' w. l( q; q+ O
    35.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;3 ~! ~& Q) `& V5 t) k6 A
    36.     EXTI_Init(&EXTI_InitStructure);
      ; m) G" [& S" C: e
    37. ' {- T3 Q* g8 H+ Q2 \3 O& f
    38.     // 配置NVIC
      2 r6 o; A9 Q! P2 {- Z

    39. $ e8 O. Z! f, Y8 F% D
    40.     NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;* C( D* U: c: `0 I$ d& ]
    41.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
      . X# m: H( s' D( b! L* N
    42.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;/ J5 ~9 X( E5 }2 B$ Q
    43.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      * @* U% t( d; q6 i9 ~
    44.     NVIC_Init(&NVIC_InitStructure);2 n* e; Z* q! \% q$ O
    45. " B% O9 D/ x0 r0 s6 o2 D% {
    46.     // 进入无限循环
      , W; w, Q- R" C% h9 n
    47.     while (1) {  O! Z# n6 V+ k5 m; c4 j" c  ^6 J
    48.         // 主循环任务; I6 T4 D4 q. X, x1 j+ R3 R; |! g
    49.     }& t3 R/ w* E. N6 W1 n  j
    50. }9 Q) P. b7 ~. `$ b/ c
    51. 1 N% V4 w6 @1 R6 |# Z% T* E2 n
    52. % Z5 a# I' K: W

    53. $ V0 U4 T1 w) X' i2 |- r' _( \) u
    54. 3 u1 s1 U9 C' u

    55. ; c7 }4 a# J! N* {: y
    56. void Delay_us(uint16_t us) {
      $ F; D2 B- }5 v8 a( \$ c
    57.     TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
      7 o( j$ g* a4 _8 A+ E7 r5 ?) W
    58.     TIM_OCInitTypeDef TIM_OCInitStructure;
      ; P9 Z* E5 H& o7 A9 |8 z
    59.     uint16_t PrescalerValue = 0;
      9 W2 @, g4 `  {# d
    60. - b- u( j( X2 j: D
    61.     // 使能TIM2时钟
      4 y& ^  [# F; {4 z$ T
    62.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
      + P# L6 B' k0 }

    63. ' G4 N6 y7 j8 t4 r4 C' K5 g
    64.     // 计算预分频器值+ w. _; e* m3 x4 N- E
    65.     PrescalerValue = (uint16_t) ((SystEMCoreClock / 1000000) - 1);# {  ^2 S$ K# L' V& L5 I# _
    66. . I  v* c. v# Z% F: H& M8 K
    67.     // 初始化TIM2
        T/ d$ F; l" |# ]) V4 y
    68.     TIM_TimeBaseStructure.TIM_Period = us - 1;  // 自动重装载值3 R6 q, q8 [# \% E
    69.     TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;  // 预分频值
      6 s$ T2 W- b7 c  X- H: d
    70.     TIM_TimeBaseStructure.TIM_ClockDivision = 0;  // 时钟分割
      8 N, `! p3 W2 R, A
    71.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  // 向上计数模式. Y! v4 j, r8 b0 {9 W$ `7 Q% U
    72.     TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);7 E$ X+ n4 S+ L& U& [/ D  h! r

    73. ) q. o" t, V0 W& R% V
    74.     // 使能TIM2* L0 u% ], j3 C' ]* l
    75.     TIM_Cmd(TIM2, ENABLE);
      3 e7 `' y; p4 M' l
    76. ( T1 J6 d3 `/ {$ p
    77.     // 等待定时器计数完成
      $ x' S0 F3 y9 F' ^8 J2 j
    78.     while (TIM_GetFlagStatus(TIM2, TIM_FLAG_Update) == RESET);7 j0 Q4 R, [4 z9 f

    79. * W0 S2 A7 K' m9 ^
    80.     // 清除更新标志位
      % B. r8 [  Q, H4 I7 \
    81.     TIM_CleaRFlag(TIM2, TIM_FLAG_Update);
      , }% l5 l- _6 N
    82. ) _6 i6 I; q7 z6 f1 R7 {3 @  @9 A
    83.     // 关闭TIM2
      ! d$ G) i) c2 ?' n) e0 N& w
    84.     TIM_Cmd(TIM2, DISABLE);0 h: E* F7 l0 O8 H" `
    85. }3 e' I. x& t7 W
    86. 8 e: N- x) ~9 R$ p) A( K5 E3 d
    87. - x) w' H' \% j% D. H# `

    88. & m% m* y& m, o% A

    89. * @1 Z2 T9 I& W1 W  I- [

    90. 7 x. m" M0 S4 w1 B; W0 e% L
    91. void EXTI0_IRQHandler(void) {' E) M1 Z5 K; X! q( j0 N
    92.     if (EXTI_GetITStatus(EXTI_Line0) != RESET) {% i' h8 h9 h  _& F
    93. #if 1. |6 g6 Q( c0 m
    94.         // 按键PA0按下,控制PA5输出20微秒的双脉冲3 x7 @8 T+ e5 |7 t& e
    95.         GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);  // PA5高电平0 Q8 Q- k- F/ p4 _
    96.         Delay_us(10);  // 延迟10微秒$ i- u; k7 P; o* N% {
    97.         GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);  // PA5低电平
      + {/ C2 [  N) P; @6 M4 d" |
    98.         Delay_us(10);  // 延迟10微秒6 F- s. S1 X" h* G9 I: a! L
    99.         GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);  // PA5高电平7 S6 u1 _; _  A7 U
    100.         Delay_us(10);  // 延迟10微秒
      $ T. E: j( {1 _! B/ Z
    101.         GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);  // PA5低电平
      / l: B$ s4 G+ p9 C1 F& `2 X
    102. #else
      0 Q0 O+ D' `$ Z3 v8 q; Z4 g
    103.                 GPIOA->ODR ^= GPIO_Pin_5;# u7 X% c' |" L$ F
    104. #endif
      8 Z* G8 f" E8 B. N# u0 l
    105.         EXTI_ClearITPendingBit(EXTI_Line0);  // 清除中断标志位
      9 X4 \5 ]! |3 q
    106.     }* M/ o0 b- t/ m
    107. }1 X6 ~3 n( @* [9 z2 l

    108. 1 l% [/ h/ w% L# _/ o# ^5 W& ~
    复制代码

    ; W' l; o- @8 M/ R( e6 ~9 D, N( \# R  A/ I% z% c' ^7 n
  • TA的每日心情
    开心
    2024-11-5 15:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    2#
     楼主| 发表于 2024-10-29 11:24 | 只看该作者
    补充一下:有怀疑过是延时函数的问题,换成空循环延时,问题依旧
  • TA的每日心情
    慵懒
    2024-5-7 15:27
  • 签到天数: 2 天

    [LV.1]初来乍到

    3#
    发表于 2024-10-29 13:55 | 只看该作者
    看不到你的67 初始化TIM2数值(看看是不是TIM2配置有误),建议把外部中断去掉,直接输出脉冲看看

    点评

    不是TIM2初始化的问题,延时函数换成空循环也不行  详情 回复 发表于 2024-10-29 14:41
  • TA的每日心情
    开心
    2024-11-5 15:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    4#
     楼主| 发表于 2024-10-29 14:41 | 只看该作者
    Shieh 发表于 2024-10-29 13:55# L1 ?% e5 u# B: f1 F3 `
    看不到你的67 初始化TIM2数值(看看是不是TIM2配置有误),建议把外部中断去掉,直接输出脉冲看看

    " ?" `& L5 R) w9 O/ ~) [不是TIM2初始化的问题,延时函数换成空循环也不行$ R6 r/ e# U& @

    点评

    延迟空函数是什么意思? 我的意思是 会不会是你的计时器数值不对,比如工作频率、分频系数等(你自己去计算一下)  详情 回复 发表于 2024-10-29 15:18
  • TA的每日心情
    慵懒
    2024-5-7 15:27
  • 签到天数: 2 天

    [LV.1]初来乍到

    5#
    发表于 2024-10-29 15:18 | 只看该作者
    cynic 发表于 2024-10-29 14:414 V  x* H+ q8 B# {; \* m. l$ m* j7 k
    不是TIM2初始化的问题,延时函数换成空循环也不行

    ( |! o& \6 j8 Q2 Q& k, p延迟空函数是什么意思?  e9 g; R. J& m9 k3 L8 S
    我的意思是 会不会是你的计时器数值不对,比如工作频率、分频系数等(你自己去计算一下)

    点评

    空循环就是这样的 uint8_t t = 200; while(t--);  详情 回复 发表于 2024-10-29 15:33

    该用户从未签到

    6#
    发表于 2024-10-29 15:22 | 只看该作者
    中断里面尽量不要用延时

    该用户从未签到

    7#
    发表于 2024-10-29 15:22 | 只看该作者
    肯定就是把延时放在中断引起的

    点评

    中断放延时是不推荐,但我这个程序就只执行中断里面的程序,主程序是空循环  详情 回复 发表于 2024-10-29 15:31
  • TA的每日心情
    开心
    2024-11-5 15:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    8#
     楼主| 发表于 2024-10-29 15:31 | 只看该作者
    今天也晴 发表于 2024-10-29 15:22
    ; O+ u' G: y4 n7 w. t- e肯定就是把延时放在中断引起的

    : W  z9 A' a, y  D% ]中断放延时是不推荐,但我这个程序就只执行中断里面的程序,主程序是空循环: F% Y% f7 T6 E3 r9 I
  • TA的每日心情
    开心
    2024-11-5 15:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    9#
     楼主| 发表于 2024-10-29 15:33 | 只看该作者
    本帖最后由 cynic 于 2024-10-29 15:35 编辑 ( W; M9 A! z, \" R0 \2 I! \
    Shieh 发表于 2024-10-29 15:18
      s' c2 e/ \( w# ~0 e0 N  Z延迟空函数是什么意思?* Q1 I& P- N! I3 I
    我的意思是 会不会是你的计时器数值不对,比如工作频率、分频系数等(你自己去 ...

    4 |$ E3 K' U# Z) P# U- o# E空循环就是这样的   
    % x7 f/ G4 ~8 F7 f
    ; m8 h: f9 [9 A9 [' M$ zuint8_t  t = 200;
    0 {, ~6 h, ?, h# E' Pwhile(t--);
    ( V& q# O' E! w6 f7 P7 j7 e6 U" X/ \, V. T
    这样就不用定时器来计时,只是延迟时间没那么准而已,理论上不影响输出
    - n+ F) a% t( r; z! E! o
    . w! O/ ~+ c3 a1 N3 S3 F, r
    - _& r' e7 C# a, g% v

    点评

    你这样做肯定是没有用啊,你把外部中断去掉,保证你TIM2没问题了么?  详情 回复 发表于 2024-10-29 16:16
  • TA的每日心情
    慵懒
    2024-5-7 15:27
  • 签到天数: 2 天

    [LV.1]初来乍到

    10#
    发表于 2024-10-29 16:16 | 只看该作者
    cynic 发表于 2024-10-29 15:330 b) w) i7 ^$ o# I9 `! _
    空循环就是这样的   
    . L3 [( A7 J6 ^# q' n
    6 q. f3 N0 e5 a& E! B) buint8_t  t = 200;

    ! B* B+ i( e  g( w你这样做肯定是没有用啊,你把外部中断去掉,保证你TIM2没问题了么?

    点评

    我都用空循环替换掉用TIM2来计时了,程序里面就不用TIM2了,当然跟TIM2的设置没关系了  详情 回复 发表于 2024-10-29 16:21
  • TA的每日心情
    开心
    2024-11-5 15:44
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    11#
     楼主| 发表于 2024-10-29 16:21 | 只看该作者
    Shieh 发表于 2024-10-29 16:16
    - W' l+ J' ~' ], D你这样做肯定是没有用啊,你把外部中断去掉,保证你TIM2没问题了么?
    & P4 A4 t$ ~7 d8 Q1 v4 L# w2 z9 V* q
    我都用空循环替换掉用TIM2来计时了,程序里面就不用TIM2了,当然跟TIM2的设置没关系了1 M! I* h6 @4 c' R! A1 q; a2 Q

    # [" B2 T  X+ M+ z& _2 J0 D2 `
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-8-19 10:59 , Processed in 0.156250 second(s), 35 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表