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

STM32F3 多路外触发无法进入中断问题

[复制链接]
庭超 发布时间:2020-12-16 23:38
由于工作需要,最近需要使用STM32F303VC芯片来做一个带霍尔的电机驱动,使用的TIM1定时器,霍尔信号采用普通端口识别。9 f, Y' o) _) ?2 ?/ b
初始代码使用论坛里面下载下来的测试程序https://www.stmcu.org.cn/module/ ... ht=STM32F3%2BEEPROM3 P; T+ Y9 ]. i5 v/ n/ \3 J5 q' ^
主要问题出在霍尔信号上,发现一直无法进入外触发中断,即使使用EXTI_GenerateSWInterrupt(EXTI_Linex);也无法正常进入中断。
, ^/ c- H* I% I8 e查看了库文件stm32f30x_exti.c中的相关配置信息,如下:# l. n4 t' U  n/ b! ?; r* \
##### How to use this driver #####+ M- H# z, O0 S' B( r# [
===============================================================================: ]9 ~7 X4 S6 t$ o# N4 O' b
    [..] In order to use an I/O pin as an external interrupt source,
, l9 e& r+ {! l/ V% A  S& x) S         follow steps below:; _4 p/ ?) e9 Z$ _
         (#) Configure the I/O in input mode using GPIO_Init().5 D( }3 z. Y# j! t) M$ f
         (#) Select the input source pin for the EXTI line using" w: ]" `% a0 j3 L$ c6 a
             SYSCFG_EXTILineConfig().
% b& R( w! V6 u$ D$ g6 f/ g; o         (#) Select the mode(interrupt, event) and configure the trigger
- e: N/ U6 v* W2 V- i             selection (Rising, falling or both) using EXTI_Init(). For the
  Y% b- r! K- Z% d+ T* X3 T. i             internal interrupt, the trigger selection is not needed
% t7 \' L+ N0 R6 ^2 V9 D             (the active edge is always the rising one).. N- U1 r" P# b& w; \7 a4 b( z% D
         (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init().7 _: x; L. l, E2 n& o( |; Q) }/ t) l' I
         (#) Optionally, you can generate a software interrupt using the function ( C3 E- F& E5 }- u3 r# _2 }
             EXTI_GenerateSWInterrupt().
7 z, B0 X& \% u0 i4 J, s, {    [..]
9 r2 p1 b; J3 a! \  d0 ]; {    (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx, ]( v% s5 W" H0 u. m  e) w
      registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
& ?4 T8 x' \* Q8 B# u: x
- x) u$ b5 G' _+ U4 _按照以上的配置,配置顺序应该是:端口设置-->触发源配置--> 外触发设置-->中断优先级设置;& p2 V! Q8 l5 x5 t
原先的程序是这样的:
& n8 ?  |# Z4 e# E/ p8 O9 m6 [' Yvoid Ext_Init(void)
6 Y+ `8 m* K, h1 {{+ u3 S4 b9 S& Z- }2 a
  GPIO_InitTypeDef GPIO_InitStructure;0 s2 [) ^1 Y/ g$ W9 L: t
  EXTI_InitTypeDef EXTI_InitStructure;3 c4 O  g- R- V! H9 g, a% e
  NVIC_InitTypeDef NVIC_InitStructure;! c& J7 A) d! Q/ Z
       
' j4 O: H- M8 a+ S1 g  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
1 e1 Z' ]" z2 E9 _+ N. K//        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);  //注意与下行代码的区别,该函数会影响外触发中断,即使在其他函数中出现也会有影响
9 w2 S6 ?+ a0 N# g0 D. x  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
! e. z6 M, H" ^' q  Q2 T/ |% j
0 t& o' j* b% d4 [- T  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
! }" E- O) }7 ?  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
! v+ v; b5 Y1 T1 f0 ~! }# F8 T  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
$ j/ p2 D! u4 G  GPIO_Init(GPIOC, &GPIO_InitStructure);
3 l6 H) G$ Q; L& M2 c- y! s6 b+ p' {) M4 }; R
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
; Z4 U+ D5 V* I  X  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;/ f8 w* W( [+ M4 h/ I$ K
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/ u; B; u/ i- P  a4 G# p6 Z* r  GPIO_Init(GPIOD, &GPIO_InitStructure);
  d/ I2 A% C9 _2 u6 d: f0 @        , H4 L3 \+ N0 a; u8 S
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);- s. W1 k: W0 {1 ~* U* ^/ D
       
, q  B5 g1 }9 G3 [; O. r  EXTI_InitStructure.EXTI_Line=EXTI_Line6 | EXTI_Line7 | EXTI_Line8;
0 a" Y3 p( p% s- l9 |3 H! _( n  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
4 ~/ L. u# c3 W% ^  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;0 F, O- ^) O3 F
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
3 t* e2 p* r; _$ h  EXTI_Init(&EXTI_InitStructure);
& [1 \! J' @' k; W' G; D* s. q- i/ |" w# [5 S8 I( N3 q2 V
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);" y8 `- e# _' ^3 A+ H
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;# P6 {. u) K2 f. T" W6 X
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  . E5 E+ J9 _* j8 U& n8 i, U
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/ G( \5 @8 k9 Q  i5 T( D! {
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ' @  R% k  `. s6 Q# t. C' N
  NVIC_Init(&NVIC_InitStructure);  
* R1 }6 k( _. M8 D9 T7 ~' q}
! D4 w. n/ H9 `7 z+ w8 A
% M( K# {/ H; U这个代码调试了有很久,一直找不出问题,网上有些说需要把这个函数提前到比较前面,测试了,也没用,也有说是调换配置的顺序,也是没有用处。) h+ [! N, \4 C# ]. \/ S5 U! H
后来干脆直接用keil的软件仿真功能来看各个端口的配置信息,一步一步调试,才发现原来SYSCFG_EXTILineConfig、EXTI_InitStructure.EXTI_Line这两个函数只能一个通道一个通道设置,不能像端口配置GPIO_Init一样可以合在一起配置,无法得到想要的功能,只会出错。9 G5 J6 f+ S0 T  \6 C' X% y, N
以下是正确的配置方式:
7 v0 o8 u5 a. D9 ^( Y  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6);//只能一个一个设置
1 l. @9 B* n& g- x( [  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource7);5 x( M, e7 [- Z4 i1 d
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource8);/ o/ _9 X& @3 h4 L  R- ~
       
5 a3 c# I+ }0 d  q  EXTI_InitStructure.EXTI_Line=EXTI_Line6; //只能一个一个设置
2 I  e6 {' I  V  w% n% \  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;2 I4 K: N! s$ z& u8 B7 N
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
! R) G( I( m; k, D& E: W  EXTI_InitStructure.EXTI_LineCmd = ENABLE;/ j& X+ \6 b! g/ [, a6 t, L9 M
  EXTI_Init(&EXTI_InitStructure);
- x% Y( }3 L- `' d  EXTI_InitStructure.EXTI_Line=EXTI_Line7; 7 k! K( P; h2 |" l
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
' w. c2 X4 r& Y' F9 ?  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  g7 ]3 R( u1 t# B) t7 v$ s
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
9 _- d* ~+ T5 U  EXTI_Init(&EXTI_InitStructure);        5 s1 C0 K- E4 j* r* v
  EXTI_InitStructure.EXTI_Line=EXTI_Line8; + d4 ~2 z- q8 H9 b& E& s1 |
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
% |" E) n; [7 G# |% R+ y: F  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;8 u' S' O7 C& c' t" A. O
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;: B/ x: \! w. v. P: [* u( z
  EXTI_Init(&EXTI_InitStructure);
2 k% S( M7 k" S# r! g  ~( Y4 N' `! n' z
正确配置后,使用EXTI_GenerateSWInterrupt函数就能直接进入中断了,最后再将RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);去掉,才能通过端口进入中断。
: e+ h+ Z3 |6 w$ Y这个问题也是算是个低级问题,只能怪自己不够仔细了。. I6 H4 r; K, S. `4 r' _
分享一下错误经验,让各位大佬见笑了。
! i) A! F8 N& F: Z, A
" @6 D  |9 P3 O" ~: Y
赞 收藏 评论2 发布时间:2020-12-16 23:38

举报

2个回答
yklstudent 回答时间:2020-12-17 08:41:05
感觉问题就出在:
" i+ S8 J" i5 j; a  [- B& u9 ^SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);, F( s# Q+ p$ @3 z3 }
楼主就不应该这么写,乖乖的分开写
庭超 回答时间:2020-12-17 10:23:07
yklstudent-1794 发表于 2020-12-17 08:418 h7 ?5 C/ u+ m& @
感觉问题就出在:
+ @1 l, C3 y; k/ C. ESYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO ...
9 G+ Y" [" K" Q9 g0 V, l& }2 d
是的,没错,还有 EXTI_Init(&EXTI_InitStructure)这个函数里,也只能一个一个设置
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版