【问题标题】:ARM Cortex-M4, Read/Write using UART_DR and FIFOARM Cortex-M4,使用 UART_DR 和 FIFO 读/写
【发布时间】:2014-10-19 19:40:14
【问题描述】:

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

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

我坚持的是读写,例如通过串行到 TeraTerm/Putty。

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

但是在比较并满足这些条件之后,我实际上将什么数据写入 UART_DR,即数据寄存器..?是否只是将数据寄存器加载到寄存器中,将此地址处的值加载到另一个寄存器中,然后......我丢失了,因为我没有更改位我正在添加新数据 - 然后你会从这个寄存器回到数据寄存器寄存器..

所以如果数据寄存器中存在数据,那么它会及时传递出去..? 我可以使用正确的 COM 端口连接到 TeraTerm,调整 BAUD 和 PARITY 设置。但是再一次,如果数据寄存器中存在数据,在到期周期后会自动发送它..?

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

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

;-------

读取字符

    PUSH {R0, R1}

inloop LDR R0, =UART_FR LDR R1, [R0] 与 R1,#0x10 CMP R1,#0x0 BNE 内循环

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

    POP {R0, R1}

    BX LR  

;-------

输出字符

    PUSH {R0, R1}

outloop LDR R0, =UART_FR LDR R1, [R0] 与 R1,#0x20 CMP R1,#0x0 BNE 外环回

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

    POP {R0, R1}

    BX LR

;-------

【问题讨论】:

  • 欢迎您!在 SO 上,我们通常不使用称呼和其他无关内容,例如“帮助”/“提前致谢”/等。我们并不想表现得不友善,我们大多只是想保持简短。查看帮助部分或 Meta 以了解有关该网站如何运作的更多信息!

标签: assembly arm uart m4


【解决方案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 为空。

【讨论】:

    【解决方案2】:

    听起来您还没有完全理解这种“寄存器”的工作原理。不要将其视为保存数据的存储箱(如 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(我认为这是一个合适的,零件号似乎已经改变)在数据字节上方有一些只读接收状态位,因此您可以将 LDRB 更改为 @987654325 @ 来捕获数据旁边的那些,但在这种情况下我真的不会打扰 - 串行通信的内部工作完全与学习汇编无关。

    【讨论】:

    • 顺便说一句,这与从 C 中进行操作没有什么不同:char c = *(char *)UART_DR; - 人们使用 C 是因为它编写起来更快,更容易处理,尤其是当项目变得更大时。事实上,Cortex-M 架构的设计显然是为了一切都可以用 C 语言编程,而您永远不需要去接触汇编。显然,当手头的任务是专门学习汇编时,这并没有多大帮助......
    猜你喜欢
    • 1970-01-01
    • 2018-09-29
    • 2017-12-03
    • 2019-12-14
    • 1970-01-01
    • 2014-04-06
    • 2018-12-04
    • 2017-06-23
    • 2019-06-27
    相关资源
    最近更新 更多