Search code examples
stm32gpiousartthumb

Configuring USART to send a character in ARM thumb assembly


I am trying to send a character using my stm32. I am using Real Term serial capture program and have set up a baud rate of 9600.

I have attempted to write the initialization for the USART and GPIOA. So far, when I reset my device, it sends a NULL character to the serial capture program, so I think I am on the right track atleast. But I have tried writing a character to the USART_DR and have had no luck seeing the character at the serial capture side.

I have been following this link as a guide (http://www.micromouseonline.com/2009/12/31/stm32-usart-basics)

And here's a little guide for GPIO registers

@; GPIOx
@; MODER [15:0] 
@;0:'00'-> input mode, which allows the GPIO pin to be used as an input pin,
@;1:'01'-> Output mode, which allows the GPIO pin to be used as an output pin,
@;3:'11'-> Analog mode, which allows the GPIO pin to be used as an Analog input pin and finally,
@;2:'10'-> Alternate function mode which allow the GPIO pins to be used by peripherals such as the UART, SPI e.t.c. 
@;OTYPER
@;'0'-> output push/pull
@;'1'-> output open drain
@;OSPEEDR
@;'x0': 2MHz Low speed
@;'01':10MHz Medium speed
@;'11': 50MHz High speed
@;OPUPDR
@;'00'-> No pull-up/pull-down
@;'01'-> pull up
@;'10'-> pull down
@;'11'-> Reserved

How I have configured the USART:

According to the guide, I needed to set up PA9 as alternative function mode, output push pull, output low speed, and no pull-up/pull-down.

I then set up PA10 as general purpose input, floating (Though I do not need to use this at this point, I am just trying to see if I can get a character to send first.)

Next, I had to make sure the USART1 clock was enabled.

I found that the RCC_APB2ENR( RCC APB2 periperal clock enable register) is located 0x44 from RCC_base. I enabled it like so,

@; make sure USART1 is enabled clock
ldr r3,=RCC_BASE
ldr r2,[r3,#RCC_APB2ENR]
orr r2,#(1<<4)  @; set enable bit
str r2,[r3,#RCC_APB2ENR]

I then set the baud rate, and enabled the CR1 TE and RE bit.

@; load the baud rate (9600), baud = fclk/(16*usartdiv), fclk=16*10^6
ldr r3, =USART1_BASE
mov r2, #0x683      @; Mantissa [15:4] 0x68=0d104 Frac [3:0] 0x3
str r2, [r3, #USART_BRR]

@; enable the USARTx_CR1_UE bit
ldr r2,  [r3, #USART_CR1]
orr r2, #(1<<13)
str r2, [r3, #USART_CR1]

@; enable the USARTx_CR1_TE bit
ldr r2, [r3, #USART_CR1]
orr r2, #(1<<3)
str r2, [r3, #USART_CR1]

@; enable the USARTx_CR1_RE bit
ldr r2, [r3, #USART_CR1]
orr r2, #(1<<2)
str r2, [r3, #USART_CR1]

I think I have set it up correctly!

But to no avail, I am not seeing any characters show up in my serial capture program.

I just tried putting the character A in the data register but have received nothing.

ldr r3, =USART1_BASE
mov r2, #0x41 @; A
str r2, [r3, #USART_DR]

Its been a couple days now trying to debug whats wrong and I haven't found an answer. Some type of help would be appreciated! Thank you.


Solution

  • I did need to enable the Moder register to alternate function mode. But what I did not do was enable the alternate function for use by USART1.

    Specifically, for Pin 9 (Tx) the alternate function for USART1 can be set in the Alternate Function High Register.

    More detail here: (http://web.eece.maine.edu/~zhu/book/Appendix_I_Alternate_Functions.pdf)