簡體   English   中英

啟用外部中斷 ARM Cortex-M0+ (STM32G070)

[英]Enable external interrupts ARM Cortex-M0+ (STM32G070)

我試圖對 STM32 微控制器的編程有一個基本的了解。 我試圖通過設置所有適當的寄存器(沒有外部庫/定義)來使用來自按鈕的外部中斷來切換 LED 的狀態。 我似乎無法讓中斷例程工作,控制權永遠不會傳遞給處理程序。

這是我用來將 PC-13(根據 Nucleo-G070RB 板連接有一個按鈕)設置為外部中斷的方法:

RCC_APBENR2  |= 0b1 <<  0; // Enable SYSCFGEN
RCC_IOPENR   |= 0b1 <<  2; // Enable PORTC
EXTI_RTSR1   |= 0b1 << 13; // Enable interrupt on rising edge at EXTI line 13
EXTI_EXTICR4 |= 0x2 <<  8; // Set PC-13 as GPIO pin for interrupt
EXTI_IMR1    |= 0x1 << 13; // Unmask EXTI line 13

NVIC_ISER    |= 0b1 <<  7; // Enable interrupts for EXTI4_15

我不確定我錯過了什么。

這是完整的代碼:

#include <stdint.h>
#include <stdio.h>

#define RCC_IOPENR   *((uint32_t volatile *) 0x40021034)
#define RCC_APBENR2  *((uint32_t volatile *) 0x40021040)

#define GPIOA_MODER  *((uint32_t volatile *) 0x50000000)
#define GPIOA_IDR    *((uint32_t volatile *) 0x50000010)
#define GPIOA_ODR    *((uint32_t volatile *) 0x50000014)

#define GPIOC_MODER  *((uint32_t volatile *) 0x50000800)
#define GPIOC_IDR    *((uint32_t volatile *) 0x50000810)
#define GPIOC_ODR    *((uint32_t volatile *) 0x50000814)

#define NVIC_ISER    *((uint32_t volatile *) 0xE000E100)

#define EXTI_RTSR1   *((uint32_t volatile *) 0x40021800)
#define EXTI_EXTICR1 *((uint32_t volatile *) (0x40021800 + 0x060 + 0x4 * 0))
#define EXTI_EXTICR2 *((uint32_t volatile *) (0x40021800 + 0x060 + 0x4 * 1))
#define EXTI_EXTICR3 *((uint32_t volatile *) (0x40021800 + 0x060 + 0x4 * 2))
#define EXTI_EXTICR4 *((uint32_t volatile *) (0x40021800 + 0x060 + 0x4 * 3))
#define EXTI_IMR1    *((uint32_t volatile *) (0x40021800 + 0x080))
#define EXTI_RPR1    *((uint32_t volatile *) (0x40021800 + 0x00C))

void button_init();
extern void initialise_monitor_handles();

uint8_t volatile g_button_pressed = 0;

int main(void) {
    //asm volatile ("cpsie i");
    initialise_monitor_handles();

    //printf("Hello World!\n");

    RCC_IOPENR  |= 0b1 << 0;         // Enable PORTA
    GPIOA_MODER &= ~(0b11 << (2*5)); // Clear MODE bits for 5th pin (PA-5)
    GPIOA_MODER |= 0b1 << (2*5);     // Set MODE bits for 5th pin (PA-5) to 01 (set output)
    GPIOC_MODER &= ~(0b11 << (2*13)); // Clear MODE bits for 13th pin (PC-13) (set input)

    button_init();

    while(1) {
        if (g_button_pressed) {
            GPIOA_ODR ^= 0b1 << 5;
            printf("Button pressed\n");
            g_button_pressed = 0;
        }
    }
}

void button_init() {
    RCC_APBENR2  |= 0b1 <<  0; // Enable SYSCFGEN
    RCC_IOPENR   |= 0b1 <<  2; // Enable PORTC
    EXTI_RTSR1   |= 0b1 << 13; // Enable interrupt on rising edge at EXTI line 13
    EXTI_EXTICR4 |= 0x2 <<  8; // Set PC-13 as GPIO pin for interrupt
    EXTI_IMR1    |= 0x1 << 13; // Unmask EXTI line 13

    NVIC_ISER    |= 0b1 <<  7; // Enable interrupts for EXTI4_15
}

void EXTI4_15_IRQHandler(void) {
    g_button_pressed = 1;
    printf("Button pressed\n");
    EXTI_RPR1 |= 0xFFFF << 0;
}

我將 STM32CubeIDE 與默認編譯器一起使用,並通過 OpenOCD 的半主機打印。

所以,我的問題是,我是否遺漏了一步或做錯了什么?

所以,我弄清楚我的愚蠢錯誤是什么。 我非常專注於試圖了解我在設置外部中斷時出錯的地方,我並沒有真正檢查我是否正確設置了按鈕。

我嘗試將 PC13 設置為輸入:

GPIOC_MODER &= ~(0b11 << (2*13)); // Clear MODE bits for 13th pin (PC-13) (set input)

在我調用button_init()函數之前,它通過以下方式啟用button_init()的時鍾:

RCC_IOPENR   |= 0b1 <<  2; // Enable PORTC

由於 GPIOC 沒有啟用,PC13 也沒有設置為輸入,所以沒有什么可檢測的。

這是固定代碼:(我還更新了它以使用 CMSIS stm32 標頭,如P__J__所建議的P__J__

#define STM32G070xx
#include "stm32g0xx.h"

uint8_t volatile g_button_pressed = 0;

void button_init();
//extern void initialise_monitor_handles();

int main(void) {
//  initialise_monitor_handles();

    //printf("Hello World!\n");
    RCC->IOPENR  |= 0b1 << 0;         // Enable PORTA
    GPIOA->MODER &= ~(0b11 << (2*5)); // Clear MODE bits for 5th pin (PA-5)
    GPIOA->MODER |= 0b1 << (2*5);     // Set MODE bits for 5th pin (PA-5) to 01 (set output)

    button_init();

    while(1) {
        if (g_button_pressed) {
            GPIOA->ODR ^= 0b1 << 5;
//          printf("Button pressed! Yay!\n");
            g_button_pressed = 0;
        }
    }
}

void button_init() {
    // RCC->APBENR2    |= (uint32_t) (0b1 <<  0); // Enable SYSCFGEN
    RCC->IOPENR     |= (uint32_t) (0b1 <<  2); // Enable PORTC
    GPIOC->MODER    &= ~(0b11 << (2*13));      // Clear MODE bits for 13th pin (PC-13) (set input)

    EXTI->RTSR1     |= (uint32_t) (0b1 << 13); // Enable interrupt on rising edge at EXTI line 13
    EXTI->EXTICR[3] |= (uint32_t) (0x2 <<  8); // Set PC-13 as GPIO pin for interrupt
    EXTI->IMR1      |= (uint32_t) (0x1 << 13); // Unmask EXTI line 13

    NVIC->ISER[0]   |= (uint32_t) (0b1 <<  7); // Enable interrupts for EXTI4_15
}

void EXTI4_15_IRQHandler(void) {
    g_button_pressed = 1;
//  printf("Button pressed\n");
    EXTI->RPR1 = 0b1 << 13;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM