1. STM32F411RET6(ARM Cortex-M4)
STM32f411RET6 특성
- Flash Memory : 512 kBytes
- RAM : 128 kBytes
- Speed : 100 MHz
2. STM32 구조
- D-BUS : RAM BUS
- I-BUS : Flash Memory BUS
- S-BUS : 주변장치 BUS
- APB1, APB2 : Bus 이름
→ ARM Architecture에서는 모든 peripheral, clock을 사용자가 설정해줘야함
⇒ 복잡할 수 있지만 전력 소모에서 이득
3. ioc를 이용한 설정
3-1. Clock 설정
PLL회로 : 클럭 증폭
→ NUCLEO 보드에는 8MHz 외부 크리스탈 오실레이터가 장착되어 있음
3-2. GPIO output 설정
- GPIO output level : 초기 상태
- GPIO mode : input, output
- GPIO Pull-up/down : 풀업, 풀다운 저항 설정
- Maximum output speed : 속도
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();
}
}
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();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
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);
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
→ 위와 같이 자동으로 setup한 코드가 만들어진다.
4. STM32F411 Memory 구조
가장 낮은 주소부터 Boot, Timer, UART, GPIO 등의 주소가 할당되어 있음
⇒ Memory 주소에 따라 Peripheral을 어떻게 할당할 수 있는지 알아야 한다.
CPU(Master)와 각 주변장치(Slave → Decoder, ROM, RAM …)와 BUS로 연결되어 있음
→ Address Bus, Data Bus, Signal Bus
그렇다면 어떻게 각 Slave를 서로 구별할것인가? ⇒ Decoder
CE(==CS) = LOW일 때만 해당 Chip 동작
ex) C, B, A = 0, 0, 0 일 때) Rom Enable
Address : A15 ~ A0 (2Bytes)
ROM Enable → A15, A14, A13 = 0, 0, 0
→ ROM Address Range : 0x0000 ~ 0x1FFF (0b000 0000… ~ 0b0001 1111 …)
RAM Enable → A15, A14, A13 = 0, 0, 1
→ RAM Address Range : 0x2000 ~ 0x3FFF (0b0010 0000… ~ 0b0011 1111 …)
8255 Enable → A15, A14, A13 = 0, 1, 0
→ 8255 Address Range : 0x4000 ~ 0x5FFF (0b0100 0000… ~ 0b0101 1111 …)
위와 같이 주소를 나누어 놓으면 아래와 같은 Memory Map을 만들 수 있다.
⇒ Memory 형태로 Read/Write하는 구조 = Memory Mapped I/O
5. Low level programming
→ CubeIDE에서 제공하는 ioc 라이브러리를 이용하지 않고 처음부터 프로그래밍하기
GPIOA 5pin Output Mode setup & LED Blink
- GPIOA peropheral에 Clock 인가
- GPIOA pin5 output mode 설정
- GPIOA pin5 output PushPull 설정
- Low Speed 설정
- GPIOA pin5에 High, Low 신호 출력
1. RCC CR → GPIOA peropheral에 Clock 인가
1-1. Clock 인가 → RCC
- GPIOA, RCC : AHB1 Bus
- Clock : RCC
RCC CR (Control Register)
- RCC Address Rage : 0x4002 3800 ~ 0x4002 3BFF
- RCC_CR Address : 0x4002 3800 + 0x00
- RCC_CR 초기 값 : 0x0000 XX81
(volatile unsigned int *)(0x40023800 + 0x00) |= (1<<0); // RCC_CR |= (1<<0)
`( )` : casing 연산자
`*` : 포인터화 → 뒤에 오는 상수가 주소라는 의미
`(unsigned int *)(XXX)` : XXX가 부호가 없는 4byte 주소다 라는 것을 정의함
⇒ 그렇다면 주소 XXX에 저장된 값을 수정하고 싶다면 ? → 간접참조 연산자 `*` 사용
* (volatile unsigned int *)(0x40023800 + 0x00) |= (1<<0); // RCC_CR |= (1<<0)
1-2. RCC AHB1ENR → AHB1 Bus 에 연결된 GPIOA에 Clock Enable
*(volatile unsigned int *)(0x40023800 + 0x30) |= (1<<0); // AHB1_ENR, GPIOA Enable
2. MODER → GPIOA pin5 output mode 설정
GPIO pin5 : MODER5 → bit 10, 11
GPIO pin5 Output mode : MODER5 0, 1
// GPIOA pin5 output setup
*(volatile unsigned int *)(0x40020000 + 0x00) &= ~(1<<11); // set bit 11 to 0
*(volatile unsigned int *)(0x40020000 + 0x00) |= (1<<10); // set bit 10 to 1
→ MCU에서 S-BUS를 통해 GPIO PORT A Resgister에 값을 저장
3. OTYPER → GPIOA pin5 output PushPull 설정
pin5 PushPull setup : set OT5(bit 5) to 0
- PushPull : MCU에서 전류를 Push or Pull (내부 전원)
- Open Drain : Drain 단자를 Open한다 → 외부 전원
// GPIOA pin5 PushPull setup (GPIOA_OTYPER)
*(volatile unsigned int *)(0x40020000 + 0x04) &= ~(1<<5);
4. SPEDDR → Low speed 설정
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
*(volatile unsigned int *)(0x40020000 + 0x14) |= (1<<5); // Output Register set to 1(High)
*(volatile unsigned int *)(0x40020000 + 0x14) &= ~(1<<5); // Output Register set to 0(Low)
5. ODR → GPIOA pin5에 High, Low 신호 출력
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
*(volatile unsigned int *)(0x40020000 + 0x14) |= (1<<5); // Output Register set to 1(High)
*(volatile unsigned int *)(0x40020000 + 0x14) &= ~(1<<5); // Output Register set to 0(Low)
GPIOA pin5 BLINK
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
int main()
{
// Clock authorization (RCC_CR)
*(volatile unsigned int *)(0x40023800 + 0x00) |= (1<<0); // RCC_CR |= (1<<0)
// RCC_ AHB1_ENR, GPIOA Enable
*(volatile unsigned int *)(0x40023800 + 0x30) |= (1<<0); // RCC_ AHB1_ENR, GPIOA Enable
// GPIOA pin5 output setup (GPIOA_MODER)
*(volatile unsigned int *)(0x40020000 + 0x00) &= ~(1<<11); // set bit 11 to 0
*(volatile unsigned int *)(0x40020000 + 0x00) |= (1<<10); // set bit 10 to 1
// GPIOA pin5 PushPull setup (GPIOA_OTYPER)
*(volatile unsigned int *)(0x40020000 + 0x04) &= ~(1<<5);
// GPIOA pin5 Low Speed setup (GPIOA_OSPEEDR)
*(volatile unsigned int *)(0x40020000 + 0x08) &= ~(1<<11);
*(volatile unsigned int *)(0x40020000 + 0x08) &= ~(1<<10);
while(1)
{
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
*(volatile unsigned int *)(0x40020000 + 0x14) |= (1<<5); // Output Register set to 1(High)
delay(200);
*(volatile unsigned int *)(0x40020000 + 0x14) &= ~(1<<5); // Output Register set to 0(Low)
delay(200);
}
return 0;
}
#define RCC_CR (volatile unsigned int *)(0x40023800 + 0x00)
#define RCC_AHB1_ENR (volatile unsigned int *)(0x40023800 + 0x30)
#define GPIOA_MODER (volatile unsigned int *)(0x40020000 + 0x00)
#define GPIOA_OTYPR (volatile unsigned int *)(0x40020000 + 0x04)
#define GPIOA_OSPEEDR (volatile unsigned int *)(0x40020000 + 0x08)
#define GPIOA_ODR (volatile unsigned int *)(0x40020000 + 0x14)
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
int main()
{
// Clock authorization (RCC_CR)
*RCC_CR |= (1<<0);
// RCC_ AHB1_ENR, GPIOA Enable
*RCC_AHB1_ENR |= (1<<0);
// GPIOA pin5 output setup (GPIOA_MODER)
*GPIOA_MODER &= ~(1<<11); // set bit 11 to 0
*GPIOA_MODER |= (1<<10); // set bit 10 to 1
// GPIOA pin5 PushPull setup (GPIOA_OTYPER)
*GPIOA_OTYPR &= ~(1<<5);
// GPIOA pin5 Low Speed setup (GPIOA_OSPEEDR)
*GPIOA_OSPEEDR &= ~(1<<11);
*GPIOA_OSPEEDR &= ~(1<<10);
while(1)
{
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
*GPIOA_ODR |= (1<<5); // Output Register set to 1(High)
delay(200);
*GPIOA_ODR &= ~(1<<5); // Output Register set to 0(Low)
delay(200);
}
return 0;
}
#define AHB1_BASE 0x40020000
#define RCC_BASE (AHB1_BASE + 0x3800)
#define GPIOA_BASE (AHB1_BASE + 0x0000)
#define GPIOC_BASE (AHB1_BASE + 0x0800)
#define RCC_CR (volatile unsigned int *)(RCC_BASE + 0x00)
#define RCC_AHB1_ENR (volatile unsigned int *)(RCC_BASE + 0x30)
#define GPIOA_MODER (volatile unsigned int *)(GPIOA_BASE + 0x00)
#define GPIOA_OTYPR (volatile unsigned int *)(GPIOA_BASE + 0x04)
#define GPIOA_OSPEEDR (volatile unsigned int *)(GPIOA_BASE + 0x08)
#define GPIOA_ODR (volatile unsigned int *)(GPIOA_BASE + 0x14)
#define GPIOC_MODER (volatile unsigned int *)(GPIOC_BASE + 0x00)
#define GPIOC_OTYPR (volatile unsigned int *)(GPIOC_BASE + 0x04)
#define GPIOC_OSPEEDR (volatile unsigned int *)(GPIOC_BASE + 0x08)
#define GPIOC_ODR (volatile unsigned int *)(GPIOC_BASE + 0x14)
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
int main()
{
// Clock authorization (RCC_CR)
*RCC_CR |= (1<<0);
//------------------GPIOA pin5-------------------
// RCC_ AHB1_ENR, GPIOA Enable
*RCC_AHB1_ENR |= (1<<0);
// GPIOA pin5 output setup (GPIOA_MODER)
*GPIOA_MODER &= ~(1<<11); // set bit 11 to 0
*GPIOA_MODER |= (1<<10); // set bit 10 to 1
// GPIOA pin5 PushPull setup (GPIOA_OTYPER)
*GPIOA_OTYPR &= ~(1<<5);
// GPIOA pin5 Low Speed setup (GPIOA_OSPEEDR)
*GPIOA_OSPEEDR &= ~(1<<11);
*GPIOA_OSPEEDR &= ~(1<<10);
//------------------GPIOC pin8-------------------
*RCC_AHB1_ENR |= (1<<2);
*GPIOC_MODER &= ~(1<<17);
*GPIOC_MODER |= (1<<16);
*GPIOC_OTYPR &= ~(1<<8);
*GPIOC_OSPEEDR &= ~(1<<17);
*GPIOC_OSPEEDR &= ~(1<<16);
while(1)
{
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
*GPIOA_ODR |= (1<<5); // Output Register set to 1(High)
*GPIOC_ODR |= (1<<8); // Output Register set to 1(High)
delay(200);
*GPIOA_ODR &= ~(1<<5); // Output Register set to 0(Low)
*GPIOC_ODR &= ~(1<<8); // Output Register set to 0(Low)
delay(200);
}
return 0;
}
구조체 변수 선언하여 레지스터 값 define
#define GPIOA_MODER (volatile unsigned int *)(GPIOA_BASE + 0x00)
#define GPIOA_OTYPER (volatile unsigned int *)(GPIOA_BASE + 0x04)
#define GPIOA_OSPEEDR (volatile unsigned int *)(GPIOA_BASE + 0x08)
#define GPIOA_PUBDR (volatile unsigned int *)(GPIOA_BASE + 0x0C)
#define GPIOA_IDR (volatile unsigned int *)(GPIOA_BASE + 0x10)
#define GPIOA_ODR (volatile unsigned int *)(GPIOA_BASE + 0x14)
#define GPIOA_BSRR (volatile unsigned int *)(GPIOA_BASE + 0x18)
#define GPIOA_LCKR (volatile unsigned int *)(GPIOA_BASE + 0x1C)
#define GPIOA_AFRL (volatile unsigned int *)(GPIOA_BASE + 0x20)
#define GPIOA_AFRH (volatile unsigned int *)(GPIOA_BASE + 0x24)
→ 각 register가 4byte씩 차이가 나기 때문에 아래와 같이 구조체로 바꿀 수 있음
(!!단, 구조체 멤버 변수 순서 중요!!)
typedef struct{
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int GPIOA_PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRR;
volatile unsigned int LCKR;
volatile unsigned int AFRL;
volatile unsigned int AFRH;
}GPIO_TypeDef;
#define AHB1_BASE 0x40020000
#define RCC_BASE (AHB1_BASE + 0x3800)
#define GPIOA_BASE (AHB1_BASE + 0x0000)
#define GPIOB_BASE (AHB1_BASE + 0x0400)
#define GPIOC_BASE (AHB1_BASE + 0x0800)
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
`GPIO_TypeDef` 구조체 변수 → 4byte씩 멤버변수 10개 → 40byte
typedef struct{
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int GPIOA_PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRR;
volatile unsigned int LCKR;
volatile unsigned int AFRL;
volatile unsigned int AFRH;
}GPIO_TypeDef;
#define AHB1_BASE 0x40020000
#define RCC_BASE (AHB1_BASE + 0x3800)
#define GPIOA_BASE (AHB1_BASE + 0x0000)
#define GPIOB_BASE (AHB1_BASE + 0x0400)
#define GPIOC_BASE (AHB1_BASE + 0x0800)
#define RCC_CR (volatile unsigned int *)(RCC_BASE + 0x00)
#define RCC_AHB1_ENR (volatile unsigned int *)(RCC_BASE + 0x30)
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
int main()
{
// Clock authorization (RCC_CR)
*RCC_CR |= (1<<0);
//------------------GPIOA pin5-------------------
// RCC_ AHB1_ENR, GPIOA Enable
*RCC_AHB1_ENR |= (1<<0);
// GPIOA pin5 output setup (GPIOA_MODER)
//*GPIOA_MODER &= ~(1<<11); // set bit 11 to 0
//*GPIOA_MODER |= (1<<10); // set bit 10 to 1
GPIOA->MODER &= ~(1<<11);
GPIOA->MODER |= (1<<10);
// GPIOA pin5 PushPull setup (GPIOA_OTYPER)
//*GPIOA_OTYPER &= ~(1<<5);
GPIOA->OTYPER &= ~(1<<5);
// GPIOA pin5 Low Speed setup (GPIOA_OSPEEDR)
//*GPIOA_OSPEEDR &= ~(1<<11);
//*GPIOA_OSPEEDR &= ~(1<<10);
GPIOA->OSPEEDR &= ~(1<<11);
GPIOA->OSPEEDR &= ~(1<<10);
//------------------GPIOC pin8-------------------
*RCC_AHB1_ENR |= (1<<2);
//*GPIOC_MODER &= ~(1<<17);
//*GPIOC_MODER |= (1<<16);
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
//*GPIOC_OTYPER &= ~(1<<8);
GPIOC->OTYPER &= ~(1<<8);
//*GPIOC_OSPEEDR &= ~(1<<17);
//*GPIOC_OSPEEDR &= ~(1<<16);
GPIOC->OSPEEDR &= ~(1<<17);
GPIOC->OSPEEDR &= ~(1<<16);
while(1)
{
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
//*GPIOA_ODR |= (1<<5); // Output Register set to 1(High)
//*GPIOC_ODR |= (1<<8); // Output Register set to 1(High)
GPIOA->ODR |= (1<<5);
GPIOC->ODR |= (1<<8);
delay(200);
//*GPIOA_ODR &= ~(1<<5); // Output Register set to 0(Low)
//*GPIOC_ODR &= ~(1<<8); // Output Register set to 0(Low)
GPIOA->ODR &= ~(1<<5);
GPIOC->ODR &= ~(1<<8);
delay(200);
}
return 0;
}
위 사진과 같이 HAL Library에 구조체 형식으로 저장되어 있음
#include "stm32f4xx_hal.h"
//typedef struct{
// volatile unsigned int MODER;
// volatile unsigned int OTYPER;
// volatile unsigned int OSPEEDR;
// volatile unsigned int GPIOA_PUPDR;
// volatile unsigned int IDR;
// volatile unsigned int ODR;
// volatile unsigned int BSRR;
// volatile unsigned int LCKR;
// volatile unsigned int AFRL;
// volatile unsigned int AFRH;
//
//}GPIO_TypeDef;
//
//#define AHB1_BASE 0x40020000
//#define RCC_BASE (AHB1_BASE + 0x3800)
//#define GPIOA_BASE (AHB1_BASE + 0x0000)
//#define GPIOB_BASE (AHB1_BASE + 0x0400)
//#define GPIOC_BASE (AHB1_BASE + 0x0800)
//
//#define RCC_CR (volatile unsigned int *)(RCC_BASE + 0x00)
//#define RCC_AHB1_ENR (volatile unsigned int *)(RCC_BASE + 0x30)
//
//#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)
//#define GPIOB ((GPIO_TypeDef *)GPIOB_BASE)
//#define GPIOC ((GPIO_TypeDef *)GPIOC_BASE)
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
int main()
{
RCC->CR |= (1<<0);
RCC->AHB1ENR |= (1<<0);
// Clock authorization (RCC_CR)
//*RCC_CR |= (1<<0);
//------------------GPIOA pin5-------------------
// RCC_ AHB1_ENR, GPIOA Enable
//*RCC_AHB1_ENR |= (1<<0);
// GPIOA pin5 output setup (GPIOA_MODER)
//*GPIOA_MODER &= ~(1<<11); // set bit 11 to 0
//*GPIOA_MODER |= (1<<10); // set bit 10 to 1
GPIOA->MODER &= ~(1<<11);
GPIOA->MODER |= (1<<10);
// GPIOA pin5 PushPull setup (GPIOA_OTYPER)
//*GPIOA_OTYPER &= ~(1<<5);
GPIOA->OTYPER &= ~(1<<5);
// GPIOA pin5 Low Speed setup (GPIOA_OSPEEDR)
//*GPIOA_OSPEEDR &= ~(1<<11);
//*GPIOA_OSPEEDR &= ~(1<<10);
GPIOA->OSPEEDR &= ~(1<<11);
GPIOA->OSPEEDR &= ~(1<<10);
//------------------GPIOC pin8-------------------
RCC->AHB1ENR |= (1<<2);
//*RCC_AHB1_ENR |= (1<<2);
//*GPIOC_MODER &= ~(1<<17);
//*GPIOC_MODER |= (1<<16);
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
//*GPIOC_OTYPER &= ~(1<<8);
GPIOC->OTYPER &= ~(1<<8);
//*GPIOC_OSPEEDR &= ~(1<<17);
//*GPIOC_OSPEEDR &= ~(1<<16);
GPIOC->OSPEEDR &= ~(1<<17);
GPIOC->OSPEEDR &= ~(1<<16);
while(1)
{
// GPIOA pin5 High & Low Signal (GPIOA_ODR)
//*GPIOA_ODR |= (1<<5); // Output Register set to 1(High)
//*GPIOC_ODR |= (1<<8); // Output Register set to 1(High)
GPIOA->ODR |= (1<<5);
GPIOC->ODR |= (1<<8);
delay(200);
//*GPIOA_ODR &= ~(1<<5); // Output Register set to 0(Low)
//*GPIOC_ODR &= ~(1<<8); // Output Register set to 0(Low)
GPIOA->ODR &= ~(1<<5);
GPIOC->ODR &= ~(1<<8);
delay(200);
}
return 0;
}
#include "stm32f4xx_hal.h"
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
void clock_init()
{
RCC->CR |= (1<<0);
RCC->AHB1ENR |= (1<<0); // GPIOA
RCC->AHB1ENR |= (1<<2); // GPIOC
}
void gpio_init()
{
// GPINA pin 5
GPIOA->MODER &= ~(1<<11);
GPIOA->MODER |= (1<<10);
GPIOA->OTYPER &= ~(1<<5);
GPIOA->OSPEEDR &= ~(1<<11);
GPIOA->OSPEEDR &= ~(1<<10);
// GPINC pin 8
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
GPIOC->OTYPER &= ~(1<<8);
GPIOC->OSPEEDR &= ~(1<<17);
GPIOC->OSPEEDR &= ~(1<<16);
}
void sys_init()
{
clock_init();
gpio_init();
}
void GPIO_write(GPIO_TypeDef *GPIOx, int pin, int state)
{
if(state == SET)
{
GPIOx->ODR |= (1<<pin);
}
else if(state == RESET)
{
GPIOx->ODR &= ~(1<<pin);
}
}
int main()
{
sys_init();
while(1)
{
GPIO_write(GPIOA, 5, SET);
GPIO_write(GPIOC, 8, SET);
delay(200);
GPIO_write(GPIOA, 5, RESET);
GPIO_write(GPIOC, 8, RESET);
delay(200);
}
return 0;
}
#include "stm32f4xx_hal.h"
void delay(unsigned int times)
{
unsigned int temp = times * 1000;
while(temp) temp--;
}
void clock_init()
{
RCC->CR |= (1<<0);
RCC->AHB1ENR |= (1<<0); // GPIOA
RCC->AHB1ENR |= (1<<2); // GPIOC
}
void gpio_init()
{
// GPINA pin 5
GPIOA->MODER &= ~(1<<11);
GPIOA->MODER |= (1<<10);
GPIOA->OTYPER &= ~(1<<5);
GPIOA->OSPEEDR &= ~(1<<11);
GPIOA->OSPEEDR &= ~(1<<10);
// GPINC pin 8
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
GPIOC->OTYPER &= ~(1<<8);
GPIOC->OSPEEDR &= ~(1<<17);
GPIOC->OSPEEDR &= ~(1<<16);
}
void sys_init()
{
clock_init();
gpio_init();
}
void GPIO_write(GPIO_TypeDef *GPIOx, int pin, int state)
{
if(state == SET)
{
GPIOx->ODR |= (1<<pin);
}
else if(state == RESET)
{
GPIOx->ODR &= ~(1<<pin);
}
}
void GPIO_toggle(GPIO_TypeDef *GPIOx, int pin)
{
GPIOx->ODR ^= (1<<pin);
}
int main()
{
sys_init();
while(1)
{
// GPIO_write(GPIOA, 5, SET);
// GPIO_write(GPIOC, 8, SET);
// delay(200);
// GPIO_write(GPIOA, 5, RESET);
// GPIO_write(GPIOC, 8, RESET);
// delay(200);
GPIO_toggle(GPIOA, 5);
GPIO_toggle(GPIOC, 8);
delay(200);
}
return 0;
}
Made By Minseok KIM
'ARM > 2_Study' 카테고리의 다른 글
[ARM] STM32_FreeRTOS, Shared Memory (0) | 2024.04.30 |
---|---|
[ARM] STM32_Serial Communication(UART), Queue (0) | 2024.04.29 |
[ARM] STM32_PWM, Driver(Motor) (0) | 2024.04.29 |
[ARM] STM32_Driver(CLCD I2C, Ultrasonic) (0) | 2024.04.26 |
[ARM] STM32_메모리 저장&실행 과정, Driver(Button, LED) (0) | 2024.04.26 |
Let's Be Happy!
도움이 되었으면 좋겠어요 :)