红外遥控步进电机运行.docx
《红外遥控步进电机运行.docx》由会员分享,可在线阅读,更多相关《红外遥控步进电机运行.docx(21页珍藏版)》请在冰豆网上搜索。
红外遥控步进电机运行
;********************************************************************
;**
;*红外遥控步进电机运行*
;**
;*MCU:
AT89S52晶振:
11.0592MHz*
;**
;**
;********************************************************************
;**
;*UP键按下步进电机正转,显示>>>>。
*
;*DOWM键按下步进电机反转,显示<<<<。
*
;*K1键按下步进电机停止转动,显示STOP。
*
;*+键减少延时时间,步进电机加速。
*
;*-键增加延时时间,步进电机减速。
*
;*步进电机转动时请先按K1停止后,再切换转动方向。
*
;**
;********************************************************************
;**
;*步进电机步进角为7.5度。
*
;**
;*单双八拍工作方式:
*
;*A-AB-B-BC-C-CD-D-DA(即一个脉冲,转3.75度)*
;**
;*A组线圈对应P1.0(桔色)*
;*B组线圈对应P1.1(棕色)*
;*C组线圈对应P1.2(黄色)*
;*D组线圈对应P1.3(黑色)*
;**
;********************************************************************
IRCOMEQU31H;31H-34HIR使用
RATEEQU38H
COUNTEQU39H
TEMPEQU3AH
IRINBITP3.2
BEEPBITP3.7
;**********************************************************
ORG0000H
AJMPMAIN
ORG0003H;外部中断INT0的中断向量地址
LJMPIR_IN
ORG001BH;定时器0的中断向量地址
LJMPTIMER1
ORG0050H
;**********************************************************
;主程序
;**********************************************************
MAIN:
MOVSP,#60H
MOVP1,#0F0H;步进电机断电
MOVA,#00H
MOVR0,#IRCOM
LOOP0:
MOV@R0,A;31-37H清零
INCR0
CJNER0,#IRCOM+7,LOOP0
MOVRATE,#9
SETBIRIN
SETBIT0;;下降沿触发
SETBEX0;;使能INT0外部中断
MOVTMOD,#10H;工作于方式1
MOVTH1,#0F8H;2ms定时常数
MOVTL1,#0CCH
SETBET1;允许定时/计数器0中断
SETBEA;开总中断
ACALLLCD_INIT;LCD初始化
ACALLSET_LCD
MOVDPTR,#BJ1;显示停止标记
ACALLRUN_BJ
LOOP1:
ACALLCODE_CONV
ACALLRATE_PLAY
MOVA,TEMP;
CJNEA,#10H,LOOP2;是否为遥控的K1键
MOVDPTR,#BJ1;显示停止标记
ACALLRUN_BJ
CLRTR1;
MOVP1,#0F0H;步进电机断电
LOOP2:
CJNEA,#1DH,LOOP3;是否为遥控的UP键
MOVDPTR,#BJ2;显示正转标记
ACALLRUN_BJ
MOVDPTR,#TABLE_F;选择工作方式(正转)
MOVR0,#00H
SETBTR1
LOOP3:
CJNEA,#12H,LOOP4;是否为遥控的DOWN键
MOVDPTR,#BJ3;显示反转标记
ACALLRUN_BJ
MOVDPTR,#TABLE_R;选择工作方式(正转)
MOVR0,#00H
SETBTR1
LOOP4:
MOVTEMP,#00H;清临时存放单元
AJMPLOOP1
;**********************************************************
;LCD初始化显示
;**********************************************************
SET_LCD:
MOVB,#00H
MOVDPTR,#INFO1
ACALLW_STRING1;显示信息字符串1
MOVB,#00H
MOVDPTR,#INFO2
ACALLW_STRING2;显示信息字符串2
RET
INFO1:
DB"IR_CODE:
--H",0;LCD第一行显示信息
INFO2:
DB"RATE:
",0;LCD第二行显示信息
;**********************************************************
;标记字符写入子程序
;**********************************************************
RUN_BJ:
MOVLCD_X,#0AH;指定写入地址
ACALLSET_X2
MOVR1,#0
MOVR0,#4;写4个标记字符
RUN_BJ1:
MOVA,R1
MOVCA,@A+DPTR;读出要写的标记字符
ACALLWDATA;写入标记字符
INCR1
DJNZR0,RUN_BJ1;没有写完,继续
RET
BJ1:
DB"STOP";停止标记
BJ2:
DB">>>>";正转标记
BJ3:
DB"<<<<";反转标记
;**********************************************************
;IR译码子程序
;R0---存放IR数据
;R2---高电平宽度的计数值
;R3---一字节需接收8位计数
;**********************************************************
IR_IN:
CLREA;暂时关闭CPU的所有中断请求
PUSHACC
PUSHPSW
SETBRS0;选择工作寄存器组1
MOVR0,#IRCOM
MOVR4,#30
IR_IN1:
ACALLDEL;延时4ms,去干扰再确认IR信号是否出现
DJNZR4,IR_IN1
JBIRIN,IR_END;如果IRIN=1没有IR信号出现,则退出
WAIT_H:
JBIRIN,WAIT_H1;等IR变为高电平避开9ms低电平引导脉冲
ACALLDEL
AJMPWAIT_H
WAIT_H1:
MOVR3,#0;8位数清为0
WAIT_L:
JNBIRIN,WAIT_H2;等IR变为低电平
ACALLDEL
AJMPWAIT_L
WAIT_H2:
JBIRIN,IR_COUN;等IR变为高电平
ACALLDEL
AJMPWAIT_H2
IR_COUN:
MOVR2,#0;对高电平进行0.14ms计数
IR_COUN1:
ACALLDEL
JBIRIN,IR_COUN2;等IR变为高电平
;IR=0,检查R2中的计数值
MOVA,#8
CLRC;清借位标志
SUBBA,R2;判断高低位
;若C=0,则解码为“0"
;若C=1,则解码为“1"
MOVA,@R0;取出原先的数据
RRCA;将借位标志C移入A
MOV@R0,A;处理完一位,将数据写入
INCR3;接收字节计数加1
CJNER3,#8,WAIT_L;需处理完8位
MOVR3,#0
INCR0;存放IR数据值加1
CJNER0,#IRCOM+4,WAIT_L;收集到4字节了
AJMPIR_SHOW
IR_COUN2:
INCR2
CJNER2,#20,IR_COUN1;0.14ms计数过长,则自动离开
IR_END:
POPPSW
POPACC
SETBEA
RETI
IR_SHOW:
MOVA,IRCOM+2
CPLA;将22H取反后和23H比较
CJNEA,IRCOM+3,IR_END;如果不等表示接收数据发生错误,放弃。
MOVA,IRCOM;比较用户编码
CJNEA,#00H,IR_END;如果不等表示遥控器错误,放弃。
ACALLBEEP_BL;蜂鸣器鸣响表示解码成功
MOVTEMP,IRCOM+2;存入临时存放单元
MOVA,IRCOM+2
CJNEA,#09H,IR_SHOW2;是否为遥控器的“+”键
MOVA,RATE
CJNEA,#4,IR_SHOW1;速率值达到最小值
AJMPIR_SHOW4
IR_SHOW1:
DECRATE;速率值减1
IR_SHOW2:
CJNEA,#1FH,IR_SHOW4;是否为遥控器的“-”键
MOVA,RATE
CJNEA,#15,IR_SHOW3;速率值达到最大值
AJMPIR_SHOW4
IR_SHOW3:
INCRATE;速率值加1
IR_SHOW4:
AJMPIR_END
;**********************************************************
;定时器1中断服务子程序(负责步进电机运行)
;**********************************************************
TIMER1:
PUSHACC;入栈保护
PUSHPSW
MOVTH1,#0F8H;2ms定时
MOVTL1,#0CCH
INCCOUNT;中断计数加1
MOVA,COUNT
CJNEA,RATE,T1_END;延时(RATE)毫秒
MOVCOUNT,#00H;清计数单元
MOVA,R0
MOVCA,@A+DPTR;查表取驱动码
MOVP1,A;输出驱动码
INCR0
CJNER0,#08H,T1_END;一个周期数据取完?
MOVR0,#00H
T1_END:
POPPSW
POPACC;出栈恢复
RETI
;**********************************************************
;编码数据转换与显示子程序
;**********************************************************
CODE_CONV:
MOVLCD_X,#0AH;10列
ACALLSET_X1;第一行
MOVA,IRCOM+2
ANLA,#0F0H;取出高四位数
SWAPA;高四位与低四位互换
CLRC;C=0
CJNEA,#0AH,ASC_H1
ASC_H1:
JCASC_H2;>=时,C=0;<时,C=1
ADDA,#07H;大于等于10的数加上37H
ASC_H2:
ADDA,#30H;小于10的数加上30H
ACALLWDATA;写数据
MOVA,IRCOM+2
ANLA,#0FH;取出低四位数
CLRC;C=0
CJNEA,#0AH,ASC_L1
ASC_L1:
JCASC_L2;>=时,C=0;<时,C=1
ADDA,#07H;大于等于10的数加上37H
ASC_L2:
ADDA,#30H;小于10的数加上30H
ACALLWDATA;写数据
RET
;**********************************************************
;速率显示子程序
;**********************************************************
RATE_PLAY:
MOVLCD_X,#07H;7列
ACALLSET_X2;第二行
MOVA,RATE
SUBBA,#03H
MOVB,#10
DIVAB
ADDA,#30H;十位
CJNEA,#30H,RATE_W
MOVA,#20H;十位为0不显示
RATE_W:
ACALLWDATA
MOVA,B
ADDA,#30H;个位
ACALLWDATA
RET
;**********************************************************
;蜂鸣器驱动子程序
;**********************************************************
BEEP_BL:
MOVR6,#180
BL1:
ACALLDEX1
CPLBEEP
DJNZR6,BL1
RET
DEX1:
MOVR7,#220;716us
DEX2:
NOP
DJNZR7,DEX2
RET
;**********************************************************
;延时0.14ms
;IR解码使用
;11.0592MHz,1.085us×(64×2)+2=140us
;**********************************************************
DEL:
MOVR7,#64
DJNZR7,$
RET
;**********************************************************
;单双八拍工作方式
;**********************************************************
TABLE_F:
DB0F1H,0F3H,0F2H,0F6H,0F4H,0FCH,0F8H,0F9H
DB0FFH;正转表
TABLE_R:
DB0F9H,0F8H,0FCH,0F4H,0F6H,0F2H,0F3H,0F1H
DB0FFH;反转表
;**********************************************************
$INCLUDE(LCD.ASM)
;**********************************************************
END;结束
;**********************************************************
/*******************************************************************
**
*红外遥控步进电机运行*
**
*MCU:
AT89S52晶振:
11.0592MHz*
**
**
********************************************************************
**
*UP键按下步进电机正转,显示>>>>。
*
*DOWM键按下步进电机反转,显示<<<<。
*
*K1键按下步进电机停止转动,显示STOP。
*
*+键减少延时时间,步进电机加速。
*
*-键增加延时时间,步进电机减速。
*
*步进电机转动时请先按K1停止后,再切换转动方向。
*
**
********************************************************************
**
*步进电机步进角为7.5度。
*
**
*单双八拍工作方式:
*
*A-AB-B-BC-C-CD-D-DA(即一个脉冲,转3.75度)*
**
*A组线圈对应P1.0(桔色)*
*B组线圈对应P1.1(棕色)*
*C组线圈对应P1.2(黄色)*
*D组线圈对应P1.3(黑色)*
**
*******************************************************************/
#include//管脚定义头文件
#include"lcd.h"
#defineucharunsignedchar
#defineuintunsignedint
sbitBEEP=P3^7;//蜂鸣器
sbitIRIN=P3^2;//红外接收端口
bitdirection;//方向标志
bitflag=0;//红外接收有效标志
ucharcodecdis1[]={"IR_CODE:
--H"};
ucharcodecdis2[]={"RATE:
"};
ucharcodecdis3[]={"STOP"};//停止
ucharcodecdis4[]={">>>>"};//正转
ucharcodecdis5[]={"<<<<"};//反转
ucharcount1=0,count2=0;
ucharrate=9;//预设定速率值
ucharIRCOM[6];
ucharcodeFFW[8]=//正转表
{
0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9
};
ucharcodeREV[8]=//反转表
{
0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1
};
charcodereserve[3]_at_0x3b;//保留0x3b开始的3个字节
/**********************************************************
x*0.14ms延时子函数
**********************************************************/
voiddelay(ucharx)
{
uchari;
while(x--)
{
for(i=0;i<14;i++)
;
}
}
/**********************************************************
蜂鸣器响一声
**********************************************************/
voidbeep(void)
{
uchari;
for(i=0;i<200;i++)
{
delay(5);
BEEP=!
BEEP;//BEEP取反
}
BEEP=1;//关闭蜂鸣器
}
/**********************************************************
编码转换与显示子函数
**********************************************************/
voidcode_conv(void)
{
IRCOM[4]=IRCOM[2];
IRCOM[5]=IRCOM[4]&0x0f;//低位
if(IRCOM[5]>0x09)
IRCOM[5]=IRCOM[5]+0x37;
else
IRCOM[5]=IRCOM[5]+0x30;
IRCOM[4]=(IRCOM[4]&0xf0)>>4;//高位
if(IRCOM[4]>0x09)
IRCOM[4]=IRCOM[4]+0x37;
else
IRCOM[4]=IRCOM[4]+0x30;
lcd_pos(10,1);//第一行10列
lcd_wdat(IRCOM[4]);
lcd_wdat(IRCOM[5]);
}
/**********************************************************
速率显示子函数
**********************************************************/
voidrate_conv(void)
{
ucharrate_l,rate_h;
rate_h=(rate-3)/10;//高位
if(rate_h==0)
rate_h=0x20;//高位为0不显示
else
rate_h=rate_h+0x30;
rate_l=(rate-3)%10;//低位
rate_l=rate_l+0x30;
lcd_pos(7,2);//第二行7列
lcd_wdat(rate_h);
lcd_wdat(rate_l);
}
/**********************************************************
主函数
**********************************************************/
voidmain(void)
{
P0=0xff;//端口初始化
P2=0xff;
P1=0xf0;//步进电机断电
lcd_init();//LCD1602初始化
lcd_pos(0,1);//设置显示位置为第一行
wr_string(cdis1,0);//显示字符串1
lcd_pos(0,2);//设置显示位置为第二行
wr_string(cdis2,0);//显示字符串2
lcd_pos(10,2);//第二行10列
wr_string(cdis3,0);//显示停止标记
TMOD=0x01;//