Chapter 10 - Hongjayeong-02/Basic_SoC_implementation GitHub Wiki

10. UART β€” USART3

Goal

NUCLEO-F439ZI의 USART3λ₯Ό register levelμ—μ„œ μ„€μ •ν•˜κ³ , ST-LINK Virtual COM Portλ₯Ό 톡해 PC terminal둜 λ¬Έμžμ—΄μ„ μ „μ†‘ν•œλ‹€.

이번 μ‹€μŠ΅:

STM32F439ZI
    β”‚
    β”‚ USART3
    β”‚
    └── PD8 (TX)
          ↓
       ST-LINK
          ↓
       USB VCP
          ↓
         PC
          ↓
"Hello from NUCLEO-F439ZI!"

μ„€μ •:

USART  : USART3
TX     : PD8
RX     : PD9
AF     : AF7
Baud   : 115200 bps
Clock  : 16 MHz
Format : 115200-8-N-1

1. Board Mapping

μ›μ„œμ˜ NUCLEO-F411κ³Ό ν˜„μž¬ μ‚¬μš©ν•˜λŠ” NUCLEO-F439ZIλŠ” Virtual COM Port 연결이 λ‹€λ₯΄λ‹€.

  | NUCLEO-F411 | NUCLEO-F439ZI -- | -- | -- USART | USART2 | USART3 TX | PA2 | PD8 RX | PA3 | PD9 AF | AF7 | AF7 APB1 Enable | USART2EN | USART3EN AFR | AFR[0] | AFR[1]

λ”°λΌμ„œ μ›μ„œ μ½”λ“œλ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜λ©΄ compile은 λ˜λ”λΌλ„ VCP에 좜λ ₯이 λ‚˜νƒ€λ‚˜μ§€ μ•Šμ„ 수 μžˆλ‹€.

이번 boardμ—μ„œλŠ”:

USART3 TX β†’ PD8
USART3 RX β†’ PD9

λ₯Ό μ‚¬μš©ν•œλ‹€.


2. UART Registers

이번 μ½”λ“œμ—μ„œ 직접 μ‚¬μš©ν•˜λŠ” register:

RCC->AHB1ENR
RCC->APB1ENR

GPIOD->MODER GPIOD->AFR[1]

USART3->BRR USART3->CR1 USART3->SR USART3->DR

USART μ£Όμš” bit:

CR1 bit3   TE
β†’ Transmitter Enable

CR1 bit13 UE β†’ USART Enable

SR bit7 TXE β†’ Transmit Data Register Empty


3. Baud Rate

Peripheral clock:

APB1 Clock = 16 MHz

Target:

Baud Rate = 115200

κΈ°μ‘΄ μ‹€μŠ΅ μ½”λ“œ:

BRR = (periph_clk + baudrate / 2) / baudrate;

λ”°λΌμ„œ:

16,000,000 + 57,600
───────────────────
115,200

β‰ˆ 139

즉:

USART3->BRR β‰ˆ 139

λ₯Ό μ‚¬μš©ν•œλ‹€.

baudrate / 2λ₯Ό λ¨Όμ € λ”ν•˜λŠ” 것은 μ •μˆ˜ λ‚˜λˆ—μ…ˆμ—μ„œ 반올림 효과λ₯Ό μ£ΌκΈ° μœ„ν•œ 것이닀.


4. Practice Code

Project:

Inc/
β”œβ”€β”€ gpio.h
β”œβ”€β”€ systick.h
└── uart.h

Src/ β”œβ”€β”€ gpio.c β”œβ”€β”€ systick.c β”œβ”€β”€ uart.c └── main.c

gpio.c와 systick.cλŠ” μ•ž chapterμ—μ„œ λ§Œλ“  driverλ₯Ό μž¬μ‚¬μš©ν•œλ‹€.


5. uart.h

#ifndef UART_H
#define UART_H

#include "stm32f4xx.h"

/*

  • Initialize USART3.
  • Board:
  • NUCLEO-F439ZI
    
  • Pin:
  • PD8 β†’ USART3_TX
    
  • PD9 β†’ USART3_RX
    
  • Alternate Function:
  • AF7
    
  • Baud:
  • 115200 bps
    

*/ void uart_init(void);

/*

  • Send a null-terminated string through USART3.
  • Example:
  • uart_write_string("Hello\r\n"); */ void uart_write_string(const char *s);

/*

  • printf redirection hook.
  • This function is useful when the project is built
  • in an environment where newlib/newlib-nano is linked.
  • The standalone bare-metal Make build does not depend
  • on printf, so uart_write_string() is used directly. */ int __io_putchar(int ch);

#endif


6. uart.c

#include <stdint.h>
#include "uart.h"

/*

  • ============================================================
  • RCC Clock Enable Bits
  • ============================================================ */

/*

  • RCC AHB1ENR bit3:
  • Enable GPIOD peripheral clock.
  • PD8 / PD9 cannot be configured until
  • the GPIOD clock is enabled. */ #define GPIODEN (1U << 3)

/*

  • RCC APB1ENR bit18:
  • Enable USART3 peripheral clock. */ #define USART3EN (1U << 18)

/*

  • ============================================================
  • UART Clock / Baud Configuration
  • ============================================================ */

/*

  • Target communication speed. */ #define DBG_UART_BAUDRATE 115200U

/*

  • This Bare-Metal project does not configure the PLL.
  • System clock:
  • HSI = 16 MHz
    

*/ #define SYS_FREQ 16000000U

/*

  • USART3 is connected to APB1.
  • In this project APB1 clock is also 16 MHz. */ #define APB1_CLK SYS_FREQ

/*

  • ============================================================
  • USART Register Bits
  • ============================================================ */

/*

  • USART CR1 bit3:
  • TE = Transmitter Enable
  • 0 β†’ transmitter disabled
  • 1 β†’ transmitter enabled */ #define CR1_TE (1U << 3)

/*

  • USART CR1 bit13:
  • UE = USART Enable
  • 0 β†’ USART disabled
  • 1 β†’ USART enabled */ #define CR1_UE (1U << 13)

/*

  • USART SR bit7:
  • TXE = Transmit Data Register Empty
  • 0 β†’ DR is not ready for new data
  • 1 β†’ next byte may be written to DR */ #define SR_TXE (1U << 7)

/*

  • ============================================================
  • Private Function Prototypes
  • ============================================================ */

/*

  • Send one byte.
  • This is kept static because it is used only
  • inside uart.c. */ static void uart_write(int ch);

/*

  • Calculate BRR value from peripheral clock
  • and target baud rate. */ static uint16_t compute_uart_bd(uint32_t periph_clk, uint32_t baudrate);

/*

  • Program the calculated baud rate into USART3 BRR. */ static void uart_set_baudrate(uint32_t periph_clk, uint32_t baudrate);

/*

  • ============================================================
  • printf Redirection
  • ============================================================ */

int __io_putchar(int ch) { /* * Redirect one character to USART3. */ uart_write(ch);

/*
 * Standard putchar-style function returns
 * the transmitted character.
 */
return ch;

}

/*

  • ============================================================
  • USART3 Initialization
  • ============================================================ */

void uart_init(void) { /* * -------------------------------------------------------- * Step 1. Enable GPIOD Clock * -------------------------------------------------------- * * USART3 VCP pins: * * PD8 β†’ TX * PD9 β†’ RX * * Before configuring these pins, * GPIOD must receive an AHB1 clock. */ RCC->AHB1ENR |= GPIODEN;

/*
 * --------------------------------------------------------
 * Step 2. Configure PD8 as Alternate Function
 * --------------------------------------------------------
 *
 * GPIO MODER uses 2 bits per pin.
 *
 * PD8:
 *
 *     MODER<span>[17:16]</span>
 *
 * Mode:
 *
 *     00 β†’ Input
 *     01 β†’ Output
 *     10 β†’ Alternate Function
 *     11 β†’ Analog
 *
 * First clear the field.
 */
GPIOD-&gt;MODER &amp;= ~(0x3UL &lt;&lt; (8 * 2));

/*
 * Then write 10b.
 *
 * PD8 becomes Alternate Function mode.
 */
GPIOD-&gt;MODER |=  (0x2UL &lt;&lt; (8 * 2));


/*
 * --------------------------------------------------------
 * Step 3. Configure PD9 as Alternate Function
 * --------------------------------------------------------
 *
 * PD9:
 *
 *     MODER<span>[19:18]</span>
 */
GPIOD-&gt;MODER &amp;= ~(0x3UL &lt;&lt; (9 * 2));
GPIOD-&gt;MODER |=  (0x2UL &lt;&lt; (9 * 2));


/*
 * --------------------------------------------------------
 * Step 4. Select AF7 for PD8
 * --------------------------------------------------------
 *
 * AFR register:
 *
 *     AFR<span>[0]</span> β†’ Pin 0 ~ 7
 *     AFR<span>[1]</span> β†’ Pin 8 ~ 15
 *
 * PD8 is therefore controlled by AFR<span>[1]</span>.
 *
 * Each pin uses 4 bits.
 *
 * PD8 position:
 *
 *     (8 - 8) Γ— 4
 *     = bit <span>[3:0]</span>
 *
 * Clear existing AF field first.
 */
GPIOD-&gt;AFR<span>[1]</span> &amp;= ~(0xFUL &lt;&lt; ((8 - 8) * 4));

/*
 * AF7 = 0111b
 *
 * PD8 β†’ USART3_TX
 */
GPIOD-&gt;AFR<span>[1]</span> |=  (0x7UL &lt;&lt; ((8 - 8) * 4));


/*
 * --------------------------------------------------------
 * Step 5. Select AF7 for PD9
 * --------------------------------------------------------
 *
 * PD9 position:
 *
 *     (9 - 8) Γ— 4
 *     = bit <span>[7:4]</span>
 */
GPIOD-&gt;AFR<span>[1]</span> &amp;= ~(0xFUL &lt;&lt; ((9 - 8) * 4));

/*
 * PD9 β†’ AF7 β†’ USART3_RX
 */
GPIOD-&gt;AFR<span>[1]</span> |=  (0x7UL &lt;&lt; ((9 - 8) * 4));


/*
 * --------------------------------------------------------
 * Step 6. Enable USART3 Clock
 * --------------------------------------------------------
 *
 * USART3 belongs to APB1.
 *
 * RCC APB1ENR bit18:
 *
 *     USART3EN = 1
 */
RCC-&gt;APB1ENR |= USART3EN;


/*
 * --------------------------------------------------------
 * Step 7. Configure Baud Rate
 * --------------------------------------------------------
 *
 * Peripheral clock:
 *
 *     16 MHz
 *
 * Baud:
 *
 *     115200 bps
 *
 * Calculated BRR:
 *
 *     approximately 139
 */
uart_set_baudrate(APB1_CLK,
                  DBG_UART_BAUDRATE);


/*
 * --------------------------------------------------------
 * Step 8. Enable Transmitter
 * --------------------------------------------------------
 *
 * This chapter transmits only.
 *
 * TE = 1
 *
 * Note:
 * PD9 is configured for USART3_RX,
 * but RE(receiver enable) is not set here.
 *
 * Therefore actual communication in this exercise
 * is board β†’ PC TX only.
 */
USART3-&gt;CR1 = CR1_TE;


/*
 * --------------------------------------------------------
 * Step 9. Enable USART3
 * --------------------------------------------------------
 *
 * UE = 1
 *
 * USART3 is now operational.
 */
USART3-&gt;CR1 |= CR1_UE;

}

/*

  • ============================================================
  • Send One Character
  • ============================================================ */

static void uart_write(int ch) { /* * -------------------------------------------------------- * Step 1. Wait Until DR Can Accept New Data * -------------------------------------------------------- * * TXE: * * 0 β†’ transmit data register is not ready * 1 β†’ transmit data register is empty * * CPU continuously checks TXE. * * This is polling / busy waiting. / while (!(USART3->SR & SR_TXE)) { / * Wait here until TXE becomes 1. */ }

/*
 * --------------------------------------------------------
 * Step 2. Write Data
 * --------------------------------------------------------
 *
 * Only the lower 8 bits are transmitted.
 */
USART3-&gt;DR = (ch &amp; 0xFF);

}

/*

  • ============================================================
  • Send String
  • ============================================================ */

void uart_write_string(const char s) { / * C string: * * H e l l o \0 * * Continue until null terminator '\0'. */ while (s) { / * Send current character. */ uart_write((int)*s);

    /*
     * Move pointer to next character.
     */
    s++;
}

}

/*

  • ============================================================
  • Baud Rate Calculation
  • ============================================================ */

static uint16_t compute_uart_bd(uint32_t periph_clk, uint32_t baudrate) { /* * Integer arithmetic would normally truncate * the fractional part. * * Adding baudrate / 2 before division gives * a rounding effect. * * Example: * * periph_clk = 16,000,000 * baudrate = 115,200 * * BRR = * * (16,000,000 + 57,600) * -------------------- * 115,200 * * β‰ˆ 139 */ return (uint16_t) ((periph_clk + (baudrate / 2U)) / baudrate); }

/*

  • ============================================================
  • Program Baud Rate Register
  • ============================================================ */

static void uart_set_baudrate(uint32_t periph_clk, uint32_t baudrate) { /* * Store the calculated divider into BRR. */ USART3->BRR = compute_uart_bd(periph_clk, baudrate); }


7. main.c

#include "gpio.h"
#include "systick.h"
#include "uart.h"

int main(void) { /* * -------------------------------------------------------- * Step 1. Initialize LD1 * -------------------------------------------------------- * * NUCLEO-F439ZI: * * LD1 β†’ PB0 */ led_init();

/*
 * --------------------------------------------------------
 * Step 2. Initialize USART3
 * --------------------------------------------------------
 *
 * Configuration:
 *
 *     USART3
 *     PD8  β†’ TX
 *     PD9  β†’ RX pin mapping
 *     AF7
 *     115200 bps
 */
uart_init();


while (1)
{
    /*
     * ----------------------------------------------------
     * Step 3. Send String to PC
     * ----------------------------------------------------
     *
     * uart_write_string() sends the string
     * one character at a time.
     *
     * '\r\n':
     *
     *     \r β†’ Carriage Return
     *     \n β†’ Line Feed
     *
     * Terminal output moves to the next line.
     */
    uart_write_string(
        "Hello from NUCLEO-F439ZI! "
        "(USART3, 115200bps)\r\n"
    );


    /*
     * ----------------------------------------------------
     * Step 4. Toggle LD1
     * ----------------------------------------------------
     *
     * Provides a visual indication that
     * the main loop is running.
     */
    led_toggle();


    /*
     * ----------------------------------------------------
     * Step 5. Wait 1 Second
     * ----------------------------------------------------
     *
     * Ch08 SysTick driver is reused.
     */
    systick_msec_delay(1000);
}

}


8. UART Initialization Flow

전체 μ΄ˆκΈ°ν™” μˆœμ„œ:

uart_init()
β”‚
β”œβ”€β”€ GPIOD Clock Enable
β”‚
β”œβ”€β”€ PD8 β†’ Alternate Function
β”‚
β”œβ”€β”€ PD9 β†’ Alternate Function
β”‚
β”œβ”€β”€ PD8 β†’ AF7
β”‚
β”œβ”€β”€ PD9 β†’ AF7
β”‚
β”œβ”€β”€ USART3 Clock Enable
β”‚
β”œβ”€β”€ BRR = 139
β”‚
β”œβ”€β”€ TE = 1
β”‚
└── UE = 1

이후:

USART3 Ready

μƒνƒœκ°€ λœλ‹€.


9. Why Alternate Function?

GPIO pin ν•˜λ‚˜λŠ” GPIO κΈ°λŠ₯만 μˆ˜ν–‰ν•˜λŠ” 것이 μ•„λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ PD8은 섀정에 따라 μ—¬λŸ¬ peripheral function으둜 연결될 수 μžˆλ‹€.

PD8
β”‚
β”œβ”€β”€ GPIO
β”œβ”€β”€ USART
β”œβ”€β”€ Timer
└── Other Peripheral

MODER=10은:

이 pin을 GPIO output으둜 직접 μ“°μ§€ μ•Šκ³ 
Peripheralμ—κ²Œ λ„˜κΈ°κ² λ‹€

λŠ” μ˜λ―Έλ‹€.

κ·Έ ν›„:

GPIOD->AFR[1] = ...

μ—μ„œ μ–΄λ–€ peripheral function을 μ—°κ²°ν• μ§€ μ„ νƒν•œλ‹€.

이번 μ„€μ •:

PD8
↓
Alternate Function Mode
↓
AF7
↓
USART3_TX

10. Why AFR[1]?

Alternate Function registerλŠ” 두 κ°œλ‹€.

AFR[0]
β†’ Pin 0 ~ 7

AFR[1] β†’ Pin 8 ~ 15

PD8κ³Ό PD9λŠ” λͺ¨λ‘ pin numberκ°€ 8 이상이닀.

λ”°λΌμ„œ:

GPIOD->AFR[1]

을 μ‚¬μš©ν•œλ‹€.

PD8 field:

AFR[1][3:0]

PD9 field:

AFR[1][7:4]

κ·Έλž˜μ„œ μ½”λ“œκ°€:

((8 - 8) * 4)
((9 - 8) * 4)

ν˜•νƒœκ°€ λœλ‹€.


11. Character Transmission

문자 'A'λ₯Ό 보낸닀고 κ°€μ •ν•œλ‹€.

ASCII:

'A'

0x41

호좜:

uart_write('A');

흐름:

CPU
↓
TXE 확인
↓
TXE = 1
↓
USART3->DR = 0x41
↓
USART Hardware
↓
Serial Frame 생성
↓
PD8 TX
↓
ST-LINK VCP
↓
PC Terminal
↓
A

12. TXE Polling

핡심:

while (!(USART3->SR & SR_TXE))
{
}

CPUκ°€ 계속:

TXE?
↓
0 β†’ κΈ°λ‹€λ¦Ό
↓
0 β†’ κΈ°λ‹€λ¦Ό
↓
1 β†’ λ‹€μŒ data write

λ₯Ό μˆ˜ν–‰ν•œλ‹€.

μ—¬κΈ°μ„œ TXE의 μ •ν™•ν•œ μ˜λ―ΈλŠ”:

Transmit Data Register Empty

이닀.

즉:

λ‹€μŒ byteλ₯Ό DR에 μ“Έ 수 μžˆλ‹€

λŠ” λœ»μ΄λ‹€.

TXE와 **전체 serial frame 전솑 μ™„λ£Œλ₯Ό μ˜λ―Έν•˜λŠ” TC**λŠ” ꡬ뢄해야 ν•œλ‹€.

이번 λ¬Έμžμ—΄ 연속 μ†‘μ‹ μ—μ„œλŠ”:

TXE

λ₯Ό μ΄μš©ν•˜λ©΄ λ‹€μŒ characterλ₯Ό μ—°μ†ν•΄μ„œ 곡급할 수 μžˆλ‹€.


13. String Transmission

uart_write_string("ABC");

memory:

'A' 'B' 'C' '\0'
↑
s

첫 번째 loop:

*s = 'A'
β†’ uart_write('A')
β†’ s++

두 번째:

*s = 'B'
β†’ uart_write('B')
β†’ s++

μ„Έ 번째:

*s = 'C'
β†’ uart_write('C')
β†’ s++

λ§ˆμ§€λ§‰:

*s = '\0'

이면:

while (*s)

쑰건이 falseκ°€ λ˜μ–΄ μ’…λ£Œλœλ‹€.


14. Why No printf()?

ν˜„μž¬ bare-metal Make buildλŠ” ν‘œμ€€ library μ˜μ‘΄μ„±μ„ μ΅œμ†Œν™”ν•œλ‹€.

λ”°λΌμ„œ λ‹¨μˆœ 좜λ ₯μ—λŠ”:

uart_write_string()

을 직접 μ‚¬μš©ν•œλ‹€.

μž₯점:

μž‘μ€ μ½”λ“œ
λͺ…ν™•ν•œ μ‹€ν–‰ 흐름
Library dependency μ΅œμ†Œν™”
UART hardware λ™μž‘ 직접 확인

__io_putchar()λŠ” 이후 newlib/newlib-nanoκ°€ μ—°κ²°λœ ν™˜κ²½μ—μ„œ printf() redirection에 ν™œμš©ν•  수 μžˆλ„λ‘ 남겨둔 ν•¨μˆ˜λ‹€.


15. TX Only in This Practice

PD9κΉŒμ§€ AF7둜 μ„€μ •ν•˜μ§€λ§Œ ν˜„μž¬ CR1μ—λŠ”:

TE

만 enableν•œλ‹€.

즉:

Transmitter Enable
= YES

Receiver Enable = NO

이닀.

λ”°λΌμ„œ ν˜„μž¬ κΈ°λŠ₯:

Board
↓
PC

단방ν–₯이닀.

RXκΉŒμ§€ μ‚¬μš©ν•˜λ €λ©΄ 이후:

CR1.RE
SR.RXNE
DR Read

등이 μΆ”κ°€λ‘œ ν•„μš”ν•˜λ‹€.


16. Runtime Flow

main()
β”‚
β”œβ”€β”€ led_init()
β”‚
β”œβ”€β”€ uart_init()
β”‚
└── while(1)
β”‚
β”œβ”€β”€ uart_write_string()
β”‚      β”‚
β”‚      β”œβ”€β”€ TXE wait
β”‚      β”œβ”€β”€ DR write
β”‚      β”œβ”€β”€ TXE wait
β”‚      β”œβ”€β”€ DR write
β”‚      └── ...
β”‚
β”œβ”€β”€ LED toggle
β”‚
β”œβ”€β”€ SysTick 1000 ms
β”‚
└── Repeat

17. Hardware Data Flow

CPU
β”‚
β”‚ write
β–Ό
USART3->DR
β”‚
β–Ό
USART3 Transmitter
β”‚
β–Ό
PD8 / AF7
β”‚
β–Ό
ST-LINK VCP
β”‚
β–Ό
USB
β”‚
β–Ό
PC Terminal

18. Build Result

κΈ°μ‘΄ μ‹€μŠ΅ κ²°κ³Ό:

text = 1168 bytes
data = 0 bytes
bss  = 2560 bytes

κ²½κ³  없이 buildλ˜μ—ˆκ³ , μ‹€μ œ NUCLEO-F439ZI에 download/runν•˜μ—¬ VCP 115200-8-N-1μ—μ„œ 1μ΄ˆλ§ˆλ‹€ λ¬Έμžμ—΄ 좜λ ₯κ³Ό LD1 toggle을 ν™•μΈν–ˆλ‹€.


19. Verification

Build

make clean
make

Expected:

Build PASS

text = 1168 data = 0 bss = 2560


Debugger β€” GPIO

확인:

GPIOD->MODER
GPIOD->AFR[1]

Expected:

PD8 MODER = 10
PD9 MODER = 10

PD8 AF = 7 PD9 AF = 7


Debugger β€” USART

확인:

USART3->BRR
USART3->CR1
USART3->SR

Expected:

BRR β‰ˆ 139

CR1.TE = 1 CR1.UE = 1

TX λ™μž‘ 쀑:

SR.TXE

λ³€ν™”λ₯Ό 확인할 수 μžˆλ‹€.


PC Terminal

Terminal configuration:

Baud Rate : 115200
Data Bits : 8
Parity    : None
Stop Bits : 1
Flow Ctrl : None

즉:

115200-8-N-1

Expected output:

Hello from NUCLEO-F439ZI! (USART3, 115200bps)
Hello from NUCLEO-F439ZI! (USART3, 115200bps)
Hello from NUCLEO-F439ZI! (USART3, 115200bps)
...

μ•½ 1초 κ°„κ²©μœΌλ‘œ 좜λ ₯λœλ‹€.


20. If Nothing Appears

κ°€μž₯ λ¨Όμ € 확인할 λΆ€λΆ„:

Board
β†’ F439ZI λ§žλŠ”κ°€?

USART β†’ USART3인가?

TX β†’ PD8인가?

AF β†’ AF7인가?

AFR β†’ AFR[1]인가?

Clock β†’ APB1 USART3EN bit18인가?

Baud β†’ 115200인가?

Terminal β†’ μ˜¬λ°”λ₯Έ ST-LINK COM Port인가?

특히 μ›μ„œμ˜:

USART2 / PA2

λ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©ν•˜λ©΄ F439ZI VCPμ—μ„œλŠ” 좜λ ₯이 보이지 μ•ŠλŠ” 것이 핡심 porting issueλ‹€.


21. Screenshots to Add

images/ch10_build.png
images/ch10_gpio_af.png
images/ch10_usart_registers.png
images/ch10_terminal.png
images/ch10_board_led.gif

κ°€μž₯ μ€‘μš”ν•œ 증거:

USART3 Register
+
115200 Terminal Output
+
LD1 Toggle

22. Key Points

GPIOD Clock
↓
PD8 / PD9 AF Mode
↓
AF7
↓
USART3 Clock
↓
BRR = 139
↓
TE + UE
↓
TXE Polling
↓
DR Write
↓
PD8
↓
PC
  • NUCLEO-F439ZI의 ST-LINK VCPλŠ” USART3λ₯Ό μ‚¬μš©ν•œλ‹€.

  • USART3 TXλŠ” PD8, RXλŠ” PD9λ‹€.

  • PD8/PD9λŠ” AF7둜 μ„€μ •ν•œλ‹€.

  • Pin 8~15λŠ” AFR[1]을 μ‚¬μš©ν•œλ‹€.

  • USART3λŠ” APB1 peripheral이닀.

  • 이번 project clock은 16MHzλ‹€.

  • 115200bpsμ—μ„œ BRR은 μ•½ 139λ‹€.

  • CR1.TEλŠ” transmitterλ₯Ό enableν•œλ‹€.

  • CR1.UEλŠ” USART peripheral 자체λ₯Ό enableν•œλ‹€.

  • SR.TXEλŠ” λ‹€μŒ dataλ₯Ό DR에 μ“Έ 수 μžˆμŒμ„ λ‚˜νƒ€λ‚Έλ‹€.

  • λ¬Έμžμ—΄μ€ ν•œ characterμ”© TXEλ₯Ό pollingν•˜λ©° μ „μ†‘ν•œλ‹€.

  • 이번 μ‹€μŠ΅μ€ TX-only communication이닀.

  • μ‹€μ œ boardμ—μ„œ VCP 115200-8-N-1 좜λ ₯κΉŒμ§€ κ²€μ¦ν–ˆλ‹€.

⚠️ **GitHub.com Fallback** ⚠️