ARM Cortex-M4,使用UART_DR和FIFO进行读/写

时间:2014-08-26 13:01:29

标签: assembly arm uart m4

所以我正在学习ASM,并拥有一台LM4F120XL ARM Cortex-M4 MCU。 我正在使用Keil uVision V4.54。

我熟悉设置端口等,初始化GPIO和UART。

我所坚持的是通过连续读取和写入TeraTerm / Putty,例如。

我理解RxFE = 0,FIFO不为空 - 从中​​读取;          并且TxFF = 0,FIFO未满 - 写入它..

但是在比较并满足这些条件之后,我实际上写了什么数据到UART_DR,数据寄存器......?仅仅是将数据寄存器加载到寄存器中,将该地址的值加载到另一个寄存器中,然后......即使不更改位,我也会丢失,而不是添加新数据 - 然后你就是' d将它从该寄存器存储回数据寄存器寄存器..

因此,如果数据寄存器中存在数据,那么它将被及时传出..? 我可以使用正确的COM端口连接到TeraTerm,调整BAUD和PARITY设置..但是如果数据寄存器中存在数据,那么在适当的周期之后它会自动发送..?

另外,从键盘读取字符怎么样?或者其他计算机外围设备..问题是 - 知道地址,将值加载到寄存器中,然后将其存储到数据寄存器中?如果数据寄存器保存数据,那么这需要非破坏性地完成..

为什么用C ++而不是ASM编写的每一篇关于MCU编码的文章呢? 我也学习C ++,但不知道为什么没有人使用汇编/机器代码..

; -------

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

; -------

2 个答案:

答案 0 :(得分:1)

是的,您正在编写串行/ uart界面上的字符。如果您使用哑终端,ASCII是最容易使用的。一个简单的测试循环:

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

其中定时延迟比发送字符所需的时间长(10位周期,开始,数据,停止,无论9600,115200等等,还是长时间延迟)

然后

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

其中uart_putc在这种情况下等待tx缓冲区/ fifo中有一个空格,然后插入传递给该fifo的值。

您的终端将显示的是01234567(您可能想告诉它换行)。如果第二个程序不是01234567,而是那些03715的那些......那么你不是在等待tx为空。

答案 1 :(得分:1)

听起来你还没有完全理解这种'注册'是如何运作的。不要把它当作保存数据的存储盒(比如CPU的通用寄存器),把它想象成一个邮箱 - 当你写一个字节时,那个字节被带入Tx FIFO缓冲区,但是当你从它读取时,你会得到一个从Rx FIFO传送的字节。通过读 - 修改 - 写操作改变位的想法确实没有意义,因为读和写这样的寄存器意味着完全不同的东西。

传输一个字节(一旦设置完成)就像这样简单:

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

一旦你写入FIFO,你的工作(作为软件)就完成了,你可以让硬件负责将缓冲区的内容传输到线路。

接收大致相同,但阅读而非写作:

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

根据MCU的the TRM(我认为这是合适的,部件号似乎已经改变),数据字节上方有一些只读接收状态位,因此您可以更改{{1} } LDRB来捕捉数据旁边的那些,但在这种情况下我真的不会打扰 - 串行通信的内部工作方式与学习装配完全相同。