我在Keil uVision(STM32F103RBT6)中的按钮和IRQ处理程序遇到问题

时间:2020-04-23 06:55:16

标签: arm stm32 interrupt keil

很抱歉提出这样一个基本问题,我是ARM编程的初学者。我目前正在努力进行实验室练习。

我应该:使用板上按钮(PC13)打开和关闭板上LED(PA5)。按下按钮时,LED点亮。释放按钮后,LED熄灭。

下面的代码可以构建,但不会产生我想要的结果。实际上,当我按下按钮时什么也没发生。

#include "stm32f10x.h"                  // Device header
#include "stdbool.h"                 // For Boolean data type

#define BUTTON_RCC_GPIO  RCC_APB2Periph_GPIOC
#define BUTTON_GPIO       GPIOC 
#define BUTTON_GPIO_PIN   GPIO_Pin_13

int main(void) {

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(BUTTON_RCC_GPIO, ENABLE); 


    //GPIO set up for PA5 (on board LED)
    GPIO_InitTypeDef GPIO_InitStructure; 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //Timer 2 set up
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    TIM_TimeBaseInitTypeDef timerInitStructure;
    timerInitStructure.TIM_Prescaler = 0;  
    timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    timerInitStructure.TIM_Period = 0;  
    timerInitStructure.TIM_ClockDivision = 0; 
    timerInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &timerInitStructure);
    TIM_Cmd(TIM2, ENABLE);

    TIM_TIxExternalClockConfig(TIM2, TIM_TIxExternalCLK1Source_TI2, TIM_ICPolarity_Rising, 0);

    //Enable update event for Timer2
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
    NVIC_EnableIRQ(TIM2_IRQn);

    while(1);

    static char state = 0;
}

static char state = 0;

void TIM2_IRQHandler(void) { 
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { 
            GPIO_ResetBits(GPIOA, GPIO_Pin_5); 
            state = 1; 
        } else {
            GPIO_SetBits(GPIOA, GPIO_Pin_5);
            state = 0;
        }
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}

编辑:我已经对代码进行了大量修改,我决定完全不使用计时器。

#include "stm32f10x.h"                  // Device header
#include "stdbool.h"

//TI2 PA1 Tim2 Ch2
#define BUTTON_RCC_GPIO   RCC_APB2Periph_GPIOA
#define BUTTON_GPIO   GPIOA
#define BUTTON_GPIO_PIN   GPIO_Pin_13

#define L3_RCC_GPIO  RCC_APB2Periph_GPIOA
#define L3_GPIO      GPIOA
#define L3_PIN     GPIO_Pin_5


static bool wait = true;

int main(void) {
    GPIO_InitTypeDef GPIO_InitStruct;

    // GPIO clock for I/O
    RCC_APB2PeriphClockCmd(BUTTON_RCC_GPIO, ENABLE);
  RCC_APB2PeriphClockCmd(L3_RCC_GPIO, ENABLE);

    // Configure I/O for L3
    GPIO_InitStruct.GPIO_Pin = L3_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(L3_GPIO, &GPIO_InitStruct);

    while(1) {
                if(BUTTON_GPIO_PIN==true)
                {
                    GPIO_SetBits(L3_GPIO, L3_PIN);
                }else
                {
                    GPIO_ResetBits(L3_GPIO, L3_PIN);
                }
    }
}

1 个答案:

答案 0 :(得分:0)

您并未明确编写此代码,但我认为您的实验练习使用的是 NUCLEO-F103RB,您可以在其中找到 STM32F103RBTx控制器在PC13处配备了用户按钮,在PA5处配备了用户LED-我认为其他品牌几乎不会创造出具有相同属性的PCB ...:-)


正如KIIV在评论中所指出的那样,当您按下按钮时看不到LED改变的原因是,甚至没有检查按钮所连接的控制器输入引脚(PC13)。

相反,LED的输出状态(PA5)在由定时器(TIM2)中断触发的ISR中切换。 计时器配置(可能是不完整的,我无法通过单独阅读代码片段来判断)是由事件TI2的外部时钟源的上升沿触发的,该事件与通道TIM2_CH2相关联(可用于引脚PA1PB3,但是我看不到任何初始化代码。)


有些行是多余的(对RCC_APB2PeriphClockCmd()的调用和对state的定义将相互屏蔽...)。

我的印象是该代码尚未完成,但是对您首先研究您希望通过该程序实现什么以及将在代码的哪个部分实现什么有帮助。然后,为每个细节找到正确的解决方案更多是出于勤奋和查找正确的数据表的问题(请参见上面的链接)。