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

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

[复制链接]
庭超 发布时间:2020-12-16 23:38
由于工作需要,最近需要使用STM32F303VC芯片来做一个带霍尔的电机驱动,使用的TIM1定时器,霍尔信号采用普通端口识别。
, p# q& @% V7 n# K% f" Z初始代码使用论坛里面下载下来的测试程序https://www.stmcu.org.cn/module/ ... ht=STM32F3%2BEEPROM
# T* z3 {. Z( j主要问题出在霍尔信号上,发现一直无法进入外触发中断,即使使用EXTI_GenerateSWInterrupt(EXTI_Linex);也无法正常进入中断。; I( W) H. C2 X( _) [
查看了库文件stm32f30x_exti.c中的相关配置信息,如下:0 p' Q( k$ s- y% S2 H
##### How to use this driver #####) D9 Q. g6 ?# d9 c1 I8 [0 }
===============================================================================
1 h$ l3 \% o# g5 E# x    [..] In order to use an I/O pin as an external interrupt source, 1 F8 y/ O; u3 P1 v  X7 K
         follow steps below:) f; Z2 W/ Q5 _. M7 S& |4 _- B
         (#) Configure the I/O in input mode using GPIO_Init().2 x9 y  ]1 y* \: I; @( J0 g: `
         (#) Select the input source pin for the EXTI line using
$ Y4 d4 j8 v* F# \; P/ q/ O             SYSCFG_EXTILineConfig().
$ G% _; P: v! |  x         (#) Select the mode(interrupt, event) and configure the trigger
# u' x* I5 Y( m* P& ~/ X* F             selection (Rising, falling or both) using EXTI_Init(). For the
, r" B8 v: K  L% N" R. p! z             internal interrupt, the trigger selection is not needed
! T. }- W1 d# P9 S3 b2 G             (the active edge is always the rising one).
, [: A9 ^# e0 H$ `7 m: D8 f         (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init().
/ c& T8 E6 y6 D: o         (#) Optionally, you can generate a software interrupt using the function
' y( g: s/ q  v5 Q( E  e% H             EXTI_GenerateSWInterrupt().
) ?" f. \- \( U; A% n% N$ L    [..]
2 E" b3 @/ H3 h8 D8 E+ ^8 M    (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx
7 @* S! l. A3 M  b( Y      registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);  B7 ?2 {  v- y3 s' ~7 F, N
2 V" y1 a' m6 Q/ ]; K0 R+ I% R
按照以上的配置,配置顺序应该是:端口设置-->触发源配置--> 外触发设置-->中断优先级设置;
6 g& h- p6 W/ l+ c, n2 y* y" ?原先的程序是这样的:
4 W! |* ~4 {* q" e& g$ P' J6 }% @void Ext_Init(void)
7 m) c% K2 {* X0 ]% |0 A{9 N2 V! M; R6 \) p, g1 r* @+ r
  GPIO_InitTypeDef GPIO_InitStructure;% o9 Y! s2 S# F; n9 o( s% x
  EXTI_InitTypeDef EXTI_InitStructure;. H& j+ r+ W1 ~- t- K$ I
  NVIC_InitTypeDef NVIC_InitStructure;
& Z# d# S& `7 Y8 N& p        ) S, \9 {) x, E7 z: @# |1 Q+ t
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
' L1 E% {  g$ b. h; \//        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);  //注意与下行代码的区别,该函数会影响外触发中断,即使在其他函数中出现也会有影响1 V! ]' t) B4 {8 g2 \* A
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);0 Q; C$ M, o/ G8 K  t, l5 y
- v5 P+ C) b$ V' j
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
- ~5 e& K# q- |0 k0 V( ]+ O  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;( x' N. Y% I% W: o+ ~9 X2 P+ f
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
! F) e9 g* c3 }' S  GPIO_Init(GPIOC, &GPIO_InitStructure);( C1 M1 p7 u# J& Z  q3 `% r
7 _: p- W' D# M: ?6 o7 }) ?% y$ [
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
' a/ l. D" U" a  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
# s" D$ ~7 n4 L1 n  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;" W  M! K. @' J2 \: a/ o
  GPIO_Init(GPIOD, &GPIO_InitStructure);& E/ J+ D% Z7 Y) H! p! T
       
; V/ R: j' C- O% |  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);) q) O1 J+ f. T  k) Q
       
9 k; y1 X6 o- A: u! L; F% Y  EXTI_InitStructure.EXTI_Line=EXTI_Line6 | EXTI_Line7 | EXTI_Line8;$ t7 ?. m4 I$ f
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
7 K$ `; C7 M3 c  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;0 P( {6 ^2 ^: s0 \* N( I
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+ u$ e- b; s1 U1 I9 A  EXTI_Init(&EXTI_InitStructure);9 S4 m2 [' I1 Z; i1 X' w
* X, r8 _* Z, A& ?" X  P7 U% ^
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);  T" v5 P) X$ t; Z
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
1 f& y8 R) S5 s$ V7 S  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
5 P* D7 \2 F2 @  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
' I; t2 V' P0 ~6 N6 D" K' e  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
; g6 g+ |) O6 x2 T0 y  NVIC_Init(&NVIC_InitStructure);  & z" ]1 M+ \! U0 J# ~3 i% {
}
; G* A6 D* }4 G5 G  J2 ^# q, V" ?3 m" G  h: m- R/ c8 l
这个代码调试了有很久,一直找不出问题,网上有些说需要把这个函数提前到比较前面,测试了,也没用,也有说是调换配置的顺序,也是没有用处。4 w9 X8 E6 L* d8 `7 _# N
后来干脆直接用keil的软件仿真功能来看各个端口的配置信息,一步一步调试,才发现原来SYSCFG_EXTILineConfig、EXTI_InitStructure.EXTI_Line这两个函数只能一个通道一个通道设置,不能像端口配置GPIO_Init一样可以合在一起配置,无法得到想要的功能,只会出错。0 ?$ @, U# o: I% h
以下是正确的配置方式:
2 Z8 ?% S8 v& s2 t9 \  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6);//只能一个一个设置/ ^- ~- B( @# [  V0 l! D% a" v4 ]" b
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource7);* v* N, j3 w/ P9 y3 ?, Y6 A4 d: y% u) z
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource8);
3 U0 q! P: T# K. R- p, \        ! q3 f- `. B7 A" ?
  EXTI_InitStructure.EXTI_Line=EXTI_Line6; //只能一个一个设置
8 W' j3 D1 D3 A  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;0 `  [3 P) B( @) J: Z
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;: m: s( ^( `% Y1 N; @* g2 S7 Q
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
. J) p5 M7 C, a8 ]  EXTI_Init(&EXTI_InitStructure);2 P. M" C1 ^  C# d2 O
  EXTI_InitStructure.EXTI_Line=EXTI_Line7;
1 n% @" K- {0 G% z7 x  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
. x0 y4 V: U! v4 A2 P  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
5 I' x8 q1 D3 z1 D0 `  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
" R# Y. ~, o. \$ t- ]4 m8 h. L- h  EXTI_Init(&EXTI_InitStructure);        ! W: q. x4 s$ h1 b
  EXTI_InitStructure.EXTI_Line=EXTI_Line8; + T  F8 y9 r) I2 ~/ W% X
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
5 y4 b5 u( _6 B- a5 W8 K8 o. A/ O  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
* j& Q) k8 s+ Q- f5 _  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
3 F* M; ?, d# f$ \7 W$ Z  EXTI_Init(&EXTI_InitStructure);+ j- o$ Y7 b9 a$ k# R+ X

$ x/ [3 D+ v4 F正确配置后,使用EXTI_GenerateSWInterrupt函数就能直接进入中断了,最后再将RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);去掉,才能通过端口进入中断。! l+ A7 B+ U* w+ m9 [
这个问题也是算是个低级问题,只能怪自己不够仔细了。
+ Q( S: h: i# V" `分享一下错误经验,让各位大佬见笑了。. A& M1 J+ \& L) @2 K/ q

2 Z4 K1 q8 V! E& k  {
收藏 评论2 发布时间:2020-12-16 23:38

举报

2个回答
yklstudent 回答时间:2020-12-17 08:41:05
感觉问题就出在:1 g5 F. Y$ u& i4 k, r7 d& u
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);$ Q. m: E; @2 J! l4 j! e3 e' e) E7 k# ?
楼主就不应该这么写,乖乖的分开写
庭超 回答时间:2020-12-17 10:23:07
yklstudent-1794 发表于 2020-12-17 08:41
3 z& l2 t1 [7 K感觉问题就出在:# |6 g0 K+ I5 y& f7 g
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO ...

1 l2 p; h$ ?9 s3 l0 U' U9 Y是的,没错,还有 EXTI_Init(&EXTI_InitStructure)这个函数里,也只能一个一个设置

所属标签

相似分享

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