gpt4 book ai didi

embedded - 带有 PA0 按钮的 STM32F303VCT6 外部中断不会触发 LED

转载 作者:行者123 更新时间:2023-12-05 07:37:02 24 4
gpt4 key购买 nike

我想使用连接到 PA0 的按钮作为外部中断,以在按下按钮时切换 PE14 上的 LED。但是调用 configure_PA0 函数似乎不起作用。

我在 while 循环中做了一个简单的闪烁指令来测试,结果是当我调用 configure_PA0 时 LED 一直保持亮起。

如果不调用它,LED 会正常闪烁,所以我认为这个函数一定有问题。

#include "stm32f30x.h"

void delay(volatile uint32_t count){
while(count > 0 )
count--;
}

void init_LED(){ //init led on PE14
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOE,&GPIO_InitStructure);
}
void configure_PA0(void) {

GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
//PA0 as button init
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);

//EXTI init
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_InitStruct);

//NVIC init
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}


void toggle_PE14(){
if(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_14) == 0)
GPIO_SetBits(GPIOE,GPIO_Pin_14);
else
GPIO_ResetBits(GPIOE,GPIO_Pin_14);
}

//handle pa0 interrupt
void EXTI0_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line0) != RESET){
toggle_PE14();

EXTI_ClearITPendingBit(EXTI_Line0);
}
}


int main(void) {

init_LED();
configure_PA0();

while (1) {
delay(400);
}

return 0;
}

更新我通过将处理程序定义放入 extern "C"{ .. } 括号中来修复它。如果您使用 C++ 编写代码,显然您必须这样做。

最佳答案

UPDATE ...

首先,感谢让其他读者知道!让我解释一下这些发现的因果关系:

... I fixed it by putting handler definition into extern "C" { /* .. */ } brackets. Apparently you have to do that if you code in C++.

当用 C++ 编程时 (即,对于那些在 C 和 C++ 中都有效的语言特性,当使用 C++ 编译器构建程序时) C++ 符号之间存在差异链接器使用的目标代码中的 C 符号。简而言之,这样做是因为 C++ 标识符必须通过某些类型信息进行扩展才能支持多态性。详细说明 here .

任何在没有 extern C 限定符的情况下定义的 C++ 函数都将获得一个扩展的(“损坏的”)符号。这也适用于输入 C++ 编译器的“模棱两可”函数,就像在本例中一样。

任何 extern C 函数(以及由 C 编译器翻译的任何函数,如果混合编译器)将变成一个链接器符号,其名称未被破坏(通常仅通过一些下划线扩展,具体取决于使用的工具链)。

要点是:汇编函数的行为大部分类似于 C 函数 - 在汇编代码中引用/定义的函数符号将按原样传递给链接器。通常(在本例中),STM32 中断向量表的定义也是如此(以下两个代码片段均来自 startup_stm32l476xx.s):

g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
/*...*/
.word PendSV_Handler
.word SysTick_Handler
/*...*/
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
/*...*/

以及在默认 STM32CubeF3/STM32CubeMX 代码中链接到 DefaultHandlerweak 函数定义

/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/

.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler

/*...*/

.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler

.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler

/*...*/

这意味着链接器找到了

  1. 对向量表中的 C 符号 EXTI0_IRQHandler 的引用,
  2. C 符号 EXTI0_IRQHandler 的(弱但独特的)定义
  3. 基于 EXTI0_IRQHandler 的错位 C++ 符号的(非弱但不匹配的)定义。

它匹配 (1.) 与 (2.) 并丢弃 (3.) 因为没有被引用,所以在外部引脚产生的第一个中断使 MCU 进入无限循环 DefaultHandler 并且LED 停止闪烁。

关于embedded - 带有 PA0 按钮的 STM32F303VCT6 外部中断不会触发 LED,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48886632/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com