STM32
IAR STM32F429I-DISC1 보드 UART(USART2) 통신 설정 및 사용 방법
꼬맹님
2025. 4. 23. 14:39
사용한 환경
- 보드: STM32F429I-DISC1
- 개발 환경: STM32CubeIDE 또는 Keil MDK, 또는 직접 Makefile 프로젝트
- 라이브러리: STM32F4xx Standard Peripheral Library
USART 핀 구성
USARTTX 핀RX 핀연결 포트
USART2 | PD5 | PD6 | GPIOD |
STM32F429 보드에서는 기본적으로 PD5가 TX, PD6가 RX로 연결되며 AF7 (Alternate Function 7) 을 사용합니다.
전체 소스 구성
총 3개의 파일을 사용합니다:
- main.c: 시스템 초기화, USART 설정 및 기본 송신 코드
- USART_CTM.h / .c: USART2 초기화 함수 정의
- stm32f4xx_it.c: 인터럽트 핸들러 정의
main.c
#include "main.h"
#include "stm32f4xx_usart.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "stm32f4xx.h"
#include "USART_CTM.h"
volatile uint32_t msTicks;
GPIO_InitTypeDef GPIO_InitStructure;
void SysTick_Handler(void);
void Delay(uint32_t ms);
void USART_SendString(USART_TypeDef* USARTx, const char *str);
void USART_SendData_8(USART_TypeDef* USARTx, uint8_t Data);
int main(void)
{
// 1. 시스템 초기화
SystemInit();
SystemCoreClockUpdate();
SysTick_Config(SystemCoreClock / 1000); // 1ms 타이머
// 2. GPIO 및 USART 초기화
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); // PD5, PD6용
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // USART2용
// 3. PD5, PD6 핀 Alternate Function 설정
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_USART2); // PD5 -> TX
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2); // PD6 -> RX
// 4. USART2 설정
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
// 5. USART 인터럽트 설정
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
NVIC_EnableIRQ(USART2_IRQn);
// 6. USART2 활성화
USART_Cmd(USART2, ENABLE);
while (1)
{
char data[] = "Hello\r\n"; //"HELLOW";
USART_SendString(USART2, data);
Delay(3000);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
/* 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) */
/* Infinite loop */
while (1)
{
}
}
#endif
}
void USART_SendString(USART_TypeDef* USARTx, const char *str)
{
while (*str != '\0')
{
assert_param(IS_USART_ALL_PERIPH(USARTx));
USARTx->DR = *str;
while (!(USARTx->SR & USART_SR_TC));
++str;
}
}
void USART_SendData_8(USART_TypeDef* USARTx, uint8_t Data)
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
/* Transmit Data */
USARTx->DR = (Data & (uint8_t)0xFF);
}
void Delay(uint32_t ms)
{
uint32_t cur = msTicks;
while ((msTicks - cur) < ms);
}
USART_CTM.c
직접 레지스터를 이용해 USART를 설정하는 방식
#include "USART_CTM.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_rcc.h"
void USART2_init()
{
// Enable clocks
RCC->APB1ENR |= RCC_APB1ENR_USART2EN; // Enable USART2 clock (APB1)
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // Enable GPIOD clock
// Configure PD5 (TX) and PD6 (RX) to alternate function mode (AF7)
GPIOD->MODER &= ~((3 << (5 * 2)) | (3 << (6 * 2))); // Clear mode bits
GPIOD->MODER |= (2 << (5 * 2)) | (2 << (6 * 2)); // Set alternate function mode
GPIOD->AFR[0] &= ~((0xF << (5 * 4)) | (0xF << (6 * 4))); // Clear AF bits
GPIOD->AFR[0] |= (7 << (5 * 4)) | (7 << (6 * 4)); // Set AF7 (USART2)
// Set baud rate (e.g., 115200)
// Assuming SystemCoreClock = 168MHz, APB1 = 42MHz
// USART2 is on APB1
USART2->BRR = 42000000 / 115200; // = ~364
// Enable USART2, transmitter, and receiver
USART2->CR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE;
}
stm32f4xx_it.c
수신 인터럽트 핸들러 및 Delay SysTick Handler
#include "stm32f4xx_it.h"
#include "main.h"
extern volatile uint32_t msTicks;
void SysTick_Handler(void)
{
//TimingDelay_Decrement();
msTicks++;
}
void USART2_IRQHandler(void)
{
if (USART2->SR & USART_SR_RXNE)
{
uint8_t received = USART2->DR;
USART2->DR = received;
while (!(USART2->SR & USART_SR_TC));
}
}
이 코드는 STM32F429I-DISC1 보드에서 PD5, PD6 핀을 통해 UART 송수신을 수행하며, 인터럽트를 통해 수신 이벤트도 처리합니다.
(수신 이벤트는 에코)