如何解决启用外部中断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()
函数之前,该函数通过以下方式启用GPIOC的时钟:
RCC_IOPENR |= 0b1 << 2; // Enable PORTC
由于未启用GPIOC,所以也未将PC13设置为输入,因此没有可检测的内容。
这是固定的代码:(我也将其更新为使用CMSIS stm32标头,如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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。