松翰单片机SN8P系列使用总结

1 使用M2Asm创建新工程

1.1 创建新文件夹存放工程文件

  1. 在新建文件夹下创建 main.asm 汇编文件
    在这里插入图片描述

1.2 在编译软件 M2Asm 上创建工程

  1. 点击 M2Asm软件的 file->New Project,选中 main.asm 文件,并点击“打开”

  2. M2Asm 显示如下
    在这里插入图片描述

1.3 填写 main.asm 代码框架

  1. 填写工程信息,可不填

    ;*******************************************************************************
    ; FILENAME	: 
    ; AUTHOR	: 
    ; PURPOSE	: 
    ; REVISION Date	: 
    ; UPDATE Date   : 
    ; CHECKSUM      : 
    ; END DATE      : 
    ;*******************************************************************************
    
  2. 选择芯片

     chip	SN8P2711B 
    
  3. 自动生成 SONIX_CODE_OPTION 信息(该步骤也可放在最后,且可随时更改)
    填写芯片型号后,点击 M2Asm 的 Go 可自动生成 SONIX_CODE_OPTION 信息。
    在这里插入图片描述
    在这里插入图片描述
    详细说明请参考章节 《2 编译说明SONIX_CODE_OPTION》

  4. 添加官方系统头文件

    .nolist						        ; do not list the macro file
    	INCLUDESTD	MACRO1.H
    	INCLUDESTD	MACRO2.H
    	INCLUDESTD	MACRO3.H
    

    该头文件可在 M2Asm 软件安装目录下找到
    在这里插入图片描述

  5. 添加用户头文件

    .list						        ; Enable the listing function
            include                 user_ram.h
    ……
    

    在用户头文件中可定义变量、宏、引脚等

    BIT0                EQU             01H
    ……
    R0                  DS              1
    ……
    PIN_LED             EQU             P5.1
    
  6. 代码区

;-------------------------------------------------------------------------------
;			Code section
;-------------------------------------------------------------------------------
.CODE
		    ORG	            0			        ;Code section start
	        JMP		        Reset		        ;Reset vector 上电/复位开始执行的程序
		    ORG	            8
            JMP             ISR                 ;中断服务函数入口
		    ORG	            10h
;-------------------------------------------------------------------------------
; 			Program reset section
;-------------------------------------------------------------------------------
Reset:
	……  ; 初始化等操作
LOOP:
	……  ; 功能逻辑操作
	JMP LOOP
	
ISR:
	……
	RETI
  1. 添加用户其他汇编文件

    INCLUDE         key.asm
    ……
    
  2. 工程代码结束

    ENDP
    
  3. 总的代码框架

;*******************************************************************************
; FILENAME	: 
; AUTHOR	: 
; PURPOSE	: 
; REVISION Date	: 
; UPDATE Date   : 
; CHECKSUM      : 
; END DATE      : 
;*******************************************************************************
chip	SN8P2711B 
//{{SONIX_CODE_OPTION
	.Code_Option	LVD		LVD_H		; 2.4V Reset Enable LVD36 bit of PFLAG for 3.6V Low Voltage Indicator
	.Code_Option	Reset_Pin	P04
	.Code_Option	Watch_Dog	Always_On	; Watchdog still enable even in Green and Sleep mode
	.Code_Option	High_Clk	IHRC_16M	; Internal 16M RC Oscillator
	.Code_Option	Fcpu		#7     ; Fcpu = Fosc/16
	.Code_Option	Security	Enable
	.Code_Option	Noise_Filter	Enable
//}}SONIX_CODE_OPTION
.nolist						        ; do not list the macro file
		INCLUDESTD	MACRO1.H
		INCLUDESTD	MACRO2.H
		INCLUDESTD	MACRO3.H
.list						        ; Enable the listing function
	        include                 user_ram.h
;-------------------------------------------------------------------------------
;			Code section
;-------------------------------------------------------------------------------
.CODE
		    ORG	            0			        ;Code section start
	        JMP		        Reset		        ;Reset vector 上电/复位开始执行的程序
		    ORG	            8
            JMP             ISR                 ;中断服务函数入口
		    ORG	            10h
;-------------------------------------------------------------------------------
; 			Program reset section
;-------------------------------------------------------------------------------
Reset:
	……  ; 初始化等操作
LOOP:
	……  ; 功能逻辑操作
	JMP LOOP
	
ISR:
	……
	RETI
	INCLUDE         key.asm
	ENDP

1.4 将用户文件添加进 M2Asm 软件工程目录

  1. 在 main.asm 添加用户 .asm 文件和 .h 文件后,点击M2Asm软件即可自动添加
    在这里插入图片描述

1.5 点击编译生成可烧录文件

  1. 点击M2ASM工具栏编辑按钮
    在这里插入图片描述
  2. 编译成功,没有错误
    在这里插入图片描述

2 编译说明SONIX_CODE_OPTION

在这里插入图片描述

3 重要寄存器说明

3.1 程序状态寄存器PFLAG

  1. C:进位标志。
    1 = 加法运算后有进位、减法运算没有借位发生或移位后移出逻辑“1”或比较运算的结果 ≥ 0;
    0 = 加法运算后没有进位、减法运算有借位发生或移位后移出逻辑“0”或比较运算的结果 < 0。
  2. DC:辅助进位标志。
    1 = 加法运算时低四位有进位,或减法运算后没有向高四位借位;
    0 = 加法运算时低四位没有进位,或减法运算后有向高四位借位。
  3. Z:零标志。
    1 = 算术/逻辑/分支运算的结果为零;
    0 = 算术/逻辑/分支运算的结果非零。

3.2 堆栈指针 STKP

在这里插入图片描述

  1. Bit[2:0] STKPBn :堆栈指针(n = 0 ~ 2)。
  2. Bit 7 GIE :全局中断控制位。
    0 = 禁止;
    1 = 使能。

3.3 OSCM寄存器

寄存器 OSCM 控制振荡器的状态和系统的工作模式。
在这里插入图片描述

  1. Bit 1 STPHX :高速振荡器控制位。
    0 = 运行;
    1 = 停止,内部低速 RC 振荡器仍然运行。
  2. Bit 2 CLKMD :系统时钟模式控制位。
    0 = 普通(双时钟)模式,高速时钟作为系统时钟;
    1 = 低速模式,低速时钟作为系统时钟。
  3. Bit[4:3] CPUM[1:0] :CPU 工作模式控制位。
    00 = 普通模式;
    01 = 睡眠模式;
    10 = 绿色模式;
    11 = 系统保留。

3.4 RAM初始化

上电后需要将RAM初始化为0

INIT_RAM:
                    CLR             Y
                    B0MOV           Z,#0x3F             ; 需要清零地址范围 3F~00H
INIT_RAM_LOOP:
                    CLR             @YZ                 ; 给@YZ地址清零,第一次地址为 0x3F
                    DECMS           Z                   ; Z ← Z - 1,如果 Z = 0,则跳过下一条指令。  
                    JMP             INIT_RAM_LOOP   ; 若 Z 不为 0,则循环
                    CLR             @YZ                 ; 清地址为 0x00 处内容

                    RET                                 ; 退出函数

RAM 数据寻址指针
在这里插入图片描述

3.5 引脚初始化

                    MOV             A,#0x0C             ; P0.2,P0.3 配置为输出模式
                    B0MOV           P0M,A               ; 
                    MOV             A,#0xF3             ; P0.2,P0.3 配置为禁止上拉
                    B0MOV           P0UR,A
                    MOV             A,#0x00       		; P0.2,P0.3 初始化为低电平
                    MOV             P0,A                
  1. PnM 引脚模式寄存器
    在这里插入图片描述
    寄存器 PnM 控制 I/O 口的工作模式,n = 0~5,即P0 ~ P5 端口。
    PnM[的Bit[7:0] :
    0 = 输入模式;
    1 = 输出模式。
  2. 引脚上拉模式
    I/O 引脚内置上拉电阻,仅在输入模式下有效。I/O 引脚的上拉电阻由 PnUR 寄存器控制,n = 0~5,即P0 ~ P5 端口。
    在这里插入图片描述
    PnUR 的Bit[7:0] :
    0 时,禁止上拉电阻;
    1 时,使能上拉电阻。

4 逻辑运算应用

4.1 判断指令 BTS0、BTS1

BTS0 M.b如果 M.b = 0,则跳过下一条指令
BTS1 M.b如果 M.b = 1,则跳过下一条指令

4.2 用 XOR(异或)判断两变量是否相同

异或运算:相同为0,不同为1;进行异或运算后(也是逻辑运算),零标志(Z)状态会改变:

  1. Z:零标志。
    1 = 逻辑运算的结果为零;
    0 = 逻辑运算的结果非零。
    应用举例:

          B0MOV           A,var1
          XOR             A,#AA            ; 异或运算:var1与#AA相同,则FZ==1,var1与#AA不同,则FZ==0
          B0BTS0          FZ               ; FZ 为 0 时,则跳过下一条指令
          JMP             JMP_XXX           
          ...            
    

4.3 用SUB(减法)判断两变量大小

SUB A,MA ← A – M,如果产生借位则 C=0,否则 C=1。
SUB M,AM ← A – M,如果产生借位则 C=0,否则 C=1。
应用举例:
;subtract word, SUBW 算法
SUBW	            MACRO	    m_minuend,m_subtrahend   //m_minuend=m_minuend-m_subtrahend
                    MOV             A,m_minuend
                    SUB             A,m_subtrahend
                    MOV             m_minuend,A             // save low byte
                    MOV             A,m_minuend+1
                    SBC             A,m_subtrahend+1
                    MOV             m_minuend+1,A           // save high byte
	               ENDM
 ;------------------------------------------------------------------------------------------
  AAA                 DS              2                  ; 临时双字节寄存器AAA
  BBB                 DS              2                  ; 临时双字节寄存器BBB
  ;------------------------------------------------------------------------------------------
  ;双字节变量的比较
       B0MOV           A,var1 + 0                ; var1 + 0:表示字节1
       B0MOV           AAA + 0,A
       B0MOV           A,var1 + 1                ; var1 + 1:表示字节2
       B0MOV           AAA + 1,A
       MOV             A,#CON1$L        ; #CON1$L 低字节
       B0MOV           BBB+0,A
       MOV             A,#CON1$M        ; #CON1$M 中字节
       B0MOV           BBB + 1,A
       SUBW            AAA,BBB          ; var1 -CON1(AAA >= BBB,FC为1)
       B0BTS1          FC               ; 也可以用 B0BTS0
       JMP             JMP_XXX          ; var1 < CON1
       ...                              ; var1 > CON1
  ;------------------------------------------------------------------------------------------
  ;单字节变量的比较
       B0MOV           A,var1           ; 
       B0MOV           AAA ,A
       MOV             A,#CON1          ; 
       B0MOV           BBB,A
       SUBW            AAA,BBB          ; var1 -CON1(AAA >= BBB,FC为1)
       B0BTS1          FC               ; 也可以用 B0BTS0
       JMP             JMP_XXX          ; var1 < CON1
       ...                              ; var1 > CON1

4.4 用@JMP_A 跳转表实现如C语言switch功能

B0MOV  A, BUF0  ; “BUF0”从 04。
@JMP_A  5       ; 列表个数为 5。
JMP  A0POINT    ; ACC = 0,跳至 A0POINT。
JMP  A1POINT    ; ACC = 1,跳至 A1POINT。
JMP  A2POINT    ; ACC = 2,跳至 A2POINT。
JMP  A3POINT    ; ACC = 3,跳至 A3POINT。
JMP  A4POINT    ; ACC = 4,跳至 A4POINT。

5 按键检测程序

5.1 按键引脚连接同一个端口

例如:key0、key1、key2、key3 分别连接 P1端口的P1.0、P1.1、P1.2、P1.3;

;最后 keycode 返回的是序号,而不是 TBL_KEY 表中的值
KEYIN:
        MOV             A,P1                     ; (有按键按下,相应位为0)
        XOR             A,#0xFF                  ; 此处是为了避免不按键时与结束码相同,键码取反(即有按键按下,相应位为1)(XOR:相同为0,不同为1)
        AND             A,#0x0F                  ; 屏蔽非按键IO口
KEYIN1:
        B0MOV           R1,A                     ; A 保存了按键值,如果只有P1.0按下,则A值为0x01
        MOV             A,#0xFF
        B0MOV           R0,A                     ; R1 为按键状态,R0 为0xFF
KEYIN2:
        B0MOV           Y,#TBL_KEY$M
        B0MOV           Z,#TBL_KEY$L
        INCMS           R0                       ; 第一遍R0 == 0 ;第二遍 R0 == 1...
        NOP
        B0MOV           A,R0                     ; A 即 R0 的值;
        B0ADD           Z,A                      ; 第一遍 Z == #TBL_KEY$L;第二遍 Z 为 #TBL_KEY$L 的下一个地址;...(ADD,如果产生进位则 C = 1,否则 C = 0)
        B0BTS1          FC                       ; 
        JMP             FIND_KEYTBL
        INCMS           Y
        NOP
FIND_KEYTBL:
        MOVC                                      ; 查表(执行完 MOVC 指令后,所查找数据低字节内容被存入 ACC 中,而数据高字节内容被存入 R 寄存器。)
        CMPRS           A,R1                      ; A 存储的是 TBL_KEY 表中的值,R1 即按键状态                       
        JMP             KEYIN3                    ; A != R1 ,
        B0MOV           A,R0                      ; A == R1 , 将 R0 序号(0123...)赋值给keycode,而不是将TBL_KEY 表中的值     
        B0MOV           keycode,A
        RET
KEYIN3:
        CMPRS           A,#0xFF                   ; 比较,如果相等则跳过下一条指令(0xFF是TBL_KEY表中结尾的值,所以前面值都不等,最后一个就一定等)
        JMP             KEYIN2                    ; 没有查完 TBL_KEY 表,循环查找
        B0MOV           keycode,A                 ; 

        RET
       
TBL_KEY:                                           ; 如key0(P1.0)按下,按键值为0x01,
                    DW              0x0000         ; --------------->  无按键按下
                    DW              0x0001         ; --------------->  key0 按下
                    DW              0x0002         ; --------------->  key1 按下
                    DW              0x0004         ; --------------->  key2 按下
                    DW              0x0008         ; --------------->  key3 按下
                    DW              0x00FF         ; --------------->  无定义的按键值

5.2 按键引脚连接不同端口

例如:key0、key1、key2、key3 分别连接 P1端口的P5.4、P5.5、P1.2、P1.3;

KEYIN:
        MOV             A,P1
        XOR             A,#0xFF                  ; 此处是为了避免不按键时与结束码相同,键码取反
        AND             A,#(BIT2|BIT3)           ; 屏蔽非按键IO口(读取P1^2,P1^3)
        B0MOV           R1,A

        MOV             A,P5
        XOR             A,#0xFF                  ; 此处是为了避免不按键时与结束码相同,键码取反
        AND             A,#(BIT4|BIT5)           ; 屏蔽非按键IO口(读取P5^4,P5^5)
        OR              R1,A                     ; 综合P1 & P5两个IO口
KEYIN1:
        MOV             A,#0xFF
        B0MOV           R0,A
KEYIN2:
        B0MOV           Y,#TBL_KEY$M
        B0MOV           Z,#TBL_KEY$L
        INCMS           R0
        NOP
        B0MOV           A,R0
        B0ADD           Z,A
        B0BTS1          FC
        JMP             FIND_KEYTBL
        INCMS           Y
        NOP
FIND_KEYTBL:
        MOVC                                      ; 
        CMPRS           A,R1
        JMP             KEYIN3
        B0MOV           A,R0
        B0MOV           keycode,A
        RET
KEYIN3:
        CMPRS           A,#0xFF
        JMP             KEYIN2
        B0MOV           keycode,A                 ; 

        RET
     
TBL_KEY:                                           ; 如key0(P5.4)按下,按键值为0x10,
                    DW              0x0000         ; --------------->  无按键按下
                    DW              0x0010         ; --------------->  key0 按下
                    DW              0x0020         ; --------------->  key1 按下
                    DW              0x0004         ; --------------->  key2 按下
                    DW              0x0008         ; --------------->  key3 按下
                    DW              0x0030         ; --------------->  key0&key1 同时按下
                    DW              0x00FF         ; --------------->  无定义的按键值

6 定时器的使用

例如配置SN8P2711B定时器1(TC1),参考文章《SN8P2711B_英文参考手册.PDF》章节如下

  1. TC1 INTERRUPT OPERATION
  2. TIMER/COUNTER 1 (TC1)
.DATA
                    ORG             0h                  ; Data section start address 0
AccBuf              DS              1
PflagBuf            DS              1

.CODE
		    ORG	            0			;Code section start
            JMP		        Reset		    ;Reset vector
		    ORG	            8
            JMP             Inte_Service    ;中断服务函数
		    ORG	            10h
Reset:
			……
			CALL            Fun_Time_Init
			……

;-------------------------------------------------------------------------------
;定时器中断初始化函数,间隔10ms周期中断。Fcpu = 16Mhz / 16
;-------------------------------------------------------------------------------
Fun_Time_Init:
			B0BCLR          FTC1IEN             ; 禁止TC1 中断
			B0BCLR          FTC1ENB             ; 禁止TC1 定时器
			B0BCLR          FGIE                ; 关闭全局中断(在 STKP 寄存器)

			CLR             TC1M                ; 清 TC1M
			MOV             A,#0x20             ; Set TC1 Clock=fcpu/64 = 16M/16/64 = 15625
			OR              TC1M,A              ; 
			MOV             A,#0x64; 
			MOV             TC1C,A              ; TC1间隔Cycle=10.0ms  ,TC1C = 256 -0.01 * 15625) ≈ 100

			B0BCLR          FTC1IRQ             ; 清TC1中断请求标志
			B0BSET          FTC1IEN             ; 使能TC1中断
			B0BSET          FTC1ENB             ; 开启TC1 定时器
			B0BSET          FGIE                ; 使能全局中断
			RET

;-------------------------------------------------------------------------------
;定时器中断服务函数
;-------------------------------------------------------------------------------			
Inte_Service:
			;Save ACC and PFLAG to buffers.
			b0xch	    A,AccBuf	   ; A <---> AccBuf	,将A值存于AccBuf
			b0mov       A,PFLAG
			b0mov       PflagBuf,A
;-------------user routine config start---------------	
			B0BTS1  	FTC1IRQ   ; Check TC1IRQ
			JMP  		EXIT_INT  ; TC1IRQ = 0, exit interrupt vector
			NOP 
			B0BCLR 	    FTC1IRQ  ; Reset TC1IRQ
			MOV  		A, #0x64
			B0MOV  		TC1C, A  ; Reset TC1C
;-------------user routine logic start---------------	
			……		
;-------------user routine end------------------------
			;Load ACC and PFLAG from buffers.
EXIT_INT:
			b0mov        A, PflagBuf
			b0mov        PFLAG, A	    ; Restore the PFlag
			b0xch	     A,AccBuf	    ; Restore the Reg. A				
			RETI		
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值