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개의 파일을 사용합니다:

  1. main.c: 시스템 초기화, USART 설정 및 기본 송신 코드
  2. USART_CTM.h / .c: USART2 초기화 함수 정의
  3. 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 송수신을 수행하며, 인터럽트를 통해 수신 이벤트도 처리합니다.

(수신 이벤트는 에코)