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

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

[复制链接]
庭超 发布时间:2020-12-16 23:38
由于工作需要,最近需要使用STM32F303VC芯片来做一个带霍尔的电机驱动,使用的TIM1定时器,霍尔信号采用普通端口识别。1 S1 U4 u1 g9 g1 D5 o
初始代码使用论坛里面下载下来的测试程序https://www.stmcu.org.cn/module/ ... ht=STM32F3%2BEEPROM4 ~2 I2 Y+ i7 X( B* g; c
主要问题出在霍尔信号上,发现一直无法进入外触发中断,即使使用EXTI_GenerateSWInterrupt(EXTI_Linex);也无法正常进入中断。" }0 y' }! M6 U: g  E
查看了库文件stm32f30x_exti.c中的相关配置信息,如下:
2 Z3 p( G7 C# u- L5 X##### How to use this driver #####1 P! u0 K5 @; k; c5 y8 @, y% ?( R
===============================================================================
9 i+ O, y/ f' H    [..] In order to use an I/O pin as an external interrupt source, 1 F0 A  T/ @/ J/ S# D
         follow steps below:
6 ~, R, G, A6 A0 b         (#) Configure the I/O in input mode using GPIO_Init().
, k2 [  P2 C& O6 W0 H. H0 p         (#) Select the input source pin for the EXTI line using2 Y) o: G0 U  q2 a% P
             SYSCFG_EXTILineConfig().$ f( g# C% m. Z2 a. F
         (#) Select the mode(interrupt, event) and configure the trigger
8 `# C7 Q8 k5 `6 ?             selection (Rising, falling or both) using EXTI_Init(). For the
/ ^# H& q$ Y4 M" o5 ?             internal interrupt, the trigger selection is not needed
, O% t, V5 M7 t             (the active edge is always the rising one).
( D: ?5 b. ^2 h/ h- ]         (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init().
8 x/ P, P* ~3 o3 ]/ A9 {8 ^6 C1 S         (#) Optionally, you can generate a software interrupt using the function
+ W- X1 e0 o8 B; |5 ^6 B$ i- n             EXTI_GenerateSWInterrupt().
9 k" K% ]+ n) b  v- c1 V+ E/ O) I    [..]8 ~- D# ]& f/ s* a! [
    (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx
* K/ _: M. U& [4 O      registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);7 z7 W, \1 w/ D$ }0 @& O+ J
1 ~; i- P+ s! z. X! F
按照以上的配置,配置顺序应该是:端口设置-->触发源配置--> 外触发设置-->中断优先级设置;
& G) B' Y1 t4 u/ ?8 t) ?原先的程序是这样的:  \+ y- h9 r+ S3 }; l* L
void Ext_Init(void)1 N4 F* E9 c& A  @  u; x  q
{* |& i! u% K1 N) w
  GPIO_InitTypeDef GPIO_InitStructure;
! R7 Z$ I% M; K  EXTI_InitTypeDef EXTI_InitStructure;
' @* z$ k  a) |* ?# j- V+ }5 ~  NVIC_InitTypeDef NVIC_InitStructure;
0 K5 O2 M& w( C8 r. g/ `        9 \4 Z& x- @9 M% z
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);8 ~# d7 u+ K8 n9 s
//        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);  //注意与下行代码的区别,该函数会影响外触发中断,即使在其他函数中出现也会有影响# {$ w. }# b7 A
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
2 M, H- T- w/ `: X* X3 ]: ^( S5 q
7 j6 J5 H( F5 U7 o9 x9 m  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
/ M+ N  |% `  v, d2 z6 T1 o2 Y+ J  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;; N+ O. x) f, O' c8 ~+ Y0 z+ A
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
" k7 n5 z( Y" i5 N+ U: B% C! m  GPIO_Init(GPIOC, &GPIO_InitStructure);
8 {6 b8 c) p. e
8 k* K7 C* A; o4 O( l2 o  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
, g1 o( Z0 X- y9 o& ]1 J4 x/ @! U  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;+ r" v+ |. X% U9 R9 U! J3 y9 I
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
. a8 |5 k7 m- g' J4 {# Z6 f  GPIO_Init(GPIOD, &GPIO_InitStructure);
8 z* o3 X( n- P$ C        . m; ~/ r  }+ Y1 }% c/ [% F
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);" n7 h& b0 Q7 A
        6 I9 U5 d+ B% j% I
  EXTI_InitStructure.EXTI_Line=EXTI_Line6 | EXTI_Line7 | EXTI_Line8;
8 ?" f! U9 c* c, w3 J! H0 e; a1 Z  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;( z& o2 a3 X4 h4 a6 s* H$ M; g$ w
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;7 l! ]6 b" E5 A& `0 c# ?
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
1 @; h3 E% i% u0 W# [  EXTI_Init(&EXTI_InitStructure);
/ |1 i/ G9 R. q0 ?: i. b# X9 k) ~$ o$ v# @; E% t0 D* R
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);7 \/ `9 T, r) H, `6 U, X
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
% F6 L" x. P8 a  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
8 f. K2 a+ c, t  L1 X1 g1 k) H" ^% a  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;5 j! s  t8 s7 b+ X
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; : J/ Q! Y, a. b+ x! f" @0 V
  NVIC_Init(&NVIC_InitStructure);  
% B, G; B' {0 g7 {8 D; m1 j- u}
/ e, E. L& x; _7 q
" ~' M/ t; m" W  y/ O, X这个代码调试了有很久,一直找不出问题,网上有些说需要把这个函数提前到比较前面,测试了,也没用,也有说是调换配置的顺序,也是没有用处。% y3 _, L" r5 a
后来干脆直接用keil的软件仿真功能来看各个端口的配置信息,一步一步调试,才发现原来SYSCFG_EXTILineConfig、EXTI_InitStructure.EXTI_Line这两个函数只能一个通道一个通道设置,不能像端口配置GPIO_Init一样可以合在一起配置,无法得到想要的功能,只会出错。6 e, N3 f* d6 `, ~
以下是正确的配置方式:: `4 O+ l( Q7 {
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6);//只能一个一个设置$ l/ c- ^6 p# d+ D& L# G8 `
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource7);( ]) |7 L) B. l6 ?  e: w0 @2 x
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource8);
. I' P4 \9 p2 L+ H) B9 v5 S  @        % g- @7 [0 Z& f: _3 B5 n. \8 ?( O
  EXTI_InitStructure.EXTI_Line=EXTI_Line6; //只能一个一个设置
0 V# X, g7 v7 E2 v0 M+ N5 v  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;% |& R' ?  P! I: T
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
6 U" D: m! V) R% c- q1 h  EXTI_InitStructure.EXTI_LineCmd = ENABLE;& N, T' x' b$ ?8 N$ d
  EXTI_Init(&EXTI_InitStructure);" N. S; n" ?3 }/ x6 V
  EXTI_InitStructure.EXTI_Line=EXTI_Line7; 0 E3 V; p- z+ N) w
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;% v8 [- L& {( m  c3 V: A( T
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;8 K3 C8 }6 O/ V  r  }4 t
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;1 y% z2 h" ^6 d+ [" f
  EXTI_Init(&EXTI_InitStructure);        ' b9 g, r5 s% A% b+ N- {
  EXTI_InitStructure.EXTI_Line=EXTI_Line8; & L( |% I, H% o* p2 Y* D9 W0 @9 u
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
0 d6 W  z, _* |  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;6 h  M  _1 ]) c7 n/ O8 [" d
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
: g4 k  F  a+ n, r0 O! Y2 i  EXTI_Init(&EXTI_InitStructure);$ e* P4 G! H4 O; M+ j% N6 o

' R1 G0 L) d2 W- ]( W正确配置后,使用EXTI_GenerateSWInterrupt函数就能直接进入中断了,最后再将RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);去掉,才能通过端口进入中断。
7 ]# y9 x6 f$ k' p0 k9 Y这个问题也是算是个低级问题,只能怪自己不够仔细了。
3 V- B) N+ W& J) h, b分享一下错误经验,让各位大佬见笑了。
  F5 k! d/ E. c# i1 j) H3 l4 @2 S; v- C
收藏 评论2 发布时间:2020-12-16 23:38

举报

2个回答
yklstudent 回答时间:2020-12-17 08:41:05
感觉问题就出在:& y/ L' |" ?$ K
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);
. u4 }5 j- s3 U( R楼主就不应该这么写,乖乖的分开写
庭超 回答时间:2020-12-17 10:23:07
yklstudent-1794 发表于 2020-12-17 08:41
' L. P* H" ?7 W6 m# A感觉问题就出在:% q6 g, F% g- E# B
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO ...
, }1 _/ _# W# m' J1 h, a" y! S
是的,没错,还有 EXTI_Init(&EXTI_InitStructure)这个函数里,也只能一个一个设置

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版