TOP

FAQ 常见问答

    • .19系列MCU程式编写过程中,为什么有时需要给操作码前加”x”?如xb0mov,xb0bclr,xb0bts1。不加是否可以?

      在程式码中给操作码前加X的都是对类比部分的设置,例如CPR、PGIA、ADC等的设置,主要原因是ICE无法仿真IC的类比部分的功能,而IC的类比部分主要是通过EV_KIT上的烧录有EV_LINK的IC来仿真的,操作码前加x的操作主要是对烧录有EV_LINK的IC进行动作,在ICE_MODE=1时,编译器就会将该指令编译成为对EV-KIT的操作过程,而当ICE_MODE=0时,编译器就会将该指令编译成为不加有X的操作码。
    • .使用指令累加实现计时,程式中连续出现相同指令时,如何处理比较好?

      程式中连续出现相同指令处理:
      1. 当程式中连续出现2 个的NOP 指令时,使用一条JMP $+1 指令代替两条NOP 指令能够节省1 个ROM 空间(其中“$”代表当前位址)。
      2. 如果程式中连续出现多条相同的指令,则可以使用“REPEAT”宏:
      下面使用该宏后产生的LIST 档片段:

      行号 Rom 位址 指令编码 源代码 注释
      71 00002B REPEAT 8
      72 00002B JMP $+1
      73 00002B ENDM
      74 00002B 802C(2) JMP $+1
      75 00002C 802D(2) JMP $+1
      76 00002D 802E(2) JMP $+1
      77
      00002E

      802F(2) JMP $+1
      78 00002F 8030(2) JMP $+1
      79 000030 8031(2) JMP $+1
      80 000031 8032(2) JMP $+1
      81 000032 8033(2) JMP $+1
      常数“8”代表重复的次数,重复的内容是REPEAT 和ENDM 之间的指令。
    • .主程序的.LIST档各部分代表的含义是什么?

      主程序的LIST 档的部分片段如下:

      行号 Rom 位址 指令编码 源代码 注释
      27 00000F
      28 00000F
      29 00000F C010(2) call _Loop ;; 调用延时副程式
      30 000010
      31 000010 _Loop:
      32 000010 2D13(1) mov a,#L_dly
      33 000011 1F 00(1) mov Rwk00,a ;; 设置回圈次数
      34 000012 _Loop10:
      35 000012 8013(2) jmp $+1 ;; 调节延迟时间
      36 000013 2600(1+S) decms Rwk00 ;; 递减 Rwk00, 为 0 就跳过下一行
      37 000014 8012(2) jmp _Loop10 ;; 回圈
      38 000015 0E00(2) ret ;; 返回主程序
      39 000016
      其中指令编码段括弧中的内容,代表该行指令的执行指令周期。如第38 行,括弧中的内容为2,则代表执行该指令需要2个指令周期。如果Fcpu=1M,则执行该指令需要花费2uS。
    • .macro巨集指令和expand巨集指令有什么区别?

      使用巨集可以简化程式的编写,节省两条指令(相比于副程式),且不占用堆迭。 marco和expand巨集指令都可以用来定义一个宏,不同的是在编译出现错误或仿真时,使用macro将使游标停在调用宏的位置,使用expand会使游标停在巨集指令内部,这有利于错误检查。
    • .使用“Decms”指令做延时处理时,需注意哪些问题?

      Decms操作格式及说明如下:

      指令格式 描述 C DC Z 周期
      DECMS M M ← M – 1, 如果寄存器等于0, 则跳过下一条指令 - - - 1+N+S
      其中,M可以是系统寄存器,也可以是用户自定义的寄存器。
      使用Decms指令时需注意,该指令周期为1+N+S,其中“S”表示如果跳过下条指令则S=1,如果顺序执行下一条指令则S=0;“N”表示:当M为用户自定义的寄存器时N=1,当M为系统寄存器时S=0。

      下面一段程式演示了当Fcpu为1us时,如何使用Decms实现500us的延时;

      Delay500us:
      Mov a,#125
      Mov wk00,a
      @@:
      Decms wk00 ;wk00为用户自定义的寄存器
      JMP @B ;跳到上一个
      Nop
      Ret
    • .在Sonix指令集中,当描述指令周期时有“1”,“1+N”,“1+S”或“1+N+S”,其中各项表示什么意思?

      1. 指令周期为“1”时,代表该指令具有1个CPU时钟周期,一个周期等于1/Fcpu。
      2. 指令周期为“1+N”时,代表该指令具有1+N个CPU时钟周期。如果运算元中的寄存器为用户自定义的寄存器则N=1,其余情况均为0,一个周期等于1/Fcpu。
      3. 指令周期为“1+S”时,代表该指令具有1+S个CPU时钟周期。如果跳过下条指令则S=1,如果执行下一条指令则S=0,一个周期等于1/Fcpu。
      4. 指令周期为“1+N+S”时,代表该指令具有1+N+S个CPU时钟周期。如果跳过下条指令则S=1,如果执行下一条指令则S=0;如果运算元中的寄存器为用户自定义的寄存器则N=1,其余情况均为0,一个周期等于1/Fcpu。
    • .INCLUDE和INCLUDESTD有什么不同?

      INCLUDE:该命令后面需要跟一个程式档,如果该程式档不在当前正在编译的程式目录下,用户就需要为其指定路径。
      该程式档的语法和一般的档无异。通常,副档名是.H 的档一般包括常数和宏的定义,副档名是.asm 则包含了指令。被包含的档内还可以使用INCLUDE 命令,嵌套最多255 层。
      例如:
      INCLUDE SN88X.H
      INCLUDE C: \PROJECT.H INCLUDE sub \ Filename.ASM
      INCLUDE ..\Parent\File2.ASM

      INCLUDESTD:该命令后需要一个程式档,路径已经被固定为M2ASM.EXE/SN8ASM.EXE 所在路径,即编译器根目录下,其余参考INCLUDE 命令。此命令可以使用户方便取用系统提供的巨集档案。
      例如:
      INCLUDESTD MACRO1.H //包含系统常用巨集档案
      INCLUDESTD MACRO2.H //包含系统常用巨集档案
      详细资讯可参考SN8AsmMenuV193_C.pdf
    • .编译后生成的.LIST,.HEX,.SN8都是些什么档,具有哪些功能?

      .LIST 文档 列表文件(LIST)
      .SN8 文档 用于烧录的Sonix二进位格式档
      .HEX 文档 十六进位文本文档,和二进位文档对应
      Other Output 保留
    • .Sonix 单片机的指令有什么特点?一般的指令周期是多少?

      Sonix系列单片机的指令系统为RISC(精简指令集),这样的指令集用起来非常灵活,可以有效地提高程式的效率。
      单片机大部分指令周期数为1个CPU时钟周期(Fcpu),有个别为2个CPU时钟周期的指令,如JMP,DECMS,RLCM等。指令执行具体时间可参考datasheet中INSTRUCTION TABLE和SN8InstructionV194_SC.pdf。
    • .为什么每次进入Sleep模式语句后面都要紧跟两条或更多的nop指令?不加是否可以?

      一般情况下,系统从省电模式下被唤醒,恢复到正常工作模式期间,系统时钟会有一段时间的稳定时间;所以为了避免程式在系统时钟不稳定下执行,最好在进入sleep模式语句后面紧跟两条或更多的nop指令,这样在系统时钟还没稳定时执行空操作指令,就不会影响整个系统的工作;实际上这样的情况是非常少遇到的,Sonix单片机在硬体上有做延时处理,加上空操作指令只是为了使系统更加可靠。
    • .累加器ACC为0时,零标志位FZ是否一定自动置为“1”?

      当累加器ACC为0时,零标志位FZ是否置“1”,决定于当前执行的指令,与累加器ACC的值是否为0没有必然的联系。 如执行指令:mov a,#00H,并不会影响零标志位FZ。
      当前执行的指令是否会影响零标志位FZ,请参看Datasheet中的指令表。
    • .MOV和B0MOV的有何区别?

      MOV 指令为寄存器读/写指令,通过累加器ACC 传送数据,共有3 种操作格式:
      ◆ MOV A,M :从内存中读取数据并存入ACC 中,结果为0,零标志(Z)置1,否则置0。
      ◆ MOV M,A :从ACC 中的数据写入内存中,此操作不影响PFLAG。
      ◆ MOV A,I :将立即数赋予ACC,此操作不影响PFLAG。

      ※注:
      1.“I” 为立即数;
      2.“M”为系统寄存器或用户自定义寄存器;

      B0MOV 指令为寄存器读/写指令,内存必须位于BANK0,通过ACC 传送数据,共有3 种操作格式:
      ◆ B0MOV A,M :从BANK0 内存中读取数据存入到ACC 中。结果为0,零标志(Z)置1,否则零标志置0。
      ◆ B0MOV M,A :将ACC 的数据写入到BANK0 内存中,操作不影响PFLAG。
      ◆ B0MOV M,I :将立即数赋予BANK0 内存,内存必须是工作寄存器(H,L,R,X,Y,Z)、RBANK 或PFLAG,操作不影响PFLAG。

      ※注:
      1.“I” 为立即数;
      2.“M”为系统寄存器或用户自定义内存BANK0 位置的寄存器;

      因此,在只有BANK0的芯片中,除了“MOV A,I”和“B0MOV M,I”要参照上述说明使用外,在大部分情况下“MOV”和“B0MOV”是等价的;如果是有多个RAM分区的芯片,比如包含BANK0和BANK1两页,在bank1 访问状态下,“MOV”指令可对当前BANK(即BANK1)的寄存器进行操作,而使用“B0MOV”指令,则可以无需转换RAM bank而直接访问系统寄存器或RAM bank 0 的数据。
    • .EQU与DS指令有何区别?

      DS指令是用来在RAM中定义数据,如
      MEM1 DS 1 // 定义一个寄存器MEM1,占用一个字节的RAM空间
      MEM2 DS 16 // 在RAM中定义一段长度为16字节的寄存器
      EQU是用来声明常量的,如
      NUM1 EQU 13 // 程序中NUM1即代表数值13
      PIN1 EQU P0.0 // 程序中PIN1即代表P0.0
      另外还可以这样使用,如
      MEM1 DS 1 // 定义一个寄存器MEM1,占用一个字节的RAM空间
      FLAG1 EQU MEM1.0 // FLAG1等于寄存器MEM1的bit0
      当使用DS定义数据时,IDE会自动检测是否超出RAM边界,同时使用DS定义的资料,在仿真时可以在仿真接口的观察框内进行查看.