USART1 / UART User Description
공식 USART1 clock·control·data·status 흐름을 현재 System Trainer의 독립 External UART TX → PA10 / UART_RX 경로와 연결합니다. NTC 온도 분압 노드는 별도 PB0/ADC1_IN8 입력입니다.
USART1 Datasheet 현재 Trainer 실행 예제 RCC Datasheet GPIO User Description Lab Guide
1. 그림에서 먼저 보기
Figure 1은 RM0008 블록도처럼 위쪽의 DR·shift register 데이터 경로에서 아래쪽의 CR1·BRR·SR 제어 경로로 읽습니다. 작은 1–6 표시는 User Description의 표와 연결하기 위한 흑백 학습 주석이며 기본 Datasheet 그림에는 표시되지 않습니다. Figure 2에서 8‑N‑1 한 프레임을 보고, Figure 3에서 TXE와 TC의 시간 차이를 확인합니다.
1
2
3
4
5
6
Figure 1. RM0008 형식으로 축약한 USART1 데이터·제어 경로
RM0008 Rev 21 Figure 279, Sections 27.3.2–27.3.4, RCC/AFIO controls와 DS5319 Rev 20 Table 5를 재구성했습니다. 1–6 번호는 이 페이지에만 얹는 학습 주석이며, 특수 모드·DMA·flow control·interrupt route는 첫 실습 그림에서 제외했습니다.
Figure 2. 첫 실습의 8‑N‑1 프레임
RM0008 Rev 21 Figure 280과 Section 27.3.1을 바탕으로 M=0, PCE=0, STOP=00만 남겼습니다. Trainer panel은 이 형식의 CMD byte와 DATA byte를 차례로 보여 줍니다.
Figure 3. 다음 byte를 쓰는 TXE와 선로 전송 완료를 뜻하는 TC
RM0008 Rev 21 Sections 27.3.2와 27.6.1의 TDR·shift register·TXE·TC 관계를 실습 판단 기준만 남겨 재구성했습니다. 현재 Trainer는 shift-register busy 시간을 모델링하지 않아 DR write 직후 두 flag를 모두 1로 둡니다.
2. RM0008은 이 순서로 읽기
표의 페이지는 RM0008 Rev.21 문서 하단 인쇄 번호 기준입니다. PDF viewer 번호가 다르면 Section 제목을 함께 검색합니다.
| 회독 | 페이지 / Section | 실습에서 확인할 것 |
|---|---|---|
| 준비 | p.45 p.90–121 p.159–172 | r, rw, rc_w0 표기, PCLK2와 USART1EN·IOPAEN, PA9 AF Push-pull·PA10 Input을 찾습니다. Remap이 필요할 때만 p.180과 p.184를 봅니다. |
| 1차 | p.785–790 27.1–27.3.1 | 기능 이름은 훑고, Figure 279의 DR·shift register 데이터 흐름과 Figure 280의 8‑N‑1 frame을 이해합니다. |
| 핵심 | p.791–799 27.3.2–27.3.4 | 송신 순서, TXE / TC 차이, RXNE / ORE / FE / NE / PE / IDLE, BRR 계산을 읽습니다. |
| 2차 | p.800 p.802 | clock tolerance와 parity가 word length 안에 포함되는 규칙을 확인합니다. |
| 나중 | p.803–814 | LIN, synchronous, half-duplex, smartcard, IrDA, DMA는 첫 실습에서 생략합니다. |
3. 블록 → 레지스터 비트
| 그림 블록 | 레지스터 | 필드 / bit | 그림에서 하는 일 / 값 의미 | 지원 여부 |
|---|---|---|---|---|
| 1Figure 1 peripheral and pin clock prerequisites | ||||
| USART1 peripheral clock gate | RCC_APB2ENR | USART1EN[14] | 그림에서: APB2 clock을 USART1 block에 공급합니다.0 = USART1 clock 차단1 = USART1 clock 공급현재 구현에서도 RX frame 수신과 DR TX write effect의 필수 gate입니다. | 지원됨 |
| GPIOA configuration clock gate | RCC_APB2ENR | IOPAEN[2] | 그림에서: 공식 PA9/PA10 GPIO configuration register path를 엽니다.0 = GPIOA configuration clock 차단, RX/TX 거부1 = GPIOA configuration clock 공급현재 구현도 IOPAEN과 GPIOA_CRH의 PA9/PA10 pad mode를 RX/TX accept 조건으로 검사합니다. | 지원됨 |
| PA9 transmit pad | GPIOA_CRH | CNF9[7:6] / MODE9[5:4] | 그림에서: USART1 transmit path를 PA9 alternate-function output에 연결합니다.CNF9=10, MODE9≠00 = alternate-function push-pull output현재 구현은 이 mode와 IOPAEN·USART1EN·BRR·UE·TE가 모두 맞을 때 DR write를 TX log에 기록합니다. PA9 physical waveform은 그리지 않습니다. | 지원됨 |
| PA10 receive pad | GPIOA_CRH | CNF10[11:10] / MODE10[9:8] | 그림에서: 외부 UART RX level을 PA10 input path로 전달합니다.MODE10=00, CNF10=01 = floating inputMODE10=00, CNF10=10 = pull input현재 구현은 두 digital-input form을 허용하며 analog/output mode에서는 frame을 거부합니다. | 지원됨 |
| 2Figure 1 USART1_CR1 controls | ||||
| USART enable | USART1_CR1 | UE[13] | 그림에서: USART1 transmitter와 receiver control을 활성화할 수 있게 합니다.0 = USART 비활성화1 = USART 활성화현재 구현의 RX와 TX 모두 UE를 요구합니다. | 지원됨 |
| Transmitter enable | USART1_CR1 | TE[3] | 그림에서: DR write가 transmit path로 이동할 수 있게 합니다.0 = transmitter 비활성화1 = transmitter 활성화현재 구현에서는 UE·TE·USART1EN이 모두 1일 때 low byte를 TX log에 기록합니다. | 지원됨 |
| Receiver enable | USART1_CR1 | RE[2] | 그림에서: PA10 receive path가 start bit와 data를 받을 수 있게 합니다.0 = receiver 비활성화1 = receiver 활성화현재 구현에서는 UE·RE·USART1EN이 모두 1일 때 Send Frame 입력을 받습니다. | 지원됨 |
| USART interrupt gates | USART1_CR1 | RXNEIE[5] / TCIE[6] / TXEIE[7] | 그림에서: RXNE, TC, TXE flag를 USART interrupt request에 연결합니다.0 = 해당 flag interrupt 억제1 = 해당 flag interrupt 허용현재 구현은 polling만 사용합니다. | 미지원 |
| 3Figure 1 baud-rate divider | ||||
| Baud divider | USART1_BRR | DIV_MANTISSA[15:4] / DIV_FRACTION[3:0] | 그림에서: peripheral clock을 16 × USARTDIV로 나눠 TX/RX bit rate를 정합니다.0x0000 = Trainer RX/TX 거부0x1D4C 72 MHz PCLK2에서 USARTDIV 468.75, 9600 baud현재 구현은 nonzero BRR을 요구하고 값을 저장·표시합니다. UI animation timing은 BRR에서 계산하지 않습니다. | 지원됨 |
| 4Figure 1 transmit data path | ||||
| Transmit data write | USART1_DR | DR[8:0] | 그림에서: software가 쓴 data를 transmit data register와 shift register를 거쳐 PA9로 보냅니다.DR = n 공식 hardware는 8/9-bit frame data를 전송현재 구현은 low 8 bit를 즉시 TX log에 남기며 PA9 physical waveform은 그리지 않습니다. | 지원됨 |
| 5Figure 1 receive data path | ||||
| Receive data read | USART1_DR | DR[8:0] | 그림에서: receive shift register에서 옮겨진 data word를 software가 읽습니다.DR = n 공식 hardware의 8/9-bit received data현재 수신 패널은 교육용으로 CMD[15:8]:DATA[7:0] 16-bit frame을 DR에 overlay하며, read 후 RXNE와 legacy ready alias를 지웁니다. | 지원됨 |
| 6Figure 1 USART1_SR status flags | ||||
| Receive data ready | USART1_SR | RXNE[5] | 그림에서: receive data register에 software가 읽을 data가 있음을 알립니다.0 = unread receive data 없음1 = unread receive data 있음현재 구현은 accepted Send Frame에서 set하고 DR read에서 clear합니다. | 지원됨 |
| Transmit-ready status | USART1_SR | TXE[7] / TC[6] | 그림에서: transmit data register empty와 frame transmission complete 상태를 알립니다.TXE = 0 다음 data write 준비 안 됨TXE = 1 다음 data write 가능TC = 0 transmission 미완료TC = 1 transmission 완료현재 구현은 shift-register busy interval 없이 DR write를 즉시 처리해 TXE와 TC를 계속 1로 둡니다. | 지원됨 |
| Frame error status | USART1_SR | FE[1] | 그림에서: 공식 hardware가 stop-bit/framing 오류를 감지했음을 알립니다.0 = framing error 없음1 = framing error 있음현재 구현은 실제 frame sampling 대신 USART clock/RX enable이 꺼진 상태에서 Send Frame을 거부할 때 FE를 사용합니다. | 지원됨 |
| Error flags | USART1_SR | ORE[3] / NE[2] | 그림에서: receive overrun과 noise detection 상태를 알립니다.0 = 해당 error 없음1 = 해당 error 감지현재 헤더에는 ORE mask가 있지만 overrun/noise 생성과 공식 clear sequence는 모델링하지 않습니다. | 미지원 |
| Parity error / legacy overlay | USART1_SR | PE[0] | 그림에서: 공식 hardware의 parity error 상태입니다.0 = parity error 없음1 = parity error 감지현재 구현은 bit 0을 오래된 lesson용 RX-ready alias로 겹쳐 쓰므로 공식 PE로 해석하면 안 됩니다. | 미지원 |
4. 표 기준 단순 코드
| 현재 코드 / 값 | 데이터시트 필드로 해석 | 화면에서 확인 |
|---|---|---|
| RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN | IOPAEN[2] = 1, USART1EN[14] = 1: PA10 RX GPIO와 peripheral clock | Registers → Clock |
| GPIOA_CRH PA10 = 0x4 | PA10 floating input. 현재 실행 예제는 PA9 송신 핀을 설정하지 않습니다. | Code Watch, Board · Lab pin routes |
| USART1->BRR = 0x1D4Cu | DIV_MANTISSA[15:4] = 0x1D4, DIV_FRACTION[3:0] = 0xC: 72 MHz / 9600 baud | Code Watch |
| USART1->CR1 = USART1_CR1_UE | USART1_CR1_RE | UE[13] = 1, RE[2] = 1, TE[3] = 0 | Registers의 USART1_CR1 |
| read_reg(USART1_SR) & USART1_SR_RXNE | USART1_SR.RXNE[5] polling | Registers, UART Send / Decode |
| frame = read_reg(USART1_DR) | 공식 DR read + 현재 구현의 CMD:DATA overlay consume | Code Watch, Graph, Docs / Log |
| g_uart_last_cmd = frame >> 8 g_uart_last_data = frame & 0xFF | 포인터 인자 없이 학생 코드가 바로 읽는 최신 전역 API입니다. Trainer 전용 packed-frame 해석입니다. 실제 STM32F103은 CMD와 DATA를 각각의 RXNE/DR read 순서로 받아야 합니다. | Code Watch의 PA10_UART_RX_CMD·DATA, UART Send / Decode |
5. 현재 Trainer 실행 예제
FW EDIT에 그대로 붙여넣는 PA10 RX-only 예제입니다. 현재 제공 코드와 같은 USART1->SR/DR API를 사용하며 TX는 켜지 않습니다.
#include "training_api.h"
volatile uint32_t g_uart_last_cmd = 0u;
volatile uint32_t g_uart_last_data = 0u;
static void uart_rx_init(void)
{
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; /* USART User Description 1번: USART1 clock gate */
GPIOA->CRH = (GPIOA->CRH & ~(0xFu << 8)) | (0x4u << 8); /* GPIO UD 4번: PA10 floating input */
USART1->BRR = 0x1D4Cu; /* USART User Description 3번: 72 MHz / 9600 baud */
USART1->CR1 = USART1_CR1_UE | USART1_CR1_RE; /* USART User Description 2번: RX-only enable */
}
static uint32_t uart_rx_read(void)
{
uint32_t frame;
if ((USART1->SR & USART1_SR_RXNE) == 0u) return 0u; /* USART User Description 5번: 수신 완료 확인 */
frame = USART1->DR; /* USART User Description 5번: 수신 data read, RXNE clear */
g_uart_last_cmd = (frame >> 8) & 0xFFu;
g_uart_last_data = frame & 0xFFu;
return 1u;
}
void user_init(void)
{
trainer_clock_init_72mhz(); /* RCC User Description 1~4번 */
RCC->APB2ENR = RCC_APB2ENR_IOPAEN; /* USART User Description 1번: PA10 GPIOA gate */
uart_rx_init(); /* USART User Description 1~3번·5번 */
}
void user_loop(void)
{
uart_rx_read();
watch_u32("PA10_UART_RX_CMD", g_uart_last_cmd);
watch_u32("PA10_UART_RX_DATA", g_uart_last_data);
watch_u32("USART1_BRR", USART1->BRR);
watch_u32("USART1_SR", USART1->SR);
watch_u32("USART1_CR1", USART1->CR1);
}
6. 사이트에서 확인
바로 위 실행 예제의 PA10 RX 초기화, CMD·DATA 분리와 Watch 값을 아래 화면에서 확인합니다.
- Registers: Clock의 IOPAEN·USART1EN, GPIOA_CRH의 PA10 input, USART1_BRR·CR1·SR·DR 행을 한 화면에서 확인합니다.
- Board · Lab pin routes: UART INPUT TX가 PA10 / UART_RX 단자에 정확히 닿고, NTC 분압 노드는 PB0로 별도 연결되는지 확인합니다.
- Graph: PA10/UART_RX를 선택하면 trace 목록에 자동으로 추가되며 Idle High, start, data, stop waveform을 확인합니다.
- System: PB0 NTC 온도값이 UART frame과 독립적으로 유지되고, UART receiver 상태와 마지막 CMD/DATA만 전송 frame을 나타내는지 확인합니다.
- Code Watch: 위 예제의 PA10_UART_RX_CMD와 PA10_UART_RX_DATA에서 수신한 두 바이트를 확인합니다. 이 예제는 FRAME·COUNT Watch를 출력하지 않습니다.
- Docs / Log: UART bit, RX complete, DR read 메시지 계열을 확인합니다.
7. 현재 구현 범위
| 항목 | 공식 STM32 의미 | 현재 구현 범위 | 지원 여부 |
|---|---|---|---|
| GPIOA_CRH / IOPAEN | PA9 TX, PA10 RX pad mode와 GPIOA configuration clock | PA10 digital input과 IOPAEN을 RX accept 조건으로, PA9 alternate-function output과 IOPAEN을 TX accept 조건으로 검사합니다. | 지원됨 |
| AFIO_MAPR.USART1_REMAP | USART1 TX/RX를 PB6/PB7로 remap | AFIOEN은 저장·표시되지만 remap register와 PB6/PB7 UART route는 없습니다. | 미지원 |
| USART1_SR.PE[0] | 공식 parity error flag | bit 0은 legacy RX-ready alias이므로 공식 PE 의미로 해석하지 않습니다. | 미지원 |
| USART1_CR1.SBK[0] | 공식 send-break command | bit 0은 legacy RXEN alias로도 받아들입니다. 새 코드는 반드시 UE | RE를 사용합니다. | 미지원 |
| USART interrupt route | RXNEIE·TCIE·TXEIE와 USART1 interrupt handler | 현재 실습은 SR polling만 실행합니다. | 미지원 |
| PA9 USART1_TX | shift register가 physical TX pin을 구동 | low-byte TX log만 제공하며 PA9 physical waveform/Graph route는 없습니다. | 미지원 |