;******************************************************************************** ;* 日期: 2007-3-25 * ;* 版本: 3.0 * ;* 作者: 深圳学林电子有限公司 专业8051单片机教程站 * ;* 邮箱: sxj1974@163.com * ;* 网站: http://www.51c51.com http://www.8951.com 更多例程请登陆网站 * ;******************************************************************************** ;* 步进电机端口:P1.0,P1.1,P1.2,P1.3,遥控器接口p3.2喇叭p3.7 * ;* 硬件:此程序在本公司xlisp系列单片机实验仪运行通过 * ; 按遥控器6号 键按下,步进电机正转,LCD1602 显示>>>> 。* ;14号键按下步进电机反转,显示 <<<< 。 * ;1号键按下步进电机停止转动,显示 STOP 。 * ;步进电机转动时必须先按1停止后,才能切换转动方向 * ;******************************************************************************** ;* 【版权】 Copyright(C)深圳学林电子有限公司 www.51c51.com All Rights Reserved * ;* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! * ;******************************************************************************** IRCOM EQU 30H ;30H-33H IR使用 LCD_X EQU 36H ;LCD 地址变量 IRIN EQU P3.2 BEEP EQU P3.7 RELAY EQU P1.3 LCD_RS EQU P2.0 LCD_RW EQU P2.1 LCD_EN EQU P2.2 STOP_BJ BIT 20H.0 ;停止标记位 ;--------------------------------------------------------- ORG 0000H JMP MAIN ORG 0003H ;外部中断INT0入口地址 JMP IR_IN ORG 0080H ;--------------------------------------------------------- MAIN: MOV SP,#60H MOV P1,#0F0H ;关闭步进电机 MOV A,#00H MOV R0,#30H LOOP0: MOV @R0,A ;30H-36H清零 INC R0 CJNE R0,#37H,LOOP0 CLR STOP_BJ
MOV IE,#81H ;允许总中断中断,使能INT0外部中断 MOV TCON,#01H ;触发方式为脉冲负边沿触发
SETB IRIN CALL SET_LCD MOV DPTR,#BJ1 ;显示停止标记 CALL RUN_BJ LOOP1: MOV A,IRCOM+2 CJNE A,#1DH,LOOP2 ;UP键按下 MOV DPTR,#BJ2 CALL RUN_BJ ;显示正转标记 CALL FFW MOV DPTR,#BJ1 ;显示停止标记 CALL RUN_BJ LOOP2: CJNE A,#12H,LOOP3 ;DOWN键按下 MOV DPTR,#BJ3 CALL RUN_BJ ;显示反转标记 CALL REV MOV DPTR,#BJ1 ;显示停止标记 CALL RUN_BJ LOOP3: JMP LOOP1 ;--------------------------------------------------------- ; LCD 初始化设置 ;--------------------------------------------------------- SET_LCD: CLR LCD_EN CALL INIT_LCD ;初始化 LCD CALL DELAY1 MOV DPTR,#INFO1 ;指针指到显示信息1 MOV A,#1 ;显示在第一行 CALL LCD_SHOW MOV DPTR,#INFO2 ;指针指到显示信息2 MOV A,#2 ;显示在第二行 CALL LCD_SHOW RET INFO1: DB " REMOTE CONTROL ",0 ;LCD 第一行显示信息 INFO2: DB " IR: --H ",0 ;LCD 第二行显示信息 ;--------------------------------------------------------- ;LCD 初始化 ;--------------------------------------------------------- INIT_LCD: MOV A,#38H ;双列显示,字形5*7点阵 CALL WCOM CALL DELAY1 MOV A,#38H ;双列显示,字形5*7点阵 CALL WCOM CALL DELAY1 MOV A,#38H ;双列显示,字形5*7点阵 CALL WCOM CALL DELAY1 MOV A,#0CH ;开显示,关光标, CALL WCOM CALL DELAY1 MOV A,#01H ;清除 LCD 显示屏 CALL WCOM CALL DELAY1 RET ;--------------------------------------------------------- ;LCD显示信息字符 ;--------------------------------------------------------- LCD_SHOW:
CJNE A,#1,LINE2 ;判断是否为第一行 LINE1: MOV A,#80H ;设置 LCD 的第一行地址 CALL WCOM ;写入命令 CALL CLR_LINE ;清除该行字符数据 MOV A,#80H ;设置 LCD 的第一行地址 CALL WCOM ;写入命令 JMP FILL
LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址 CALL WCOM ;写入命令 CALL CLR_LINE ;清除该行字符数据 MOV A,#0C0H ;设置 LCD 的第二行地址 CALL WCOM FILL: CLR A ;填入字符 MOVC A,@A+DPTR ;由消息区取出字符 CJNE A,#0,LC1 ;判断是否为结束码 RET LC1: CALL WDATA ;写入数据 INC DPTR ;指针加1 JMP FILL ;继续填入字符 RET ;--------------------------------------------------------- ;清除一行 LCD 的字符 ;--------------------------------------------------------- CLR_LINE: MOV R0,#24 CL1: MOV A,#' ' CALL WDATA DJNZ R0,CL1 RET ;--------------------------------------------------------- ;标记字符写入子程序 ;--------------------------------------------------------- RUN_BJ: MOV A,#0CAH ;指定写入地址 CALL WCOM MOV R1,#0 MOV R0,#4 ;写4个标记字符 RUN_BJ1: MOV A,R1 MOVC A,@A+DPTR ;读出要写的标记字符 CALL WDATA ;写入标记字符 INC R1 DJNZ R0,RUN_BJ1 ;没有写完,继续 RET BJ1: DB "STOP" ;停止标记 BJ2: DB ">>>>" ;正转标记 BJ3: DB "<<<<" ;反转标记 ;----------------------------------------------------- ; 写指令子程序 ;RS=L,RW=L,D0-D7=指令码,E=高脉冲 ;----------------------------------------------------- WCOM: MOV P0,A CLR LCD_RS CLR LCD_RW SETB LCD_EN CALL DELAY0 CLR LCD_EN RET ;--------------------------------------------------------- ;写数据子程序 ;RS=H,RW=L,D0-D7=数据,E=高脉冲 ;--------------------------------------------------------- WDATA: MOV P0,A SETB LCD_RS CLR LCD_RW SETB LCD_EN CALL DELAY0 CLR LCD_EN RET
DELAY0: MOV R7,#250 ;延时500微秒 DJNZ R7,$ RET ;--------------------------------------------------------- ;在 LCD 第二行显示字符 ;A=ASC DATA, B=LINE X POS ;--------------------------------------------------------- LCDP2: ;在LCD的第二行显示字符 PUSH ACC ; MOV A,B ;设置显示地址 ADD A,#0C0H ;设置LCD的第二行地址 CALL WCOM ;写入命令 POP ACC ;由堆栈取出A CALL WDATA ;写入数据 RET ;--------------------------------------------------------- ; IR 译码子程序 ; R0---存放IR数据 ; R2---高电平宽度的计数值 ; R3--- 一字节需接收8位计数 ;--------------------------------------------------------- IR_IN: CLR EA ;暂时关闭CPU的所有中断请求 PUSH ACC PUSH PSW SETB PSW.3 ;选择工作寄存器组1 CLR PSW.4 MOV R0,#IRCOM MOV R4,#30 IR_IN1: CALL DEL ;延时4ms,去干扰再确认IR信号是否出现 DJNZ R4,IR_IN1 JB IRIN,IR_END ;如果IRIN=1没有IR信号出现,则退出 WAIT_H: JB IRIN,WAIT_H1 ;等IR变为高电平避开9ms低电平引导脉冲 CALL DEL JMP WAIT_H WAIT_H1: MOV R3,#0 ;8位数清为0 WAIT_L: JNB IRIN,WAIT_H2 ;等 IR 变为低电平 CALL DEL JMP WAIT_L WAIT_H2: JB IRIN,IR_COUN ;等 IR 变为高电平 CALL DEL JMP WAIT_H2 IR_COUN: MOV R2,#0 ;对高电平进行0.14ms计数 IR_COUN1: CALL DEL JB IRIN, IR_COUN2 ;等 IR 变为高电平 ;IR=0,检查R2中的计数值 MOV A,#8 CLR C ;清借位标志 SUBB A,R2 ;判断高低位 ;若C=0,则解码为“0" ;若C=1,则解码为“1" MOV A,@R0 ;取出原先的数据 RRC A ;将借位标志C移入A MOV @R0,A ;处理完一位,将数据写入 INC R3 ;接收字节计数加1 CJNE R3,#8,WAIT_L ;需处理完8位 MOV R3,#0 INC R0 ;存放IR数据值加1 CJNE R0,#IRCOM+4,WAIT_L ;收集到4字节了 JMP IR_SHOW IR_COUN2: INC R2 CJNE R2,#20,IR_COUN1 ;0.14ms计数过长,则自动离开 IR_END: POP PSW POP ACC SETB EA RETI ;--------------------------------------------------------- IR_SHOW: MOV A,IRCOM+2 CJNE A,#10H,IR_SHOW1 ;是否为遥控的K1键 SETB STOP_BJ IR_SHOW1: CPL A ;将22H取反后和23H比较 CJNE A,IRCOM+3,IR_SHOW2 ;如果不等表示接收数据发生错误,放弃。 CALL CONV CALL BEEP_BL ;蜂鸣器鸣响表示解码成功 IR_SHOW2: JMP IR_END ;--------------------------------------------------------- ;转换为 ASCII 码并显示 ;--------------------------------------------------------- CONV: MOV LCD_X,#5 ;设置显示起始位置 MOV A,IRCOM+2 ANL A,#0F0H ;取出高四位二进制数 SWAP A ;高四位与低四位互换 PUSH ACC ;压入堆栈 CLR C ;C=0 SUBB A,#0AH ;减10 POP ACC ;弹出堆栈 JC ASCII0 ;该数小于10,转ASCII0 ADD A,#07H ;大于10的数加上37H ASCII0: ADD A,#30H ;小于10的数加上30H MOV B,LCD_X CALL LCDP2 MOV A,IRCOM+2 ANL A,#0FH ;取出低四位二进制数 PUSH ACC CLR C SUBB A,#0AH ;减10 POP ACC JC ASCII1 ;该数小于10,转ASCII0 ADD A,#07H ;大于10的数加上37H ASCII1: ADD A,#30H ;小于10的数加上30H INC LCD_X MOV B,LCD_X CALL LCDP2 RET ;--------------------------------------------------------- ;蜂鸣器响一声子程序 ;--------------------------------------------------------- BEEP_BL: MOV R6,#100 BL1: CALL DEX1 CPL BEEP DJNZ R6,BL1 ; MOV R5,#25 ; CALL DELAY RET DEX1: MOV R7,#180 DEX2: NOP DJNZ R7,DEX2 RET DELAY: ;延时R5×10MS MOV R6,#50 D1: MOV R7,#100 DJNZ R7,$ DJNZ R6,D1 DJNZ R5,DELAY RET ;--------------------------------------------------------- ; 延时0.14ms ; IR解码使用 ;11.0592MHz,1.085us×(64×2)+2=140us ;--------------------------------------------------------- DEL: MOV R7,#64 DJNZ R7,$ RET ;--------------------------------------------------------- ;延时5MS ;LCD1602延时使用 ;--------------------------------------------------------- DELAY1: MOV R6,#25 DL2: MOV R7,#100 DJNZ R7,$ DJNZ R6,DL2 RET ;--------------------------------------------------------- ; 步进电机正转子程序 ;--------------------------------------------------------- FFW: MOV R0,#00H FFW1: JB STOP_BJ,FFW2 ;STOP_BJ=1,步进电机停止 MOV P1,#0F0H MOV A,R0 MOV DPTR,#TABLE_F ;选择工作方式 MOVC A,@A+DPTR MOV P1,A LCALL DELAY2 INC R0 CJNE A,#0FFH,FFW1 JMP FFW FFW2: CLR STOP_BJ MOV P1,#0F0H RET ;--------------------------------------------------------- ; 步进电机反转子程序 ;--------------------------------------------------------- REV: MOV R0,#00H REV1: JB STOP_BJ,REV2 ;STOP_BJ=1,步进电机停止 MOV P1,#0F0H MOV A,R0 MOV DPTR,#TABLE_R ;选择工作方式 MOVC A,@A+DPTR MOV P1,A CALL DELAY2 INC R0 CJNE A,#0FFH,REV1 JMP REV REV2: CLR STOP_BJ MOV P1,#0F0H RET ;--------------------------------------------------------- ;延时子程序 ;可调整步进电机的转速 ;--------------------------------------------------------- DELAY2: MOV R7,#40 DEL1: MOV R6,#248 DJNZ R6,$ DJNZ R7,DEL1 RET ;--------------------------------------------------------- ; 单双八拍工作方式 ;--------------------------------------------------------- TABLE_F: ;正转表 DB 0F1H,0F3H,0F2H,0F6H,0F4H,0FCH,0F8H,0F9H DB 0FFH TABLE_R: ;反转表 DB 0F9H,0F8H,0FCH,0F4H,0F6H,0F2H,0F3H,0F1H DB 0FFH ;--------------------------------------------------------- ; 双四拍工作方式 ;--------------------------------------------------------- TABLE1: DB 0F3H,0F6H,0FcH,0F9H ;正转表 DB 0FFH ;正转结束 TABLE2: DB 0F9H,0FCH,0F6H,0F3H ;反转表 DB 0FFH ;反转结束 ;------------------------------------------------------- END
|