이번엔 진동을 감지하면 7세그먼트의 값을 올려보겠다.
첫번째 진동센서가 진동을 감지하면 값 1을 올리고, 2번째 진동센서가 진동을 감지하면 값 10을 올리는 작업을 해보겠다.
먼저 7세그먼트에 대한 자세한 정보나 핀 설정하는 방법은 다음 블로그를 참고하자
https://kksp12y.tistory.com/54
칩에 대한 설정이 끝나면 코드를 짜주면 된다.
나는 FND라이브러리를 만들어 적용해줬다.
FND.h
/*
* FND.h
*
* Created on: Dec 22, 2024
* Author: kksp1
*/
#ifndef INC_FND_H_
#define INC_FND_H_
#include "main.h"
#define HIGH 1
#define LOW 0
void send(uint8_t X);
void send_port(uint8_t X, uint8_t port);
void display_number(int number, int repetitions);
#endif /* INC_FND_H_ */
FND.c
/*
* FND.c
*
* Created on: Dec 22, 2024
* Author: kksp1
*/
#include "FND.h"
void send(uint8_t X){
for (int i = 8; i >= 1; i--)
{
if (X & 0x80)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PA10_DIO_Pin, HIGH);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PA10_DIO_Pin, LOW);
}
X <<= 1;
// make CLK
HAL_GPIO_WritePin(GPIOA, GPIO_PA8_SCLK_Pin, LOW);
HAL_GPIO_WritePin(GPIOA, GPIO_PA8_SCLK_Pin, HIGH);
}
}
void send_port(uint8_t X, uint8_t port){
send(X);
send(port);
HAL_GPIO_WritePin(GPIOA, GPIO_PA9_RCLK_Pin, LOW);
HAL_GPIO_WritePin(GPIOA, GPIO_PA9_RCLK_Pin, HIGH);
}
void display_number(int number, int repetitions){
int n1, n2, n3, n4;
uint8_t numArr[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
uint8_t numPosition[4] = {0b0001, 0b0010, 0b0100, 0b1000};
n1 = number % 10;
n2 = (number / 10) % 10;
n3 = (number / 100) % 10;
n4 = (number / 1000) % 10;
for(int i = 0; i < repetitions; i++){
send_port(numArr[n1], numPosition[0]);
send_port(numArr[n2], numPosition[1]);
send_port(numArr[n3], numPosition[2]);
send_port(numArr[n4], numPosition[3]);
}
}
여기서 dispaly_number만 사용하면 값이 뜰거다.
자세한 설명도 위 블로그에 적어두었으니 참고하라
main.c는 다음과 같다.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "FND.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
volatile uint16_t state = 0;
volatile uint16_t state_1 = 0;
uint16_t score = 0;
const uint8_t gunshot_1 = 1;
const uint8_t gunshot_10 = 10;
const uint8_t gunshot_100 = 100;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if (GPIO_Pin == han_Pin) {
state++;
}else if(GPIO_Pin == han2_Pin){
state_1++;
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if (state != 0) {
state = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PA3_LED_Pin, GPIO_PIN_SET); // LED ON
score += gunshot_1;
HAL_Delay(500); // 500ms
} else {
HAL_GPIO_WritePin(GPIOA, GPIO_PA3_LED_Pin, GPIO_PIN_RESET); // LED OFF
}
if (state_1 != 0) {
state_1 = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PA4_LED_Pin, GPIO_PIN_SET); // LED ON
score += gunshot_10;
HAL_Delay(500); // 500ms
} else {
HAL_GPIO_WritePin(GPIOA, GPIO_PA4_LED_Pin, GPIO_PIN_RESET); // LED OFF
}
display_number(score, 50);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIO_PC13_LED_GPIO_Port, GPIO_PC13_LED_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PA3_LED_Pin|GPIO_PA4_LED_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PA8_SCLK_Pin|GPIO_PA9_RCLK_Pin|GPIO_PA10_DIO_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : GPIO_PC13_LED_Pin */
GPIO_InitStruct.Pin = GPIO_PC13_LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIO_PC13_LED_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : GPIO_PA3_LED_Pin GPIO_PA4_LED_Pin */
GPIO_InitStruct.Pin = GPIO_PA3_LED_Pin|GPIO_PA4_LED_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : han2_Pin han_Pin */
GPIO_InitStruct.Pin = han2_Pin|han_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : GPIO_PA8_SCLK_Pin GPIO_PA9_RCLK_Pin GPIO_PA10_DIO_Pin */
GPIO_InitStruct.Pin = GPIO_PA8_SCLK_Pin|GPIO_PA9_RCLK_Pin|GPIO_PA10_DIO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#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 /* USE_FULL_ASSERT */
위 방법은 문제가 있다.
1. 진동 감지 센서가 여러번 인식이 된다. ( 500ms를 줬는데도..? )
2. 감지를 하면 500ms 딜레이로 인한 7세그먼트가 자연스럽게 점수가 올라가지 않는다. (영상 참고)
해당 문제들을 해결해야만 더 좋은 서비스가 될 것 같다.
구동 영상은 다음과 같다.
https://www.youtube.com/watch?v=rqnyviKxoz4
해결 방법은 한 코드에서 해결할 수 도 있겠지만 저번에 공부한 RTOS를 활용해보고 싶은 마음이 있다 하하,,
따라서 7세그먼트와 진동 감지 센서를 다른 태스크로 두고, 진동 감지 센서를 점수 값만 더해주는 태스크, 7세그먼트 태스크는 계속 LED를 키게끔 해주겠다.
그럼 1번은 해결 될 것 같다.
2번은 진동 감지 센서에서 채터링을 해결해봐야 할 것 같다.
다음 포스팅에서 더 진행해보도록 하겠다.
'STM32' 카테고리의 다른 글
STM32 버튼을 이용한 7세그먼트 초기화 (1) | 2024.12.25 |
---|---|
STM32로 진동 감지 센서 + 7세그먼트 제어 - 2 (0) | 2024.12.24 |
STM32로 DFR0027를 다루어 보기 (0) | 2024.12.22 |
STM32 익히기 2) (0) | 2024.12.05 |
STM32 익히기 1) (0) | 2024.12.02 |