cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f401re nucleo: USART programming

life758
Associate II
Posted on November 16, 2015 at 11:38

Hello everybody,

I'm new on the forum and on ST microcontrollers.

I'm trying to program the USART in assembly, but I have some issue to write on DR.

What am I missing? Somebody can help me, please?

*********************************************

        SECTION MYDATA:CONST

        DATA

TDR     DCB     ''HELLO WORLD!\r''

; statup code

..

..

ldr     r0, =0x40023800         ; RCC

        

        ldr     r1, [r0, #0x10]         ; RCC_AHB1RSTR

        bic     r1, r1, #1

        str     r1, [r0, #0x10]

        

        ldr     r1, [r0, #0x30]         ; RCC_AHB1ENR

        orr     r1, r1, #1

        str     r1, [r0, #0x30]

        

        ldr     r1, [r0, #0x24]         ; RCC_APB2RSTR

        bic     r1, r1, #(1 << 4)

        str     r1, [r0, #0x24]

        

        ldr     r1, [r0, #0x44]         ; RCC_APB2ENR

        orr     r1, r1, #(1 << 4)

        str     r1, [r0, #0x44]

        

        ldr     r0, =0x40020000         ; Configurazione della GPIOA

        

        ldr     r1, [r0]                ; GPIOA_MODER

        bic     r1, r1, #(15 << 2*9)    ; Mask PA9/10

        orr     r1, r1, #(10 << 2*9)    ; =AF mode

        str     r1, [r0]

        

        ldr     r1, [r0, #0x4]          ; GPIOA_OTYPER

        bic     r1, r1, #(3 << 9)       ; Mask PA9/10, 0= push pull

        str     r1, [r0, #0x4]

        

        ldr     r1, [r0, #0x8]          ; GPIOA_OSPEEDR

        bic     r1, r1, #(15 << 2*9)    ; Mask PA9/10

        orr     r1, r1, #(10 << 2*9)    ; =fast speed

        str     r1, [r0, #0x8]

        

        ldr     r1, [r0, #0xC]          ; GPIOA_PUPDR

        bic     r1, r1, #(15 << 2*9)    ; Mask PA9/10. =no pull

        ;orr     r1, r1, #(5 << 2*9)    ; =pull-up

        str     r1, [r0, #0xC]

        

        ldr     r1, [r0, #0x24]         ; GPIOA_AFRH

        bic     r1, r1, #(0xFF << 4*1)  ; Mask PA9/10

        orr     r1, r1, #(0x77 << 4*1)  ; =AF7, USART1

        str     r1, [r0, #0x24]

        

        

        ; Init_USART1

                                        ;

                                        ;

        ldr     r0, =0x40011000         ; USART1

        

        ldr     r1, =0xC00080           ; =reset value

        str     r1, [r0]                ; SR

        

        ldr     r1, =0x683              ; =USARTDIV. per ottenere 9600bps a partire da HSI

        str     r1, [r0, #0x8]          ; BRR

        

        ldr     r1, =0                  ; =reset value

        str     r1, [r0, #0x10]         ; CR2. 1 stop bit

        

        ldr     r1, =0x8

        str     r1, [r0, #0x14]         ; CR3. =half-duplex selected

        

        ldr     r1, =0

        str     r1, [r0, #0x18]         ; GTPR. =reset value        

        

        ldr     r1, =0x2088             ; CR1. over=16, data bits=8, TE=1, TXEIE=1

        str     r1, [r0, #0xC]

        

            

        B       main

        

        

        SECTION .text:CODE:NOROOT(2)

        THUMB

        

main    NOP

        LDR     r2, =TDR                ; carico in r2 l'indirizzo della base

                                        ; di memoria in cui è memorizzata la

                                        ; stringa ''HELLO WORLD!''

polling

        ldr     r1, [r0]                ; USART1_SR

        ands    r1, r1, #(1 << 7)       ; se TXE=0 rimane nel polling

        beq     polling

        ldrb    r3, [r2], #1            ; carica il valore puntato da r2 e poi r2++ (byte)

        cmp     r3, #'\r'

        beq     main                    ; se sono uguali salta l'istruzione di memorizzare in USART1_DR

        ldr     r4, [r0]

        strh    r3, [r0, #0x4]          ; scrive il dato da trasmettere nello USART1_DR

        B       polling

*********************************************

ps: I'm modify the startup code given by ST

pps: I'm using IAR to write my program
6 REPLIES 6
Posted on November 16, 2015 at 15:01

but I have some issue to write on DR

What does that actually mean? What issue?

Your comments suggest you enable an interrupt, why would you do that, you have no handler, or NVIC configuration.

The Nucleo's VCP port is USART2 PA2/PA3

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
life758
Associate II
Posted on November 16, 2015 at 16:12

My final goal is to use the USART to modify the duty cycle of a PWM waveform generated from a timer. In the final project I want to use the interrupts, so I leave the option for later on, but I know that option don't make any difference, because I need to configure the NVIC first.

Anyway my issue was in debugging mode, where I couldn't see the output on DR and the reset of TXE by hardware. After I wrote the post I decided to observe the output on PA9 with the oscilloscope and I was glad to see the USART working. I was stupid and a little bit lazy. Sorry!

At the moment I'm trying to send data form PC and receive the same data from nucleo

sorry for my poor english

Posted on November 16, 2015 at 17:16

Unhandled interrupts can result in the Cortex-Mx getting stuck trying to handle something that is never cleared, ie it never leaves interrupt state, and foreground code stops executing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 16, 2015 at 17:18

Peripheral register are not RAM, you often can't view the content written into logic structures that consume the data internally. In many cases the read and write view different registers.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
life758
Associate II
Posted on November 16, 2015 at 19:05

Thanks Mr. Clive!

I appreciate your patience and kindness!

I choose to leave TXEIE=1 to understand how interrupts works and seems if I don't configure the NVIC it doesn't matter if TXEIE=1 or =0

next step. use interrupts to transmit/receive data from/to pc
life758
Associate II
Posted on November 18, 2015 at 10:27

Hello everybody!

I wrote the code to send data from PC to nucleo and get back the same data from nucleo. I used as interrupt the RxNE flag.

The code works ok and I would to ask you if I can improve my code to make it faster and more reliable.

;***************************************************

;;; Subroutines-----------------------------------------------------------------

        section get:CODE:NOROOT(2)

get_char

        add     r8, r8, #1

        ldrb    r3, [r0, #4]            ; get char on r3        

        BX      LR                      ; return from function call

        

        

        section put:CODE:NOROOT(2)

put_char

        ldr     r1, [r0]                ; SR

        ands    r1, r1, #(1 << 7)

        beq     put_char                ; polling on TXE

        add     r9, r9, #1

        strb    r3, [r0, #4] ; transmit the data received on r3

        BX      LR

;;; End Subroutines-------------------------------------------------------------

        

        SECTION .text:CODE:NOROOT(2)

        THUMB

        

main    NOP

        WFI ; MCU in sleep mode until RXNE=1

        B       main

;;; Interrupts definition------------------------------------------------

PUBLIC USART1_IRQ37

        SECTION .text:CODE:REORDER:NOROOT(1)

USART1_IRQ37

        push    {LR}

        BL      get_char                

        BL      put_char

        pop     {LR}

        BX      LR

;*****************************************

regards