返回主页 单片机教程XL2000开发板 单片机学习 自制编程器 单片机资料 软件下载 电子技术产品介绍如何购买 论坛

;********************************************************************************
;* 日期: 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