红外遥控步进电机运行Word文档下载推荐.docx
《红外遥控步进电机运行Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《红外遥控步进电机运行Word文档下载推荐.docx(21页珍藏版)》请在冰豆网上搜索。
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键
CLRTR1;
LOOP2:
CJNEA,#1DH,LOOP3;
是否为遥控的UP键
MOVDPTR,#BJ2;
显示正转标记
MOVDPTR,#TABLE_F;
选择工作方式(正转)
MOVR0,#00H
SETBTR1
LOOP3:
CJNEA,#12H,LOOP4;
是否为遥控的DOWN键
MOVDPTR,#BJ3;
显示反转标记
MOVDPTR,#TABLE_R;
LOOP4:
MOVTEMP,#00H;
清临时存放单元
AJMPLOOP1
LCD初始化显示
SET_LCD:
MOVB,#00H
MOVDPTR,#INFO1
ACALLW_STRING1;
显示信息字符串1
MOVDPTR,#INFO2
ACALLW_STRING2;
显示信息字符串2
RET
INFO1:
DB"
IR_CODE:
--H"
0;
LCD第一行显示信息
INFO2:
RATE:
"
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;
没有写完,继续
BJ1:
STOP"
停止标记
BJ2:
"
正转标记
BJ3:
反转标记
IR译码子程序
R0---存放IR数据
R2---高电平宽度的计数值
R3---一字节需接收8位计数
IR_IN:
CLREA;
暂时关闭CPU的所有中断请求
PUSHACC
PUSHPSW
SETBRS0;
选择工作寄存器组1
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变为低电平
AJMPWAIT_L
WAIT_H2:
JBIRIN,IR_COUN;
等IR变为高电平
AJMPWAIT_H2
IR_COUN:
MOVR2,#0;
对高电平进行0.14ms计数
IR_COUN1:
JBIRIN,IR_COUN2;
IR=0,检查R2中的计数值
MOVA,#8
CLRC;
清借位标志
SUBBA,R2;
判断高低位
若C=0,则解码为“0"
若C=1,则解码为“1"
MOVA,@R0;
取出原先的数据
RRCA;
将借位标志C移入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;
存入临时存放单元
CJNEA,#09H,IR_SHOW2;
是否为遥控器的“+”键
MOVA,RATE
CJNEA,#4,IR_SHOW1;
速率值达到最小值
AJMPIR_SHOW4
IR_SHOW1:
DECRATE;
速率值减1
IR_SHOW2:
CJNEA,#1FH,IR_SHOW4;
是否为遥控器的“-”键
CJNEA,#15,IR_SHOW3;
速率值达到最大值
IR_SHOW3:
INCRATE;
速率值加1
IR_SHOW4:
AJMPIR_END
定时器1中断服务子程序(负责步进电机运行)
TIMER1:
PUSHACC;
入栈保护
2ms定时
INCCOUNT;
中断计数加1
MOVA,COUNT
CJNEA,RATE,T1_END;
延时(RATE)毫秒
MOVCOUNT,#00H;
清计数单元
MOVA,R0
查表取驱动码
MOVP1,A;
输出驱动码
CJNER0,#08H,T1_END;
一个周期数据取完?
MOVR0,#00H
T1_END:
POPACC;
出栈恢复
编码数据转换与显示子程序
CODE_CONV:
10列
ACALLSET_X1;
第一行
ANLA,#0F0H;
取出高四位数
SWAPA;
高四位与低四位互换
C=0
CJNEA,#0AH,ASC_H1
ASC_H1:
JCASC_H2;
=时,C=0;
时,C=1
ADDA,#07H;
大于等于10的数加上37H
ASC_H2:
ADDA,#30H;
小于10的数加上30H
写数据
ANLA,#0FH;
取出低四位数
CJNEA,#0AH,ASC_L1
ASC_L1:
JCASC_L2;
ASC_L2:
速率显示子程序
RATE_PLAY:
MOVLCD_X,#07H;
7列
ACALLSET_X2;
第二行
SUBBA,#03H
MOVB,#10
DIVAB
十位
CJNEA,#30H,RATE_W
MOVA,#20H;
十位为0不显示
RATE_W:
ACALLWDATA
MOVA,B
个位
蜂鸣器驱动子程序
BEEP_BL:
MOVR6,#180
BL1:
ACALLDEX1
CPLBEEP
DJNZR6,BL1
DEX1:
MOVR7,#220;
716us
DEX2:
NOP
DJNZR7,DEX2
延时0.14ms
IR解码使用
11.0592MHz,1.085us×
(64×
2)+2=140us
DEL:
MOVR7,#64
DJNZR7,$
单双八拍工作方式
TABLE_F:
DB0F1H,0F3H,0F2H,0F6H,0F4H,0FCH,0F8H,0F9H
DB0FFH;
正转表
TABLE_R:
DB0F9H,0F8H,0FCH,0F4H,0F6H,0F2H,0F3H,0F1H
反转表
$INCLUDE(LCD.ASM)
END;
结束
/*******************************************************************
*******************************************************************/
#include<
reg52.h>
//管脚定义头文件
#include"
lcd.h"
#defineucharunsignedchar
#defineuintunsignedint
sbitBEEP=P3^7;
//蜂鸣器
sbitIRIN=P3^2;
//红外接收端口
bitdirection;
//方向标志
bitflag=0;
//红外接收有效标志
ucharcodecdis1[]={"
};
ucharcodecdis2[]={"
ucharcodecdis3[]={"
//停止
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)
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]>
IRCOM[4]=IRCOM[4]+0x37;
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;
//