⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivers.asm

📁 基于凌阳61和pwm电机实现的智能车总程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
.INCLUDE HARDWARE.ASM


SET_IOA_IN: .MACRO  //USING R1 FOR TEMP
  R1 = 0x00ff
  [P_IOA_Dir] = R1
  R1 = 0xFFFF
  [P_IOA_Attrib] = R1 
.ENDM

SET_IOA_OUT: .MACRO //USE R1 FOR TEMP
  R1 = 0xFFFF
  [P_IOA_Attrib] = R1
  [P_IOA_Dir] = R1
.ENDM

RD_8279_FIFORAM: .MACRO //改变了 R1,R2的值,使用 R1 返回函数值
  SET_IOA_IN;
  R2 = C_RD_FIFORAM
  [P_IOB_Data] = R2;
//  R1 = 0x0000
//  [P_IOA_Data] = R1;
  R1 = [P_IOA_Data];
  R2 = C_IOB_DEFAULT & ~C_8279_A0
  [P_IOB_Data] = R2
.ENDM 

RD_8279_STATUS: .MACRO //改变了 R1,R2的值,使用 R1 返回函数值
  SET_IOA_IN;
  R2 = C_RD_STATUS 
  [P_IOB_Data] = R2;
//  R1 = 0x0000
//  [P_IOA_Data] = R1;
  R1 = [P_IOA_Data];
  R2 = C_IOB_DEFAULT 
  [P_IOB_Data] = R2
.ENDM 

WR_8279_DISPLAYRAM: .MACRO DATA  //改变了 R1,R2 的值
//  .IFMA 0
//    .MACEXIT
//  .ENDIF
  SET_IOA_OUT;
  R2 = C_WR_RAM
  [P_IOB_Data] = R2;
  R1 = DATA;
  R2 = [P_IOA_Data]
  R2 = R2 & 0x00FF
  R1 = R1 | R2
  [P_IOA_Data] = R1;
  R2 =  C_IOB_DEFAULT & ~C_8279_A0
  [P_IOB_Data] = R2;
.ENDM

WR_8279_CONTROL: .MACRO DATA  //改变了 R1,R2 的值
//  .IFMA 0
//    .MACEXIT
//  .ENDIF
  SET_IOA_OUT;
  R2 = C_WR_CONTROL
  [P_IOB_Data] = R2;
  R1 = DATA;
  R2 = [P_IOA_Data]
  R2 = R2 & 0x00FF
  R1 = R1 | R2
  [P_IOA_Data] = R1;
  R2 =  C_IOB_DEFAULT ;
  [P_IOB_Data] = R2;
.ENDM

EXCHANGER4: .MACRO
  BP = discode;
  R4 = R4 LSR 4
  R4 = R4 LSR 4
  r4 =r4 + bp
  R4 = [R4]
.ENDM

EXCHANGER3: .MACRO
  bp = discode;
  r3 = r3 + bp
  R3 = [R3]
.ENDM

CLEAR_WATCHDOG: .MACRO  //USE R1
  R1 = 0x0001
  [P_Watchdog_Clear] = R1
.ENDM        


.external CPointFlag,TurnLeftNoPwm,ForwardNoPwm
.external Time
.iRAM
.VAR counter = 4;
.VAR LastState = 0;
.var Total = 0
.var B2C = 0
.public TestObjectFlag
.var TestObjectFlag = 0  //一左\二右\三双\零无障
.public TimeB2C
.var TimeB2C=0
.public Time5Sec
.var Time5Sec=0
.public Time5SecFlag
.var Time5SecFlag=0
.public LastIntCtrlStatus
.var LastIntCtrlStatus

.DATA
.public discode
discode:
.DW 0x3F00,0x0600,0x5b00,0x4f00,0x6600,0x6d00,0x7d00,0x0700,0x7f00,0x6f00;

//==============================================================================
//==============================================================================

.CODE
//////////////////////////
//  SP061 INITIAL       //
//----------------------//
.PUBLIC _SP061_INIT
_SP061_INIT: .PROC
       INT OFF
       R1 = 0x0008
       [P_SystemClock] = R1 
       BP = discode;
/////////////////////
//P_IOA Initial
/////////////////////
     //A口全部做为带下拉电阻的输入口
     R1=0xFFFF;               //A口输入
     [P_IOA_Dir]=R1;
     [P_IOA_Attrib]=R1;
     
     //P_IOB Initial
     //IOB2--->EXT1; IOB3--->EXT2
     R1 = 0x01F3;	                 //设置IOB2,IOB3为输入
	 [P_IOB_Dir] = R1;               //
	 R1 = 0xFFF3;                    //IOB2,IOB3设置为输入,高8位输入
	 [P_IOB_Attrib] = R1;            //
	 R1 = 0xFFFF	
	 [P_IOB_Data] = R1;  
	   
	 //中断控制寄存器设置
	 R1 = 0xFFFF
	 [P_INT_Clear] = R1
	 R1 = 0x020C; 				     //开中断IRQ3_EXT1
	 [P_INT_Ctrl] = R1
	 [P_INT_New] = R1
	 
	 r1 = 0x0001
	 [P_Watchdog_Clear] = R1
	 
	 //Timer initial
	 r1 = 0x0007
	 [P_TimerB_Ctrl] = r1
	 r1 = 0x0000
	 [P_TimerB_Data] = r1
	 
//	 r1 = 0x0000
//	 [P_TimeBase_Setup] = r1
	 
	 CALL INIT_8279

	 INT IRQ;                        //开中断
RETF
.ENDP

//**********************************************//
//Function Name : INIT_8279                     //
//Function : none                               //
//Input    : R1, R2                             //
//Output   : initial 8279,display GOOD on leds  //
//Destroy  : R1,R2                              //
.PUBLIC INIT_8279
INIT_8279: .PROC
  WR_8279_CONTROL 0x0100  //键盘/显示方式命令字
                          //8个字符显示左入口,编码扫描键盘双键锁定
  WR_8279_CONTROL 0x3800  //8279扫描频率设定
  WR_8279_CONTROL 0xD300  //清显示、FIFO RAM
?LOP:
  nop
  RD_8279_STATUS          //读状态REG,比较是否清除完成
  TEST R1,0x8000
  JNZ ?LOP
  WR_8279_CONTROL 0x8000  //地址非自动增加,显示RAM 0x00
  WR_8279_DISPLAYRAM C_SEG_g  //显示 g
  WR_8279_CONTROL 0x8100  //地址非自动增加,显示RAM 0x01
  WR_8279_DISPLAYRAM C_SEG_o  //显示 o
  WR_8279_CONTROL 0x8200  //地址非自动增加,显示RAM 0x02
  WR_8279_DISPLAYRAM C_SEG_o  //显示 o
  WR_8279_CONTROL 0x8300  //地址非自动增加,显示RAM 0x03
  WR_8279_DISPLAYRAM C_SEG_d  //显示 d
  RETF
.ENDP

.PUBLIC DisplayKey
DisplayKey: .proc
  push r2,r4 to [sp]
  R3 = [counter]
  cmp r3,0x0
  jne ?next
  r3 = 4
  [counter] = r3
?next:
  R3 = [counter]
  R3 = R3 LSL 4
  R2 = R3 LSL 4
  R3 = 0x8400
  R3 = R3 - R2
  EXCHANGER4
  WR_8279_CONTROL R3
  WR_8279_DISPLAYRAM R4
  R3 = [counter]
  r3 -=1
  [counter]= r3
  pop r2,r4 from [sp] 
retf
.endp

//*************************************//
//          计算速度函数               //
// 参数: R1 为计数值                  //
// 返回:R3中为速度值,R4中为方向状态  //
//       R4     |      方向            //
//       ------------------            //
//        0     |       正             //
//        1     |       反             //     
.public CalV
CalV: .proc
  r2 = 8          //  单位长度/一秒钟
  mr = r1 * r2,us
  r1 = r3
//  r2 = 10
//  call F_Divider
  SET_IOA_IN
  R1 = [P_IOA_Data]
  test r1,C_CAR_Dir
  JZ BACKWARD
FORWARD:
  R4 = 0;
  JMP EXIT
BACKWARD:
  R4 = 1;
EXIT:
retf
.endp

//*************************************//
//          计算路程函数               //
// 参数: R1 为计数值                  //
// 返回:R3中为总路程                  //
//                 //
//                 //
//                   //
//                   //  
.public CalLong
CalLong: .proc
  r2 =  4         //  单位长度/一个脉冲
  mr = r1 * r2,us
  cmp r3,140
  jbe next1
GoToC:
  r1 = 1
  [B2C] = r1  
next1:  
  r1 = [CPointFlag]
  test r1,0
  jne quit
  cmp r3,260
//  CMP R3,300
  jbe quit
  
setCPointFlag:
  r1 = 1
  [CPointFlag] = r1
  
quit:   
retf
.endp

//**********************************************//
//Function Name : F_Divder                      //
//Function : R1/R2                              //
//Input    : R1, R2                             //
//Output   : R3; Integer value                  //
//Destroy  : All                                //
//                                                                             
.PUBLIC F_Divider
F_Divider: .proc

         R4 = R1;
         R3 = 0;
         R5 = 0;
Loop_1:
         CMP  R4,R2;
         JB   Loop_2;
         R4 -= R2;
         R3 += 1;
         JMP  Loop_1;
Loop_2:
         R5 += 1;
         CMP  R5,8;                     //Scale : 1/(2^8) = 1/256
         JG   EndDivide;
         R3 = R3 LSL 1;
         R4 = R4 LSL 1;
         JMP Loop_1;
EndDivide:
         R3 = R3 LSR 4;                 //R3/(2^8)
         R3 = R3 LSR 4;
         RETF;
.ENDP

//**********************************************//
//Function Name : Hex2Dec                       //
//Function : Hex2Dec void                       //
//Input    : R3                                 //
//Output   : R3; display on LED                 //
//Destroy  : All                                //
.PUBLIC Hex2Dec
Hex2Dec: .PROC
  push r3 to [sp]
  push r3 to [sp]
  r1 = r3
  R2 = 100  //转换百位
  CALL F_Divider
  PUSH R3 TO [SP]
  WR_8279_CONTROL 0x8100  //将百位显示在数码管上
  EXCHANGER3  //换码
  WR_8279_DISPLAYRAM R3
  POP R3 FROM [SP]
  r2 = 100
  mr = R3*r2,us  //恢复
  r1 = r3
  pop r3 from [sp]
  r3 = r3 -r1  //求第一次余数
  push r3 to [sp]
  R1 = R3
  r2 = 10  //在余数中转换十位
  call F_Divider
  PUSH R3 TO [SP]
  WR_8279_CONTROL 0x8200  //将十位显示在数码管上
  EXCHANGER3  //换码
  WR_8279_DISPLAYRAM R3
  POP R3 FROM [SP]
  r2 = 10
  mr = r2*r3,us  //恢复
  r1 = r3
  pop r3 from [sp]
  r3 = r3 - r1  //求第二次余数即个位
  WR_8279_CONTROL 0x8300  //将个位显示在数码管上
  EXCHANGER3  //换码
  WR_8279_DISPLAYRAM R3  
  pop r3 from [sp]
RETF
.ENDP

//**********************************************//
//Function Name : TurnLeft                      //
//Function :  TurnLeft (void)                   //
//Input    : none                               //
//Output   : car turn left                      //
//Destroy  : none                               //
.public TurnLeft
TurnLeft: .proc
  push r1,r2 to [sp]
  SET_IOA_IN;
//  r2 = C_CAR_TurnLeft2
//  r1 = [P_IOA_Data]
  r1 = 0x000f
  r2 = [P_IOA_Data]
  r1 = r1 | r2
//  r2 = 0xfffA
  R2 = r1 & 0xFFF5
//  r2 = r2 & r1
  SET_IOA_OUT
  [P_IOA_Data] = R2
  
  r1 = [B2C]
  test r1,1
  jz ?straight
?round:
  r1 = 0x0500
  r2 = 0x0300
  call F_Pwm
  pc = ?go  
?straight:  
  r1 = 0x0500
  r2 = 0x0230
  call F_Pwm
  call delay_1

?go:
  pop r1,r2 from [sp]
retf
.endp

//**********************************************//
//Function Name : TurnRight                     //
//Function :  TurnRight (void)                  //
//Input    : none                               //
//Output   : car turn right                     //
//Destroy  : none                               //
.PUBLIC TurnRight
TurnRight: .proc
  push r1,r2 to [sp]
  SET_IOA_IN;
//  r2 = C_CAR_TurnRight1
//  r2 = 0xfff5
  r1 = 0x000f
  r2 = [P_IOA_Data]
  r1 = r1 | r2
  R2 = r1 & 0xFFFA
//  r2 = r2 & r1
  SET_IOA_OUT
  [P_IOA_Data] = R2
  r1 = [B2C]
  test r1,1
  jz ?straight
?round:
  r1 = 0x0fff
  r2 = 0x0150
  call F_Pwm
  pc = ?go  
?straight:  
  r1 = 0x0fff
  r2 = 0x0180
  call F_Pwm
?go:
//  call delay_1
  pop r1,r2 from [sp]
retf
.endp


.public LastTurnRight
LastTurnRight: .proc
  SET_IOA_IN
  R1 =[P_IOA_Data]
  R1 = R1 & 0xfff0
  R1= R1|0x000a          //////////右转控制逻辑////////
  R2 = R1
  SET_IOA_OUT
  [P_IOA_Data] = R2
  R1 = 0x0500
  R2 = 0x0300
  CALL F_Pwm

  R1 = 0x0150          //////右转时间
  LOP:
R1 -=1
PUSH R1,R5 TO [SP]
NOP
POP R1,R5 FROM [SP]
CMP R1,0
JNE LOP
Retf
.endp

//**********************************************//
//Function Name : Forward                       //
//Function :  Forward  (void)                   //
//Input    : none                               //
//Output   : car go Forward                     //
//Destroy  : none                               //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -