微處理器 - STMicroelectronics STM32F103 - Assembly - UART



參考資料:
https://www.st.com/resource/en/reference_manual/cd00171190-stm32f101xx-stm32f102xx-stm32f103xx-stm32f105xx-and-stm32f107xx-advanced-arm-based-32-bit-mcus-stmicroelectronics.pdf

RCC_APB2ENR暫存器,需要開啟IOPA、USART1EN、AFIOEN的Clock


UART1_TX是位於PA9、UART1_RX則是PA10


UART暫存器




Baudrate計算方式如下:

Baudrate = PLL2 / (16 * DIV) = 128000000 / (16 * 69.44)

main.s

    .thumb
    .cpu cortex-m3
    .syntax unified

    .equiv GPIOA_CRL,   0x40010800
    .equiv GPIOA_CRH,   0x40010804
    .equiv GPIOA_IDR,   0x40010808
    .equiv GPIOA_ODR,   0x4001080c

    .equiv GPIOC_CRL,   0x40011000
    .equiv GPIOC_CRH,   0x40011004
    .equiv GPIOC_IDR,   0x40011008
    .equiv GPIOC_ODR,   0x4001100c

    .equiv RCC_CR,      0x40021000
    .equiv RCC_CFGR,    0x40021004
    .equiv RCC_APB2ENR, 0x40021018

    .equiv FLASH_ACR,   0x40022000

    .equiv UART1_SR,    0x40013800
    .equiv UART1_DR,    0x40013804
    .equiv UART1_BRR,   0x40013808
    .equiv UART1_CR1,   0x4001380c
    .equiv UART1_CR2,   0x40013810
    .equiv UART1_CR3,   0x40013814

    .equiv STACKINIT,   0x20005000

    .global _start
    .section .text

    .org 0x0
    .word STACKINIT
    .word _start

    .org 0x100
    .align 2
    .thumb_func
_start:
    bl rcc_init
    bl flash_init
    bl uart_init

    ldr r4, =hello
0:
    ldrb r0, [r4]
    cmp r0, #0
    beq 1f
    bl uart_byte
    add r4, #1
    bne 0b
1:
    b .
    
    .align 2
    .thumb_func
uart_init:
    push {r4, lr}
    ldr r4, =RCC_APB2ENR
    ldr r1, [r4]
    ldr r2, =(1 << 14) | (1 << 2) | (1 << 0)
    orr r1, r2
    str r1, [r4]

    ldr r4, =GPIOA_CRH
    ldr r1, [r4]
    bic r1, #0xff0
    orr r1, #0x4b0
    str r1, [r4]

    ldr r4, =UART1_BRR
    @ldr r1, =(39 << 4) | (1 << 0) @ 115200bps 72MHz
    ldr r1, =(69 << 4) | (7 << 0) @ 115200bps 128MHz
    str r1, [r4]

    ldr r4, =UART1_CR1
    ldr r1, =(1 << 13) | (1 << 3)
    str r1, [r4]
    pop {r4, pc}
    
    .align 2
    .thumb_func
uart_byte:
    push {r4, lr}
    ldr r4, =UART1_SR
0:
    ldr r1, [r4]
    tst r1, #(1 << 7)
    beq 0b

    ldr r4, =UART1_DR
    str r0, [r4]
    pop {r4, pc}
    
    .align 2
    .thumb_func
rcc_init:
    push {r4, lr}
    ldr r4, =RCC_CR
    ldr r1, =(1 << 26) | (1 << 16)
    str r1, [r4]
0:
    ldr r1, [r4]
    tst r1, #(1 << 17)
    bne 0b

    ldr r4, =RCC_CFGR
    @mov r1, #(7 << 18) @ 72MHz
    mov r1, #(14 << 18) @ 128MHz
    orr r1, #(1 << 16)
    str r1, [r4]

    ldr r4, =RCC_CR
    ldr r1, [r4]
    orr r1, #(1 << 24)
    str r1, [r4]
0:
    ldr r1, [r4]
    tst r1, #(1 << 25)
    bne 0b

    ldr r4, =RCC_CFGR
    ldr r1, [r4]
    orr r1, #2
    str r1, [r4]
0:
    ldr r1, [r4]
    tst r1, #(1 << 3)
    bne 0b
    pop {r4, pc}

    .align
    .thumb_func
flash_init:
    push {r4, lr}
    ldr r4, =FLASH_ACR
    mov r1, #0x32
    str r1, [r4]
    pop {r4, pc}

    .align
hello: .asciz "Hello, world!"
    .end

完成