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

📄 main.asm

📁 精密混合直线步进电机8细分驱动程序,带转速显示功能
💻 ASM
字号:
//step motor driver //
//A0--黄线,A1--茶线,A2--绿线,A3--青线,A4完成开关次数后的指示灯//
//功能:实现步进电机以90度角正反旋转,开关9999次后亮LED灯//
//共阴极四位8段数码管//
//内部计算显示,0~9999的显示//
//A8~A15控制数值,B8~B15控制位选//
//code by ohf//

.DEFINE	P_IOA_Data   		0x7000;        
.DEFINE P_IOA_Dir           0x7002;       
.DEFINE P_IOA_Attrib        0x7003; 
.DEFINE P_IOB_Data         	0x7005;               
.DEFINE P_IOB_Dir           0x7007;        
.DEFINE P_IOB_Attrib        0x7008;  
.DEFINE P_Watchdog_Clear    0x7012;   
.RAM                  //变量单元地址段预定义
.var COUNTER_1;       //定义延时外循环计数器1
.var COUNTER_2;       //定义延时内循环计数器2
.var COUNTER_3;       //显示时间延时参数
.var COUNTER1;       //定义延时外循环计数器1
.var COUNTER2;       //定义延时外循环计数器2
.var angle;       //旋转角度
.Var display_number;  //显示的数值,即开关的次数
.var qian_ADDRESS;  //千位地址变量
.var bai_ADDRESS;  //百位地址变量     
.var shi_ADDRESS;  //十位地址变量
.var ge_ADDRESS;  //个位地址变量  

.DATA 
   LED_ADDRESS: .DW 0xB700,0x0600,0x7300,0x5700,0xC600,0xD500,0xF500,0x0700,0xF700,0xD700;  //'0''1''2''3''4''5''6''7''8''9'的代码,接A口
   LED_dig: .DW 0x0100,0x0200,0x0400,0x0800;   //'个位','十位','百位','千位'代码,接B口
   step_code: .DW 0x0001,0x0003,0x0002,0x0006,0x0004,0x000C,0x0008,0x0009 //每步的代码,CCW
step_code1: .DW 0x0009,0x0008,0x000c,0x0004,0x0006,0x0002,0x0003,0x0001 //每步的代码,CW
.CODE                //主程序单元地址段预定义
.PUBLIC _main;       //定义主程序
_main:
call io_int;        //IO口初始化,A与B口都为低电平输出口
R2=0;
[display_number]=R2;   //开关次数初始为零
Loop_main:
R2=0x0096;            //设置旋转角90度
call step_rotor_CCW;  //CCW转动90度

R2=0x0096;           //设置旋转角90度
call step_rotor_CW;   //CW转动90度
R2=[display_number];   //开关次数显示数值加一
R2+=1;
[display_number]=R2;
call kaiguan_disp;   //显示开关次数
R2=[display_number];   
cmp R2,9999;  
JAE  Loop_stop; //大于或等于9999,则停止运行
JMP Loop_main;   //小于9999,继续循环开关
Loop_stop:
call kaiguan_disp;   //显示开关次数
jmp Loop_stop;          //停止开关,循环显示次数

kaiguan_disp:.proc        //开关次数显示
R1=0x002F;              //延时参数
[COUNTER_3]=R1;
display_loop_1:
call display;    //数值显示
R1=[COUNTER_3]
R1-=0x0001;
[COUNTER_3]=R1;
JNZ display_loop_1;
RETF;                     //子程序返回
.endp  

io_int:  .proc        //程序初始化
R1=0xFFFF;              //设定IOA0口为带数据缓存器的输出口
[P_IOA_Dir]=R1;
[P_IOA_Attrib]=R1;
[P_IOB_Dir]=R1;
[P_IOB_Attrib]=R1;
R1=0x0000;   
[P_IOA_Data]=R1;      //IOA0初始化 低电平输出      
[P_IOB_Data]=R1;      //IOA0初始化 低电平输出    
RETF;                     //子程序返回
.endp  

step_rotor_CCW:  .proc        //CCW转向子程序
main_loop:
[angle]=R2;     //旋转角度
BP=step_code;      //送CCW步进代码
ccw_loop:
R1=[BP];
[P_IOA_Data]=R1;   //步进代码送输出口
CALL DELAY;        //调用延时子程序0.01秒
BP=BP+1;            //下一步代码
cmp R1,0x0009;    //判断是否完成一周
jne ccw_loop;          //没完成跳转下一步
R2=[angle]
R2-=1;
cmp R2,0x0000;    //判断是否完成旋转角度
jne main_loop;     //未完成旋转角度则继续执行

R1=0x0000;
[P_IOA_Data]=R1;     //电机停止转动1秒
CALL DELAY1;        //调用延时子程序1秒
CALL DELAY1;        //调用延时子程序1秒
RETF;                     //子程序返回
.endp  

step_rotor_CW:  .proc        //CCW转向子程序
main_loop1:
[angle]=R2; 
BP=step_code1;      //送步进代码首地址
cw_loop:
R1=[BP];
[P_IOA_Data]=R1;   //步进代码送输出口
CALL DELAY;        //调用延时子程序0.01秒
BP=BP+1;            //下一步代码
cmp R1,0x0001;    //判断是否完成一周
jne cw_loop;          //没完成跳转下一步
R2=[angle]
R2-=1;
cmp R2,0x0000;    //判断是否完成旋转角度
jne main_loop1;     //未已完成继续循环
R1=0x0000;
[P_IOA_Data]=R1;     //电机停止转动1秒
RETF;                     //子程序返回
.endp 

display: .PROC;           //显示子程序定义
//BCD转换//
R1=0x0001;
[P_Watchdog_Clear]=R1;   //清狗
R2=0; //地址清零,
[qian_ADDRESS]=R2;    //千位
[bai_ADDRESS]=R2;     //百位
[shi_ADDRESS]=R2;     //十位
[ge_ADDRESS]=R2;      //个位
R1=[display_number];
cmp R1,1000;   //与1000比较
jb L_baiwei;   //小于1000转跳

L_qianwei:
R1-=1000;      //若大于或等于则减1000
R2=[qian_ADDRESS];     //千位变量值加一
R2+=1;
[qian_ADDRESS]=R2;
cmp R1,1000;   //与1000比较
JAE L_qianwei;           //若大于或等于1000则跳转L_qianwei

L_baiwei:
cmp R1,100;   //与100比较
jb L_shiwei;   //小于100转跳L_shiwei
R1-=100;      //若大于或等于100则减100
R2=[bai_ADDRESS];     //百位变量值加一
R2+=1;
[bai_ADDRESS]=R2;
cmp R1,100;   //与100比较
JAE L_baiwei;           //若大于或等于100则跳转L_baiwei

L_shiwei:
cmp R1,10;   //与10比较
jb L_gewei;   //小于10转跳L_gewei
R1-=10;      //若大于或等于10则减10
R2=[shi_ADDRESS];     //十位变量值加一
R2+=1;
[shi_ADDRESS]=R2;
cmp R1,10;   //与10比较
JAE L_shiwei;           //若大于或等于10则跳转L_shiwei

L_gewei:
[ge_ADDRESS]=R1;
//显示//
R4=0x0800;
[P_IOB_Data]=R4;  //千位位选
BP=LED_ADDRESS;
BP+=[qian_ADDRESS];
R4=[BP];
[P_IOA_Data]=R4;   //千位数数选
call L_DELAY;  //延时

R4=0x0400;
[P_IOB_Data]=R4;  //百位位选
BP=LED_ADDRESS;
BP+=[bai_ADDRESS];
R4=[BP];
[P_IOA_Data]=R4;   //百位数选
call L_DELAY;  //延时

R4=0x0200;
[P_IOB_Data]=R4;  //十位位选
BP=LED_ADDRESS;
BP+=[shi_ADDRESS];
R4=[BP];
[P_IOA_Data]=R4;   //十位数选
call L_DELAY;  //延时

R4=0x0100;
[P_IOB_Data]=R4;  //个位位选
BP=LED_ADDRESS;
BP+=[ge_ADDRESS];
R4=[BP];
[P_IOA_Data]=R4;   //十位数选
call L_DELAY;  //延时
RETF;                     //子程序返回
.endp                    //延时子程序结束定义

DELAY:  .proc        //延时子程序起始定义 延时0.01秒
R2=0x01EF;            //定义外循环计数器初值
[COUNTER1]=R2;         
loop1:                 //循环
R2=[COUNTER1];
R2-=0x0001;                    //循环计数器减1
[COUNTER1]=R2;
JNZ loop1;                //计数值不为零跳转LOOP1 溢出则执行下一条指令 
R3=0x0001;
[P_Watchdog_Clear]=R3;   //清狗            
RETF;                     //子程序返回
.endp  

DELAY1:  .proc        //延时子程序起始定义 延时2秒
R2=0xffff;            //定义外循环计数器初值
[COUNTER2]=R2;         
loop2:                 //循环
R2=[COUNTER2];
R2-=0x0001;                    //循环计数器减1
[COUNTER2]=R2;
JNZ loop2;                //计数值不为零跳转LOOP1 溢出则执行下一条指令 
R3=0x0001;
[P_Watchdog_Clear]=R3;   //清狗            
RETF;                     //子程序返回
.endp  

L_DELAY:  .proc        //延时子程序起始定义 延时10豪秒
R2=0x0001;            //定义外循环计数器初值
[COUNTER_1]=R2;         
loop_1:                 //外循环
                
R2=0xFD6A;             //定义内循环计数器初值
[COUNTER_2]=R2;        
loop_2:                     //内循环 内循环结束延时0.01秒
R2=0x0001;
[P_Watchdog_Clear]=R2;   //清狗

R2=[COUNTER_2];
R2+=0x0001;               //内循环计数器加1
[COUNTER_2]=R2;
JNZ loop_2;                 //计数值不为零跳转loop_2 溢出则执行下一条指令

R2=[COUNTER_1];
R2-=0x0001;                    //外循环计数器减1
[COUNTER_1]=R2;
JNZ loop_1;                //计数值不为零跳转loop_1 溢出则执行下一条指令             
RETF;                     //子程序返回
.endp                    //延时子程序结束定义
.end

⌨️ 快捷键说明

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