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

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

[复制链接]
庭超 发布时间:2020-12-16 23:38
由于工作需要,最近需要使用STM32F303VC芯片来做一个带霍尔的电机驱动,使用的TIM1定时器,霍尔信号采用普通端口识别。
初始代码使用论坛里面下载下来的测试程序https://www.stmcu.org.cn/module/ ... ht=STM32F3%2BEEPROM
主要问题出在霍尔信号上,发现一直无法进入外触发中断,即使使用EXTI_GenerateSWInterrupt(EXTI_Linex);也无法正常进入中断。
查看了库文件stm32f30x_exti.c中的相关配置信息,如下:
##### How to use this driver #####
===============================================================================
    [..] In order to use an I/O pin as an external interrupt source,
         follow steps below:
         (#) Configure the I/O in input mode using GPIO_Init().
         (#) Select the input source pin for the EXTI line using
             SYSCFG_EXTILineConfig().
         (#) Select the mode(interrupt, event) and configure the trigger
             selection (Rising, falling or both) using EXTI_Init(). For the
             internal interrupt, the trigger selection is not needed
             (the active edge is always the rising one).
         (#) Configure NVIC IRQ channel mapped to the EXTI line using NVIC_Init().
         (#) Optionally, you can generate a software interrupt using the function
             EXTI_GenerateSWInterrupt().
    [..]
    (@) SYSCFG APB clock must be enabled to get write access to SYSCFG_EXTICRx
      registers using RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

按照以上的配置,配置顺序应该是:端口设置-->触发源配置--> 外触发设置-->中断优先级设置;
原先的程序是这样的:
void Ext_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
       
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
//        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);  //注意与下行代码的区别,该函数会影响外触发中断,即使在其他函数中出现也会有影响
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
       
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);
       
  EXTI_InitStructure.EXTI_Line=EXTI_Line6 | EXTI_Line7 | EXTI_Line8;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  
}

这个代码调试了有很久,一直找不出问题,网上有些说需要把这个函数提前到比较前面,测试了,也没用,也有说是调换配置的顺序,也是没有用处。
后来干脆直接用keil的软件仿真功能来看各个端口的配置信息,一步一步调试,才发现原来SYSCFG_EXTILineConfig、EXTI_InitStructure.EXTI_Line这两个函数只能一个通道一个通道设置,不能像端口配置GPIO_Init一样可以合在一起配置,无法得到想要的功能,只会出错。
以下是正确的配置方式:
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6);//只能一个一个设置
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource7);
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource8);
       
  EXTI_InitStructure.EXTI_Line=EXTI_Line6; //只能一个一个设置
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  EXTI_InitStructure.EXTI_Line=EXTI_Line7;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);       
  EXTI_InitStructure.EXTI_Line=EXTI_Line8;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

正确配置后,使用EXTI_GenerateSWInterrupt函数就能直接进入中断了,最后再将RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG,ENABLE);去掉,才能通过端口进入中断。
这个问题也是算是个低级问题,只能怪自己不够仔细了。
分享一下错误经验,让各位大佬见笑了。

收藏 评论2 发布时间:2020-12-16 23:38

举报

2个回答
yklstudent 回答时间:2020-12-17 08:41:05
感觉问题就出在:
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO_PinSource8);
楼主就不应该这么写,乖乖的分开写
庭超 回答时间:2020-12-17 10:23:07
yklstudent-1794 发表于 2020-12-17 08:41
感觉问题就出在:
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC,GPIO_PinSource6 | GPIO_PinSource7 | GPIO ...

是的,没错,还有 EXTI_Init(&EXTI_InitStructure)这个函数里,也只能一个一个设置

所属标签

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