所以我正在学习ASM,并且有一个LM4F120XL ARM Cortex-M4 MCU。我使用的是Keil uVision V4.54。
熟悉设置端口等,初始化GPIO和UART。
我卡住的是读取和写入,例如通过串行到TeraTerm/Putty。
我理解RxFE = 0, FIFO不是空的-从它读取;如果TxFF = 0, FIFO未满,则写入。
但是在比较并满足这些条件之后,我实际写什么数据到UART_DR,数据寄存器…?是否只是将数据寄存器加载到寄存器中,将此地址的值加载到另一个寄存器中,然后……我丢失了,因为我没有改变位,我添加了新的数据-然后你会把它从这个寄存器存储回数据寄存器寄存器..
所以如果数据存在于数据寄存器中,那么它将及时被传递出去…?我可以使用正确的COM端口连接到TeraTerm,调整波特和奇偶校验设置。但是再一次,如果数据存在于数据寄存器中,经过适当的周期后,它会自动发送吗?
还有,如何从键盘读取字符…?或其他计算机外围设备…这是一个问题-知道地址,加载值到寄存器,然后将其存储到数据寄存器?如果data - register保存数据,那么这将需要非破坏性地完成。
为什么每篇关于MCU编码的文章都是用c++写的,而不是用ASM写的?我也学c++,但不知道为什么没人用汇编/机器码。
;-------
ReadChar
PUSH {R0, R1}
inloop LDR R0, =UART_FRLDR r1, [0]和R1, #0x10CMP R1, #0x0BNE inloop
LDR R0, =UART_DR
LDR R1, [R0]
************??
STR R1, [R0]
POP {R0, R1}
BX LR
;-------
OutputChar
PUSH {R0, R1}
outloop LDR R0, =UART_FRLDR r1, [0]和R1, #0x20CMP R1, #0x0BNE outloop
LDR R0, =UART_DR
LDR R1, [R0]
************??
STR R1, [R0]
POP {R0, R1}
BX LR
;-------
听起来你还没有完全理解这样一个"寄存器"是如何工作的。不要把它想象成一个保存数据的存储箱(像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的TRM(我认为这是合适的,零件号似乎已经改变)在数据字节上方有一些只读接收状态位,因此您可以将LDRB
更改为LDR
以捕获那些数据,但我真的不会在这种情况下打扰-串行通信的内部工作完全与学习组装无关。
是的,您正在编写串行/串行接口上输出的字符。如果您使用哑终端,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_put等待在tx缓冲区/fifo中有一个打开,然后将传递的值插入到该fifo中。
您的终端将显示01234567(您可能想告诉它换行)。如果第二个程序不是01234567,而是03715的一些混乱…那么你就不用等待tx为空了。