请你把下面这段程序详细解释一下好吗,谢谢!
.public _TN_Data_Buff
.ram
_TN_Data_Buff:.dw 3 dup(?)
.var Data_Counter //有什么作用,这个变量在其它地方没有出现过
//==========================================================================
// 汇编格式: _TN_ReadData
// C格式: int TN_ReadData(void);
// 实现功能: 读测得数据
// 入口参数: 无
// 出口参数: 读到的三个字数据
// 破坏寄存器:r1
//==========================================================================
.public _TN_ReadData
_TN_ReadData:
push bp to [sp]
r2 = 40 //读5个字节的数据
r5 = _TN_Data_Buff //取缓冲区数据, _TN_Data_Buff 是否应该为首地址
TN_Read_loop:
r1 = 0x0001
[P_Watchdog_Clear] = r1
r1 = [IO_Port]
r1 &= TN_Clk //检测时钟数据
jnz TN_Read_loop //不为零时继续检测
r1 = [IO_Port] //为0时读一个bit数据,即检测到下跳沿
r1 &= TN_Data
jnz TN_Read_Data_H //不为0时转到TN_Read_Data_H
r1 = 0 //返回数据0
jmp TN_Read_Data_NN
TN_Read_Data_H:
r1 = 1 //返回数据1
TN_Read_Data_NN: //主要解释这一段程序
// [r5++] = r1
r3 = [r5+2] //第一个字数据处理 ,[r5] 是否才是第一个数据
r3 = r3 lsl 1 //
r3 = r3|r1 //
[r5+2] = r3
r4 = r4 lsl 3 //有什么作用
r3 = [r5+1] //第二个字数据处理
r3 = r3 rol 1
r4 = r4 lsl 3 //有什么作用
[r5+1] = r3
r3 = [r5] //第三个字数据处理
r3 = r3 rol 1
r4 = r4 lsl 3 //有什么作用
[r5] = r3
r2-=1
jnz TN_Read_Wait //40个bit数据没有读完转向TN_Read_Wait
jmp TN_Read_Exit //读完转向TN_Read_Exit
TN_Read_Wait:
r1 = 0x0001
[P_Watchdog_Clear] = r1
r1 = [IO_Port] //检测时钟
r1 &= TN_Clk
jnz TN_Read_loop //时钟不为0时转向TN_Read_loop
jmp TN_Read_Wait
TN_Read_Exit:
nop
nop
pop bp from [sp]
retf
请你解释一下r4与SB寄存器的关系好吗?谢谢!
请你解释一下r4与SB寄存器的关系好吗?谢谢!
SB寄存器是4位的.
51的在移位时,会将移出的位移到进位当中去,而51的进位仅有一个位.对于61,SB寄存器有4位,所以想要作循环移位时(一个位一个位的循环),就需要先将所要移的有效数据位先移入SB当中,然后移三个无意义的位(上面的代码当中就是直接移了r4当中的数)以将有效位同步移到出口,然后再下一次循环移一位时,就可将该有效位移到所期望的寄存器当中.
利用加法可以实现循环左移呢!呵呵
带进位的加法
详细解释已经发到你信箱,请查收.:)
就是啊!发到这里来可供大家参考嘛!!!~~~~~~
.public _TN_Data_Buff
.ram
_TN_Data_Buff:.dw 3 dup(?)
.var Data_Counter //这个变量在其它地方没有出现过 //这个变量是没有用到,原思想是用他来做数据计数器的,后面直接用寄存器了,所以这个不用不管
//==========================================================================
// 汇编格式: _TN_ReadData
// C格式: int TN_ReadData(void);
// 实现功能: 读测得数据
// 入口参数: 无
// 出口参数: 读到的三个字数据
// 破坏寄存器:r1
//==========================================================================
.public _TN_ReadData
_TN_ReadData:
push bp to [sp]
r2 = 40 //读5个字节的数据
r5 = _TN_Data_Buff //取缓冲区数据, _TN_Data_Buff 是否应该为首地址
TN_Read_loop:
r1 = 0x0001
[P_Watchdog_Clear] = r1
r1 = [IO_Port]
r1 &= TN_Clk //检测时钟数据
jnz TN_Read_loop //不为零时继续检测
r1 = [IO_Port] //为0时读一个bit数据,即检测到下跳沿
r1 &= TN_Data
jnz TN_Read_Data_H //不为0时转到TN_Read_Data_H
r1 = 0 //返回数据0
jmp TN_Read_Data_NN
TN_Read_Data_H:
r1 = 1 //返回数据1
TN_Read_Data_NN: //主要解释这一段程序 //下面这段程序是用来读连续5个字节的数据的,至于为什么要读5个字节的数据,你可以参考一下红外测温模块的时序图。
// [r5++] = r1
r3 = [r5+2] //第一个字数据处理 ,[r5] 是否才是第一个数据 //想想看,5个字节需要几个字的空间来存放,自然是3个,因为是按顺序读取的。根据时序可以看出来,先读入放在最高位,后读入的数据放在最低位,[r5+2]存放的是我们定义的TN_Data_Buff[5]和TN_Data_Buff[6]的数据,如果按这样说的话,是第一个字的数据。
r3 = r3 lsl 1 // 左移一个数据是为了存放读进来的下一个数据
r3 = r3|r1 // 把读入的数据和上面左移好的数据相或,就可以得到读进来的数据
[r5+2] = r3
r4 = r4 lsl 3 //有什么作用//没有特别的作用,只是一种特殊的处理而已
//对于61,SB寄存器有4位,所以想要作循环移位时(一个位一个位的循环),就需要先将所要移的有效数据位先移入SB当中,然后随便用一个数移三个无意义的位(这里就是用了r4进行左移的)以将有效位同步移到出口,然后再下一次循环移一位时,就可将该有效位移到所期望的寄存器中.
r3 = [r5+1] //第二个字数据处理
r3 = r3 rol 1 //循环左移移位,下面一句是辅助实现循环移位的。
r4 = r4 lsl 3 //有什么作用//这个作用和前面讲的一样
[r5+1] = r3
r3 = [r5] //第三个字数据处理
r3 = r3 rol 1 //循环左移移位
r4 = r4 lsl 3 //有什么作用//这个作用和前面讲的一样
[r5] = r3
r2-=1 //r2的初始值是40(5*8),每读一个数据r2就减1,r2为0时表示所有5字节的数据已经读完,就退出循环,否则就返回继续读取下一个数据。
jnz TN_Read_Wait //40个bit数据没有读完转向TN_Read_Wait
jmp TN_Read_Exit //读完转向TN_Read_Exit
TN_Read_Wait:
r1 = 0x0001
[P_Watchdog_Clear] = r1
r1 = [IO_Port] //检测时钟
r1 &= TN_Clk
jnz TN_Read_loop //时钟不为0时转向TN_Read_loop
jmp TN_Read_Wait
TN_Read_Exit:
nop
nop
pop bp from [sp]
retf
呵呵!本来注释成红色字体加粗突出显示的,发出来好象一样了.
不过没有关系,字数多的肯定是详细注释的.:)