简体   繁体   中英

ARM Cortex-M4, Read/Write using UART_DR and FIFO

So I am learning ASM, and have an LM4F120XL ARM Cortex-M4 MCU. I am using Keil uVision V4.54.

I am familiar with setting up ports etc, initialising GPIO and UART.

What I am stuck on is reading and writing, to TeraTerm/Putty via serial, for example.

I understand RxFE = 0, FIFO is not empty - read from it; and TxFF = 0, FIFO is not full - write to it..

But after comparing and satisfying these conditions, what data am I actually writing to UART_DR, the data-register..? Is it simply a matter of loading the data-register into a register, loading the value at this address into another register, then ... im lost as im not changing bits I'm adding new data - then you'd store it from this register back into the data-register register..

So if data exists in the data-register, then in time it will be passed out..? I can connect to TeraTerm using the correct COM port, adjust BAUD and PARITY settings.. But once again, if data exists in the data-register, after due cycles will it be sent automatically..?

Also, what about reading characters from keyboard..? Or other computer peripherals.. Is it a matter of - knowing the address, loading the value into a register, then storing it into the data-register? If the Data-Register holds data, then this would need to be done non-destructively..

Why the hell is every article on MCU coding written in C++ and not in ASM? Im also learning C++ but dont know why no-one uses assembly/machine code..

;-------

ReadChar

    PUSH {R0, R1}

inloop LDR R0, =UART_FR LDR R1, [R0] AND R1, #0x10 CMP R1, #0x0 BNE inloop

    LDR R0, =UART_DR
    LDR R1, [R0]
    ************??
    STR R1, [R0]

    POP {R0, R1}

    BX LR  

;-------

OutputChar

    PUSH {R0, R1}

outloop LDR R0, =UART_FR LDR R1, [R0] AND R1, #0x20 CMP R1, #0x0 BNE outloop

    LDR R0, =UART_DR
    LDR R1, [R0]
    ************??
    STR R1, [R0]

    POP {R0, R1}

    BX LR

;-------

Yes you are writing the characters that go out on the serial/uart interface. ASCII is the easiest to use if you are using a dumb terminal. A simple test loop:

unsigned char ra;
...
for(ra=0;;ra++)
{
    ra&=7;
    UART_DR = 0x30+ra;
    timed_delay();
}

where timed delay is longer than the time it takes to send a character (10 bit periods, start, data, stop, at whatever rate 9600, 115200, etc, or just a long delay)

Then

unsigned char ra;
...
for(ra=0;;ra++)
{
    ra&=7;
    uart_putc(ra);
}

where uart_putc in this case waits for there to be an opening in the tx buffer/fifo and then inserts the value passed into that fifo.

What your terminal will show is 01234567 (you probably want to tell it to wrap). If this second program is not 01234567 but some mangling of those 03715... Then you are not waiting for tx to be empty.

Sounds like you haven't quite got the right concept yet of how such a 'register' works. Don't think of it as a storage box that holds data (like the CPU's general-purpose registers), think of it more like a postbox - when you write a byte to it, that byte gets taken away into the Tx FIFO buffer, however when you read from it, you instead get a byte delivered from the Rx FIFO. The idea of changing bits via read-modify-write operations indeed makes no sense because reading and writing such a register mean completely different things.

Transmitting a byte (once things are set up) is as simple as:

; byte to transmit is in r0
; <wait for space in Tx FIFO>
LDR  r1, =UART_DR
STRB r0, [r1]

Once you've written to the FIFO, your job (as software) is done, and you can let the hardware take care of transmitting the contents of the buffer to the wire.

Receiving is much the same, but reading instead of writing:

; <wait for data in Rx FIFO>
LDR  r1, =UART_DR
LDRB r0, [r1]
; received byte now in r0

According to the TRM for the MCU (I think that's an appropriate one, part numbers seem to have changed) there are some read-only receive status bits above the data byte, so you could change LDRB to LDR to capture those alongside the data, but I really wouldn't bother in this case - the inner workings of serial communication are entirely tangential to learning assembly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM