Tôi đã viết một chương trình ở Keil nhấp nháy đèn LED thông qua Ngắt GPIO bên ngoài. Đây là cách tôi đã cấu hình nó trong STM32CubeMX:
Lúc đầu, tôi đã kích hoạt và cấu hình RCC khi bạn có thể thấy và định cấu hình PA0 cho ngắt ngoài và PB1 làm đầu ra.
Đối với nguồn đồng hồ, tôi đã cấu hình nó như bạn có thể thấy dưới đây.
Và cho Ghim
Tôi đã chọn hộp kiểm "EXTI Line 0 và Line 1 interrupt". Tôi không chắc chắn rằng việc kiểm tra hộp kiểm này là cần thiết.
Sau khi cấu hình, tôi tạo mã nguồn bên dưới (main.c):
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* System interrupt init*/
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1)
{
}
/* USER CODE END 3 */
}
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
__SYSCFG_CLK_ENABLE();
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__GPIOF_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
__GPIOB_CLK_ENABLE();
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PB1 */
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
/**
* @}
*/
/**
* @}
*/
Để xử lý ngắt GPIO bên ngoài, tôi đã mở tệp 'stm32f0xx_it.c' và đặt HAL_GPIO_TogglePin(GPIOB , GPIO_PIN_1)
giữa HAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn)
và HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0)
sau đó mã nguồn ngắt là:
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
#include "stm32f0xx.h"
#include "stm32f0xx_it.h"
/* External variables --------------------------------------------------------*/
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
/**
* @brief This function handles EXTI Line 0 and Line 1 interrupts.
*/
void EXTI0_1_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
HAL_GPIO_TogglePin(GPIOB , GPIO_PIN_1);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
Tôi đã xây dựng tệp HEX chính xác và tải nó xuống MCU (không có bất kỳ vấn đề hoặc lỗi nào). Bây giờ, khi tôi chạy nó, có một vấn đề. Đèn LED nhấp nháy nhanh ngay cả khi tôi không nhấn nút. Nhìn:
Tại sao? Ngoài ra khi tôi nhấn nút, nó sẽ bật đèn LED nhưng nó nhấp nháy giữa mỗi lần nhấn. Có vẻ như một cái gì đó thay đổi trạng thái của pin PB1. Có vấn đề gì vậy? Làm thế nào tôi có thể sửa nó?
GPIO_InitStruct.Pull = GPIO_NOPULL
thể cần phải thay đổi nó để kéo xuống đất (nếu có) hoặc sử dụng điện trở bên ngoài để kéo nó xuống đất. Không chắc có thể có vấn đề khác không nhưng điều đó đáng để thử.