2024.7.22 수업날
< BUTTON >
STM32cubeide 진행 과정
이번에는 00_BASIC의 .ioc 파일을 불러오는 방식으로 새로운 파일을 만든다.
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"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 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(!(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13)))
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
}
/* 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};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
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_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/* 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 */
여러개의 파일이 열려있을 때, 원하는 하나의 파일만 build 시키고 싶다면
원하는 파일에서 오른쪽 클릭을 하여 Build Project를 선택하면 된다.
그리고 build 시킬 파일만 열어두고, 사용하지 않는 파일은 Close Project를 선택하여 잠시 닫아두는 것이 좋다.
이제 run을 실행하기 위하여 상단의 run 아이콘의 옆 화살표를 선택한 후 Run Configurations를 선택한다.
그리고 run 하려는 파일을 좌측에 나타나게 한 후에 run을 실행해야한다.
다음으로 debug를 실행해보자.
이번에는 stm32 보드에 있는 USER 버튼을 눌렀을때만 LED 불이 들어오는 소스코드를 작성했다.
다음으로 led bar를 사용하여 좌측으로 차례대로 켜지면서 다시 좌측부터 꺼지는 소스코드를 작성해본다.
아래의 그림처럼 파일을 순서대로 추가하고 작성한다.
STM32cubeide 진행 과정
새로 만든 App 파일에 아래와 같이 파일을 2개를 추가로 만든다.
최종적으로 아래와 같이 파일과 소스코드를 생성해주면 된다.
def.h 소스코드
/*
* def.h
*
* Created on: Jul 24, 2024
*/
#ifndef COMMON_DEF_H_
#define COMMON_DEF_H_
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
//#include "main.h"
#include "stm32f4xx_hal.h"
#endif /* COMMON_DEF_H_ */
hw_def.h 소스코드
/*
* hw_def.h
*
* Created on: Jul 24, 2024
*/
#ifndef HW_HW_DEF_H_
#define HW_HW_DEF_H_
#include "def.h"
#define _LED_MAX_CH 8
#define _BUTTON_MAX_CH 3
#endif /* HW_HW_DEF_H_ */
hw.c 소스코드
/*
* hw.c
*
* Created on: Jul 24, 2024
*/
#include "hw.h"
void hwInit()
{
ledInit();
}
// 할 딜레이 함수 대체
void delay(uint32_t time_ms)
{
HAL_Delay(time_ms);
}
// 전원 입력후에 카운트 값을 반환 함수
// 시스템 틱을 이용함
uint32_t millis(void)
{
return HAL_GetTick();
}
hw.h 소스코드
/*
* hw.h
*
* Created on: Jul 24, 2024
*/
#ifndef HW_HW_H_
#define HW_HW_H_
#include "hw_def.h"
#include "led.h"
void hwInit();
void delay(uint32_t time_ms);
uint32_t millis(void);
#endif /* HW_HW_H_ */
led.c 소스코드
/*
* led.c
*
* Created on: Jul 24, 2024
* Author: jsmok
*/
#include "led.h"
#include "hw.h"
LED_TBL led_tbl[_LED_MAX_CH] =
{
{GPIOA, GPIO_PIN_5, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOA, GPIO_PIN_6, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOA, GPIO_PIN_7, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOB, GPIO_PIN_6, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOC, GPIO_PIN_7, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOA, GPIO_PIN_9, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOA, GPIO_PIN_8, GPIO_PIN_SET, GPIO_PIN_RESET},
{GPIOB, GPIO_PIN_10, GPIO_PIN_SET, GPIO_PIN_RESET}
};
bool ledInit()
{
bool ret = true;
return ret;
}
void ledOn(uint8_t ch)
{
if(ch > _LED_MAX_CH) return;
for (uint8_t i = 0; i < ch; i++)
{
HAL_GPIO_WritePin(led_tbl[i].port, led_tbl[i].pinNumber, led_tbl[i].onState);
}
}
void ledOff(uint8_t ch)
{
if(ch > _LED_MAX_CH) return;
for (uint8_t i = 0; i < ch; i++)
{
HAL_GPIO_WritePin(led_tbl[i].port, led_tbl[i].pinNumber, led_tbl[i].offState);
}
}
void ledToggle(uint8_t ch)
{
HAL_GPIO_TogglePin(led_tbl[ch].port, led_tbl[ch].pinNumber);
}
void ledLeftShift(uint8_t ch)
{
for(uint8_t i = 0; i < ch; i++)
{
//HAL_GPIO_WritePin(led_tbl[i].port, led_tbl[i].pinNumber, 1);
ledOn(i);
delay(100);
}
delay(500);
for(uint8_t i = 0; i < ch; i++)
{
//HAL_GPIO_WritePin(led_tbl[i].port, led_tbl[i].pinNumber, 0);
ledOff(i);
}
delay(500);
}
led.h 소스코드
/*
* led.h
*
* Created on: Jul 24, 2024
*/
#ifndef HW_DEVICE_LED_H_
#define HW_DEVICE_LED_H_
#include "hw_def.h"
typedef struct
{
GPIO_TypeDef *port;
uint16_t pinNumber;
GPIO_PinState onState;
GPIO_PinState offState;
}LED_TBL;
bool ledInit(void);
void ledOn(uint8_t ch);
void ledOff(uint8_t ch);
void ledToggle(uint8_t ch);
void ledLeftShift(uint8_t ch);
#endif /* HW_DEVICE_LED_H_ */
ap.c 소스코드
/*
* ap.c
*
* Created on: Jul 24, 2024
*/
#include "ap.h"
void apInit(void)
{
hwInit();
}
void apMain(void)
{
while(1)
{
ledLeftShift(8);
}
}
ap.h 소스코드
/*
* ap.h
*
* Created on: Jul 24, 2024
*/
#ifndef AP_H_
#define AP_H_
#include "hw.h"
void apInit(void); // 어플리케이션에 대한 초기화 함수
void apMain(void); // 우리가 사용할 실질적인 메인함수
#endif /* AP_H_ */
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 "ap.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 */
/* 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 */
apInit();
apMain();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* 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};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** 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.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
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_3) != 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_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|GPIO_PIN_9, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10|GPIO_PIN_6, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
/*Configure GPIO pins : PA5 PA6 PA7 PA8
PA9 */
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8
|GPIO_PIN_9;
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 : PB10 PB6 */
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PC7 */
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PA10 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : PB3 PB5 */
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* 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 */
다음으로 버튼을 눌렀을때만 led bar의 led가 켜지는 소스코드를 작성해본다.
LED LeftShift와 STM32cubeide 진행 과정은 똑같고, 수정할 부분만 첨부한다.
아래와 같이 button.c, button.h를 device 파일에 추가한다.
button.c 소스코드
/*
* button.c
*
* Created on: Jul 24, 2024
*/
#include "button.h"
typedef struct
{
GPIO_TypeDef *port;
uint16_t pinNumber;
GPIO_PinState onState;
}BUTTON_TBL;
BUTTON_TBL button_tbl[_BUTTON_MAX_CH] =
{
{GPIOB, GPIO_PIN_5, 0},
{GPIOB, GPIO_PIN_3, 0},
{GPIOA, GPIO_PIN_10, 0},
};
bool buttonInit()
{
bool ret = true;
return ret;
}
bool buttonGetPressed(uint8_t ch)
{
bool ret = false;
if(ch >= _BUTTON_MAX_CH)
{
return ret;
}
if(HAL_GPIO_ReadPin(button_tbl[ch].port, button_tbl[ch].pinNumber) == button_tbl[ch].onState)
{
delay(10);
if(HAL_GPIO_ReadPin(button_tbl[ch].port, button_tbl[ch].pinNumber) == button_tbl[ch].onState)
{
ret = true;
}
}
return ret;
}
button.h 소스코드
/*
* button.h
*
* Created on: Jul 24, 2024
*/
#ifndef HW_DEVICE_BUTTON_H_
#define HW_DEVICE_BUTTON_H_
#include "hw.h"
bool buttonInit();
bool buttonGetPressed(uint8_t ch);
#endif /* HW_DEVICE_BUTTON_H_ */
ap.c 소스코드
/*
* ap.c
*
* Created on: Jul 24, 2024
* Author: jsmok
*/
#include "ap.h"
void apInit(void)
{
hwInit();
}
void apMain(void)
{
while(1)
{
if(buttonGetPressed(0))
{
ledOn(8);
}
else
{
ledOff(8);
}
}
}
< UART_Rx >
STM32cubeide 진행 과정
여기서 usart2를 설정하고 자동으로 PA2, PA3이 usart2_tx, usart2_rx으로 설정되는 이유는
아래와 같이 핀이 TX, RX로 정해져있기 때문이다.
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"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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 */
uint8_t rxData[10]; // global val
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//HAL_UART_Receive_IT(&huart2, rxData, 4);
HAL_UART_Receive_DMA(&huart2, rxData, 4);
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 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();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
//HAL_UART_Receive_IT(&huart2, rxData, 4); //interrupt
HAL_UART_Receive_DMA(&huart2, rxData, 4); //DMA
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
//HAL_UART_Receive(&huart2, rxData, 4, 1000);
//check code
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(200);
/* 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};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** 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.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
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_3) != HAL_OK)
{
Error_Handler();
}
}
/* 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 */
UART_Rx는 uart 통신을 받는 결과만 확인할 수 있으므로 디버그를 통해 통신이 잘 되는지 확인할 수 있다.
< UART_Tx >
STM32cubeide 진행 과정은 UART_Tx와 똑같다. 수정해야하는 코드만 첨부한다.
먼저 comportmaster에 uart 통신이 되는지 확인하기 위해 테스트 코드를 작성한다.
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"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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 */
uint8_t rxData[] = "Hello STM32F411\r\n"; // global val
//char hello_arr[] = "LED_ON";
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// HAL_UART_Receive_IT(&huart2, rxData, 4);
// HAL_UART_Receive_DMA(&huart2, rxData, 4);
HAL_UART_Receive_IT(&huart2, &rxData, sizeof(rxData));
HAL_UART_Transmit_IT(&huart2, &rxData, sizeof(rxData));
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 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();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2, &rxData, sizeof(rxData)); //interrupt
//HAL_UART_Receive_DMA(&huart2, rxData, 4); //DMA
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_UART_Transmit(&huart2, rxData, sizeof(rxData), 100);
HAL_Delay(1000);
/* 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};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** 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.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
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_3) != HAL_OK)
{
Error_Handler();
}
}
/* 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 */
1000 Delay 마다 지정한 문장이 반복해서 나타나도록 하는 테스트 코드이다.
이번에는 디버그를 통해 결과를 확인해본다.
UART_Rx와는 다르게 rxData의 크기를 지정해주지 않았기 때문에 기본적으로 1글자만 받으며,
comportmater에도 통신받은 글자가 2글자 이하로 받을 수 있는 소스코드이다.
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"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* 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 */
uint8_t rxData; // global val
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// HAL_UART_Receive_IT(&huart2, rxData, 4);
// HAL_UART_Receive_DMA(&huart2, rxData, 4);
HAL_UART_Receive_IT(&huart2, &rxData, sizeof(rxData));
HAL_UART_Transmit_IT(&huart2, &rxData, sizeof(rxData));
}
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 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();
MX_DMA_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart2, &rxData, sizeof(rxData)); //interrupt
//HAL_UART_Receive_DMA(&huart2, rxData, 4); //DMA
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* 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};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** 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.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 100;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
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_3) != HAL_OK)
{
Error_Handler();
}
}
/* 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 */
이번에는 uart 통신을 통해
a를 전송하면 LED_ON이라는 문구가 출력되면서 stm32보드의 LED가 켜지고,
b를 전송하면 LED_OFF라는 문구가 출력되면서 stm32보드의 LED가 꺼지는 소스코드를 작성해본다.
STM32cubeide 진행 과정
아래와 같이 파일과 소스코드를 추가해준다.
led bar를 사용하여 좌측으로 차례대로 켜지면서 다시 좌측부터 꺼지는 소스코드와 진행방식은 똑같으며 수정해야하는 코드만 첨부한다.
uart.c 소스코드
/*
* uart.c
*
* Created on: Jul 24, 2024
*/
#include "uart.h"
#include "led.h"
uint8_t rxData;
uint8_t ledOn_arr[]="LED_ON\n";
uint8_t ledOff_arr[]="LED_OFF\n";
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart2)
{
HAL_UART_Receive_IT(&huart2, &rxData, sizeof(rxData));
if(rxData == 'a')
{
HAL_UART_Transmit_IT(&huart2, ledOn_arr, sizeof(ledOn_arr));
ledOn(8);
}
if(rxData == 'b')
{
HAL_UART_Transmit_IT(&huart2, ledOff_arr, sizeof(ledOff_arr));
ledOff(8);
}
}
}
uart.h 소스코드
/*
* uart.h
*
* Created on: Jul 24, 2024
*/
#ifndef HW_DEVICE_UART_H_
#define HW_DEVICE_UART_H_
#include "hw_def.h"
extern UART_HandleTypeDef huart2;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
bool uartInit(void);
#endif /* HW_DEVICE_UART_H_ */
ap.c 소스코드
/*
* ap.c
*
* Created on: Jul 24, 2024
*/
#include "ap.h"
void apInit(void)
{
hwInit();
}
extern uint8_t rxData;
void apMain(void)
{
HAL_UART_Receive_IT(&huart2, &rxData, sizeof(rxData));
while(1)
{
}
}
BUTTON, UART 끝!
'Harman 세미콘 아카데미 > STM32' 카테고리의 다른 글
2024.7.29 [STM32]6 - BUZZER, ADC (0) | 2024.07.29 |
---|---|
2024.7.24 [STM32]5 - 엘리베이터 만들기 팀프로젝트 (0) | 2024.07.24 |
2024.7.23 [STM32]4 - TIMER, STEP MOTOR (0) | 2024.07.23 |
2024.7.19 [STM32]2 - LED (0) | 2024.07.21 |
2024.7.16 [STM32]1 - STM32 Cube IDE (1) | 2024.07.16 |