임베디드/펌웨어 기초

stm32 mx >LED

twoweeks-within 2025. 1. 3. 20:00

 

lib 파일내에 cube MX 로 코드 프로젝트 생성

 > 참고용으로 사용

   > core 파일 >  resource configuration > exclusive from build

 

inc 파일들 다 path 참조

 

stm32f1xx.h

: #define STM32F103xB  STM32F103C8 

> STM32F103xB : preprocessor 에 추가

 

msp, it.c , system 파일들도 복사해주기 ( include 포함)

 

conf.h ( config) : 주변기기들 수정될때마다 따로 복사해주어야함

 

clock conf, HAL_Init, error_handler 도 복사해주고 > bsp.c

 

void MX_GPIO_Init(void)

{

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

 

}

 

gpio 도 가져옴 > 함수말고 내용 코드만

 

 

HAL_Init

/* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */

 > HAL_InitTick(TICK_INT_PRIORITY)

 

__weak void HAL_IncTick(void)

{

uwTick += uwTickFreq;

}

// uwTickFreq : 1KHZ  = 1m s

// uint32_t uwTick;

 

  • SysTick 타이머가 1ms마다 카운트를 증가시킵니다.
  • 설정된 주기에 맞춰 타이머가 오버플로우를 발생시키면, SysTick 인터럽트가 발생합니다.
  • 이 인터럽트가 발생하면, MCU는 SysTick_Handler 함수를 자동으로 실행합니다.

 

HAL_GetTick() : 

>

__weak uint32_t HAL_GetTick(void)

{

return uwTick;

}

 

아까 사용중인 uwTick 으로 HAL_GetTick 을 이용 

+

__weak void HAL_Delay(uint32_t Delay)

{

uint32_t tickstart = HAL_GetTick();

 

 

HAL_Delay 에서도 사용한다는점에서 중요!

 

GPIO > PC13 : LED를 켜보자

 

핀셋팅 > lib\src\gpio.c 에서 설정된 Init 값 > ap.c : apInit에 구현 > apMain 에서 사용

 

>>

다른 avr 같은 기기 사용시에는 호환이 안됨..

 

#ifdef _USE_HW_LED 

 

#define LED_MAX_CH HW_LED_MAX_CH

 

bool ledInit(void);

void ledOn(uint8_t ch);

void ledOff(uint8_t ch);

void ledToggle(uint8_t ch);

 

 

1. ledOn(uint8_t ch) // 항상 여러개씩 사용할걸 생각하며 할것 > uint8_t ch

2. _USE_HW_LED // LED를 사용할지 안할지 여부

3. define // 이름으로 정의한뒤 hw_def 에서 한번에 셋팅

 

#define _USE_HW_LED

#define HW_LED_MAX_CH 1

 

: hw_def.h

 

>> 구현하기 위한 drive 폴더 > hw\drive\led.c

 아까 했던걸 잘라 붙임

#define _DEF_LED1 0

#define _DEF_LED2 1

#define _DEF_LED3 2

#define _DEF_LED4 3

 

led 이름 부여

void hwInit(void)

{

bspInit();

 

ledInit();

}

 

hw.c 에서 초기화

 

>>>> 이렇게하면...

void apInit(void)

{

 

}

 

void apMain(void)

{

while(1)

{

ledToggle(_DEF_LED1);

delay(500);

}

}

 

ap.c 가 내가만든 api 로 되어있음

 > hw\drive 에서 함수 내부의 코드만 해당하는 mcu 가 제공하는 값으로 바꿔주면

   > 호환에 용이

 

bool ret = true;

GPIO_InitTypeDef GPIO_InitStruct = {0};

 

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

 

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

 

/*Configure GPIO pin : PC13 */

GPIO_InitStruct.Pin = GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

return ret;

 

>> 함수정리

 

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

 

for(int i=0; i<LED_MAX_CH; i++)

{

GPIO_InitStruct.Pin = led_tb1[i].pin;

HAL_GPIO_Init(led_tb1[i].port, &GPIO_InitStruct);

ledOff(i);

}

 

 

//

typedef struct

{

GPIO_TypeDef * port;

uint16_t pin;

GPIO_PinState on_state;

GPIO_PinState off_state;

}led_tb1_t;

 

led_tb1_t led_tb1[LED_MAX_CH] =

{

{GPIOC,GPIO_PIN_13,GPIO_PIN_RESET,GPIO_PIN_SET},

};

  > led 구조체 설정

 

void ledOn(uint8_t ch)

{

if(ch >= LED_MAX_CH) return;

HAL_GPIO_WritePin(led_tb1[0].port, led_tb1[0].pin, led_tb1[0].on_state);

}

> 구현 

 

LED_MAX_CH : 1부터 시작

uint8_t ch : 0부터 시작 

 

>>> led_tb1 구조체 배열안에 있는 값만 추가하고

     + Init 에서 clock 포트만 추가 해주면 

led를 무한대로 늘릴수있음! 

 

 >> 확장성에 항상 유념!

 

'임베디드 > 펌웨어 기초' 카테고리의 다른 글

UART, DMA  (0) 2025.01.19
reset  (0) 2025.01.08
cdc 2  (0) 2025.01.05
USB CDC  (0) 2025.01.04
초기설정  (0) 2025.01.02