Đèn LED nhấp nháy ngay cả khi tôi không nhấn nút


7

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.

Hình 1

Đối với nguồn đồng hồ, tôi đã cấu hình nó như bạn có thể thấy dưới đây.

Hình 2

Và cho Ghim

hình 3

hinh 4

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.

hình5

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)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:

hình 6

hình7

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ó?


2
Tôi chưa bao giờ sử dụng loạt bộ xử lý đó nhưng nhận thấy rằng bạn có GPIO_InitStruct.Pull = GPIO_NOPULLthể 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ử.
PeterJ

@PeterJ Cảm ơn Peter đã trả lời. Tôi đã thử nó rồi. Tôi có nghĩa là tôi đã kéo lên điện trở bên trong (cho nois) nhưng điều đó không hoạt động. trong hướng dẫn ST, họ không bao giờ sử dụng điện trở kéo lên.
Roh

Câu trả lời:


7

Bạn phải sử dụng điện trở kéo / kéo xuống bên trong của chip hoặc cung cấp điện trở của riêng bạn.

Đồng thời, bạn cũng có thể gỡ bỏ đầu vào bằng cách thêm một điện trở nhỏ hơn và một tụ điện nhỏ:

sơ đồ

mô phỏng mạch này - Sơ đồ được tạo bằng CircuitLab

Lý thuyết vận hành là hơn khi công tắc mở, pullup / pulldown "kéo" chân đầu vào đến một giá trị đã biết. Nếu công tắc của bạn kết nối pin với mặt đất, thì điện trở pullup sẽ kết nối pin với+VCCkhi công tắc không được nhấn. Khi nhấn công tắc cả chân và điện trở được nối với mặt đất, vì vậy chân được0V và một dòng điện nhỏ (một vài mA tùy thuộc vào điện áp và điện trở) chảy qua điện trở.


Cảm ơn. Khi tôi kéo nó xuống (bởi một điện trở bên ngoài như bạn minh họa trong hình), nó hoạt động chính xác !!! làm tốt!
Roh

Ngoài ra tôi có một vấn đề đơn giản bây giờ, nó bị trả lại! Làm thế nào tôi có thể phát hành nó?
Roh


1
Tôi thường sử dụng pullup 10K, tụ 100nF và điện trở phóng 100.
Majenko

1
Nó xả tụ điện từ từ tạo ra sự chuyển tiếp trơn tru khi bạn nhấn nút.
Majenko
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.