找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17954|回复: 53
打印 上一主题 下一主题
收起左侧

学习型红外遥控8路输出端——巧妙利用家里的旧遥控器

  [复制链接]
跳转到指定楼层
楼主
ID:72947 发表于 2015-5-14 00:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 qq704661078 于 2015-12-26 23:09 编辑

       以前在论坛都持观望态度,今天第一次发帖,希望对大家有所帮助!因本人对汇编语言情有独钟,所以本程序用汇编语言编写,经过测试,MP3和电视机的遥控都能学习对键成功,其他遥控因为手头没有,所以不敢保证全部支持!P1口作为输出口,我分别接了8个灯做指示,如果连上8路继电器,就可红外控制8路电器的工作,虽然红外遥控受遥控距离及方向的影响用起来不够顺心,但在房间里是完全够用了的!红外接收头接P3.7脚;8个学习键是利用P3.0和P3.1轮流输出低电平与P3.2/3.3/3.4/3.5形成2*4矩阵键盘。短按按键可分别手动控制输出端;长按某键5秒左右则进入学习模式,相应输出端的指示灯亮起(学习指示灯与输出指示灯复用,其实学习模式应该是闪烁状态,但我没写这方面的程序,有需要的自己加进去!),在5秒内用遥控器对着接收头按一次遥控的一个键(随自己爱好),学习指示灯熄灭,学习成功!如果要删除遥控键,则长按按键至学习模式后不按遥控器,5秒后学习指示灯熄灭,原来学习的遥控键数据被删除,遥控器不能再控制这一路输出,有需要了再重新学习此路!下面晒几张我自制的实验板:           图片压缩了,不然发不上来!!!——板子可插红外接收头、315M无线发射/接收模块!!!
(1)、插红外接收头:


(2)、背面连接线路:


(3)、插315M无线接收模块:


(4)、插315M无线发射模块:





Text1.rar (3.79 KB, 下载次数: 134)
程序更新...:
因之前发布的程序还存在小Bug,正好今天有空,就把最新的程序贴上来吧!此次更新主要解决以下问题:按某个键后5S内再按另外一个键会误判断进入第二个键的学习模式...(在按键扫描部分加了一些处理动作)
好了,不多说,看程序吧:

;;;STC12C2052/STC12C56**学习型红外遥控8路继电器
;;;内部RC振荡器约6MHz;;;
;;;写EEPROM数据不能调公共的"写",所以每1路的学习模式里
;;;都要重复写一堆相同的程序,感觉有点浪费空间了,郁闷ing...
;;;修改日期2015/10/10;;;

;----------------------
       ISP_DATA  EQU 0E2H ;定义EEPROM相关寄存器
       ISP_ADDRH EQU 0E3H ;此类寄存器地址需参考所用单片机的手册来设置
       ISP_ADDRL EQU 0E4H ;STC12C2052和56**系列的地址是E2H~E7H
       ISP_CMD   EQU 0E5H
       ISP_TRIG  EQU 0E6H
       ISP_CONTR EQU 0E7H

;----------------------
       AUXR  EQU 08EH    ;定时器1T/12T时钟模式控制
       IRCOM EQU 20H     ;RAM中接收到的键值起始存放地址(20H-23H)
       Z EQU 00H         ;长按标志位
       X EQU 01H         ;接收完成标志位
       D EQU 02H         ;学习模式标志位
         
       IRIN EQU  P3.7    ;红外接收头
       K1   EQU  P3.2    ;学习键 (P3.0与P3.1轮流输出0)
       K2   EQU  P3.3    ;学习键 (实现2*4矩阵键盘)
       K3   EQU  P3.4    ;学习键
       K4   EQU  P3.5    ;学习键
       LED8 EQU  P1.0    ;OUT8         
       LED7 EQU  P1.1    ;OUT7
       LED6 EQU  P1.2    ;OUT6
       LED5 EQU  P1.3    ;OUT5
       LED4 EQU  P1.4    ;OUT4
       LED3 EQU  P1.5    ;OUT3
       LED2 EQU  P1.6    ;OUT2
       LED1 EQU  P1.7    ;OUT1

;----------------------
       ORG 0000H
       LJMP START        ;跳初始化
       ORG 000BH
       LJMP T0INT        ;T0中断服务子程序入口
       ORG 0030H

;----------------------
START: MOV   SP,#5FH
       MOV   R0,#20H
LP0:   MOV   @R0,#00H    ;20H-43H清零
       INC   R0
       CJNE  R0,#44H,LP0         
       MOV   P3,#0FFH    ;P3口置1
       MOV   AUXR,00H    ;T0/12T时钟模式
       MOV   TMOD,#01H   ;定时器工作模式1(16位)
       SETB  EA          ;开总中断EA
       SETB  ET0         ;开T0中断ET0         
       CLR  Z
       CLR  X
       CLR  D  

;-----------------------
MAIN:                    ;主程序
       ACALL IR_IN      
       ACALL KEYP30      ;矩阵键盘扫描
       ACALL KEYP31      ;矩阵键盘扫描
       AJMP MAIN

;-----------------------
;(红外接收译码)
;-----------------------
IR_IN: JNB  IRIN,I2      ;等待 IR 信号出现,IRIN=0则跳到I2
       AJMP  IEND        ;如果没有接收到红外信号则先跳出

I2:    MOV  R1,#30
I20:   ACALL  DEL
       DJNZ  R1,I20      ;延时去抖动
       JB IRIN,IR_IN     ;确认IR信号,去抖动后IRIN仍为0则往下执行
I21:   JB  IRIN,I3       ;持续4.5mS的低电平,等IRIN为1后跳到I3
       AJMP  I21         ;此处循环等待高电平的到来

I3:    MOV   R0,#IRCOM   
       MOV  R3,#0        ;8位计数器清0
LL:    JNB  IRIN,I4      ;持续4.5mS的高电平,等IRIN为0后跳到I4
       AJMP  LL          ;此处循环等待低电平的到来
;;;;;以上I1-I3程序完成引导码的确认(4.5mS低电平+4.5mS高电平);;;;;

I4:    JB  IRIN,I5       ;持续0.565mS的低电平,等IRIN为1后跳到I5
       AJMP  I4          ;此处循环等待高电平的到来

I5:    MOV  R2,#0        ;高电平到来后开始0.14mS计一次数
L1:    ACALL  DEL
       JB  IRIN, N1      ;IRIN为1则跳N1继续计数

       MOV  A,#8         ;计算高电平长度
       CLR  C            ;减前清进/借位c
       SUBB  A,R2        ;以R2的值判断此位的高/低(R2<8为0;R2>8为1)
                         ;计数值<8则此位为0(即8-R2;c=0)
       MOV  A,@R0
       RRC  A        
       MOV  @R0,A        ;将接收到的一位存入对应的键值缓存区
       INC  R3           ;处理完一位
       CJNE  R3,#8,LL    ;需收集8位  
       MOV  R3,#0        ;收集到1字节
       INC  R0           ;需收集4字节
       CJNE  R0,#24H,LL  ;用户码+用户码+操作码+操作反码

       SETB X            ;接收完成标志位置1
       JB D,IEND         ;如果D=1说明是学习模式跳过键值对比
       AJMP  DK          ;跳到键值对比区         

N1:    INC  R2           ;0.14mS R2加一次
       CJNE  R2,#30,L1   ;0.14ms 计数过长则时间到自动离开
IEND:  RET

;-----------------------
; DELAY_0.14MS(以12M晶振/12T计算)
;-----------------------
DEL:   ;IR解码使用(1+2+128+2+4+4=141uS=0.14mS)
       MOV  R5,#3       ;内部约6M/1T,3次;;;12M/1T,6次
DEL0:  MOV  R6,#2       ;1uS
DEL1:  MOV  R7,#32      ;1uS*2次=2uS
       DJNZ  R7,$       ;32*2uS*2次=128uS
       nop              ;1uS*2次=2uS
       DJNZ  R6,DEL1    ;2uS*2次=4uS  
       DJNZ  R5,DEL0    ;(1T单片机)
       RET              ;2uS+(acall的)2uS=4uS

;-----------------------
DK:    MOV R0,#24H       ;内部键值起始存放地址
       MOV DPTR,#00H     ;第1扇区起始地址
       MOV R1,#4         ;读4个字节
DP1:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP1       ;循环读完4字节

       MOV DPTR,#200H    ;第2扇区起始地址
       MOV R1,#4         ;读4个字节
DP2:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP2       ;循环读完4字节

       MOV DPTR,#400H    ;第3扇区起始地址
       MOV R1,#4         ;读4个字节
DP3:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP3       ;循环读完4字节

       MOV DPTR,#600H    ;第4扇区起始地址
       MOV R1,#4         ;读4个字节
DP4:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP4       ;循环读完4字节

       MOV DPTR,#800H    ;第5扇区起始地址
       MOV R1,#4         ;读4个字节
DP5:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP5       ;循环读完4字节

       MOV DPTR,#0A00H   ;第6扇区起始地址
       MOV R1,#4         ;读4个字节
DP6:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP6       ;循环读完4字节

       MOV DPTR,#0C00H   ;第7扇区起始地址
       MOV R1,#4         ;读4个字节
DP7:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP7       ;循环读完4字节

       MOV DPTR,#0E00H   ;第8扇区起始地址
       MOV R1,#4         ;读4个字节
DP8:   ACALL EEPROMR     ;读一字节
       MOV @R0,A         ;读出的数据存到相应地址
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,DP8       ;循环读完4字节

       MOV A,20H         ;接收到的用户码
       CJNE A,24H,D1     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,25H,D1     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,26H,D1     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,27H,D1     ;与内部存放的对比
       CPL LED1          ;都相同,则取反输出1状态

D1:    MOV A,20H         ;接收到的用户码
       CJNE A,28H,D2     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,29H,D2     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,2AH,D2     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,2BH,D2     ;与内部存放的对比
       CPL LED2          ;都相同,则取反输出2状态

D2:    MOV A,20H         ;接收到的用户码
       CJNE A,2CH,D3     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,2DH,D3     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,2EH,D3     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,2FH,D3     ;与内部存放的对比
       CPL LED3          ;都相同,则取反输出3状态

D3:    MOV A,20H         ;接收到的用户码
       CJNE A,30H,D4     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,31H,D4     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,32H,D4     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,33H,D4     ;与内部存放的对比
       CPL LED4          ;都相同,则取反输出4状态

D4:    MOV A,20H         ;接收到的用户码
       CJNE A,34H,D5     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,35H,D5     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,36H,D5     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,37H,D5     ;与内部存放的对比
       CPL LED5          ;都相同,则取反输出5状态

D5:    MOV A,20H         ;接收到的用户码
       CJNE A,38H,D6     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,39H,D6     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,3AH,D6     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,3BH,D6     ;与内部存放的对比
       CPL LED6          ;都相同,则取反输出6状态

D6:    MOV A,20H         ;接收到的用户码
       CJNE A,3CH,D7     ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,3DH,D7     ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,3EH,D7     ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,3FH,D7     ;与内部存放的对比
       CPL LED7          ;都相同,则取反输出7状态

D7:    MOV A,20H         ;接收到的用户码
       CJNE A,40H,DEND   ;与内部存放的对比
       MOV A,21H         ;接收到的用户反码
       CJNE A,41H,DEND   ;与内部存放的对比
       MOV A,22H         ;接收到的操作码
       CJNE A,42H,DEND   ;与内部存放的对比
       MOV A,23H         ;接收到的操作反码
       CJNE A,43H,DEND   ;与内部存放的对比
       CPL LED8          ;都相同,则取反输出8状态
DEND:  RET

;-----------------------
KEYP30:CLR P3.0          ;P3.0与P3.1轮流输出0,实现矩阵键盘

KEY1:  JB K1,KEY3
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K1,KEY3
       ACALL OPEN_T0     ;打开T0计时判断长按
XH1:   JBC Z,XUEXI1      ;长按跳转到学习1,并清零长按标志
       JNB K1,XH1
       CPL LED1          ;OUT1状态取反
       RET
XUEXI1:                  ;学习1
       MOV DPTR,#00H     ;第1扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#07FH      ;LED1
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ1:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND1       ;5S后没接收到新数据则退出
       JNB X,DZ1         ;接收完成标志为0则循环等待
;写EEPROM数据不能调公共的"写",所以只能每次
;学习模式里都有一堆程序重复写,浪费空间了!!!                                
       MOV DPTR,#00H     ;第1扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP1:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP1       ;循环写完4字节
XEND1: CLR D             ;退出学习模式
       SETB LED1         ;关灯
       RET               ;退出

KEY3:  JB K2,KEY5
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K2,KEY5
       ACALL OPEN_T0     ;打开T0计时判断长按
XH3:   JBC Z,XUEXI3      ;长按跳转到学习3,并清零长按标志
       JNB K2,XH3
       CPL LED3          ;OUT3状态取反
       RET
XUEXI3:                  ;学习3
       MOV DPTR,#400H    ;第3扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0DFH      ;LED3
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ3:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND3       ;5S后没接收到新数据则退出
       JNB X,DZ3         ;接收完成标志为0则循环等待

       MOV DPTR,#400H    ;第3扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP3:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP3       ;循环写完4字节
XEND3: CLR D             ;退出学习模式
       SETB LED3         ;关灯
       RET               ;退出

KEY5:  JB K3,KEY7
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K3,KEY7
       ACALL OPEN_T0     ;打开T0计时判断长按
XH5:   JBC Z,XUEXI5      ;长按跳转到学习5,并清零长按标志
       JNB K3,XH5
       CPL LED5          ;OUT5状态取反
       RET
XUEXI5:                  ;学习5
       MOV DPTR,#800H    ;第5扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0F7H      ;LED5
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ5:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND5       ;5S后没接收到新数据则退出
       JNB X,DZ5         ;接收完成标志为0则循环等待

       MOV DPTR,#800H    ;第5扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP5:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP5       ;循环写完4字节
XEND5: CLR D             ;退出学习模式
       SETB LED5         ;关灯
       RET               ;退出

KEY7:  JB K4,KP30OUT
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K4,KP30OUT
       ACALL OPEN_T0     ;打开T0计时判断长按
XH7:   JBC Z,XUEXI7      ;长按跳转到学习7,并清零长按标志
       JNB K4,XH7
       CPL LED7          ;OUT7状态取反
       RET
XUEXI7:                  ;学习7
       MOV DPTR,#0C00H   ;第7扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0FDH      ;LED7
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ7:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND7       ;5S后没接收到新数据则退出
       JNB X,DZ7         ;接收完成标志为0则循环等待

       MOV DPTR,#0C00H   ;第7扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP7:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP7       ;循环写完4字节
XEND7: CLR D             ;退出学习模式
       SETB LED7         ;关灯
       RET               ;退出

KP30OUT:
       SETB P3.0
       RET

;-----------------------
KEYP31:CLR P3.1          ;P3.0与P3.1轮流输出0,实现矩阵键盘

KEY2:  JB K1,KEY4
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K1,KEY4
       ACALL OPEN_T0     ;打开T0计时判断长按
XH2:   JBC Z,XUEXI2      ;长按跳转到学习2,并清零长按标志
       JNB K1,XH2
       CPL LED2          ;OUT2状态取反
       RET
XUEXI2:                  ;学习2
       MOV DPTR,#200H    ;第2扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0BFH      ;LED2
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ2:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND2       ;5S后没接收到新数据则退出
       JNB X,DZ2         ;接收完成标志为0则循环等待

       MOV DPTR,#200H    ;第2扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP2:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP2       ;循环写完4字节
XEND2: CLR D             ;退出学习模式
       SETB LED2         ;关灯
       RET               ;退出

KEY4:  JB K2,KEY6
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K2,KEY6
       ACALL OPEN_T0     ;打开T0计时判断长按
XH4:   JBC Z,XUEXI4      ;长按跳转到学习4,并清零长按标志
       JNB K2,XH4
       CPL LED4          ;OUT4状态取反
       RET
XUEXI4:                  ;学习4
       MOV DPTR,#600H    ;第4扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0EFH      ;LED4
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ4:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND4       ;5S后没接收到新数据则退出
       JNB X,DZ4         ;接收完成标志为0则循环等待

       MOV DPTR,#600H    ;第4扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP4:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP4       ;循环写完4字节
XEND4: CLR D             ;退出学习模式
       SETB LED4         ;关灯
       RET               ;退出

KEY6:  JB K3,KEY8
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K3,KEY8
       ACALL OPEN_T0     ;打开T0计时判断长按
XH6:   JBC Z,XUEXI6      ;长按跳转到学习6,并清零长按标志
       JNB K3,XH6
       CPL LED6          ;OUT6状态取反
       RET
XUEXI6:                  ;学习6
       MOV DPTR,#0A00H   ;第6扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0FBH      ;LED6
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ6:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND6       ;5S后没接收到新数据则退出
       JNB X,DZ6         ;接收完成标志为0则循环等待

       MOV DPTR,#0A00H   ;第6扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP6:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP6       ;循环写完4字节
XEND6: CLR D             ;退出学习模式
       SETB LED6         ;关灯
       RET               ;退出

KEY8:  JB K4,KP31OUT
       CLR TR0;这两句是为了防止在快速连按按键  (2015/10/10修改)
       MOV 45H,#0;或快速切换按键时,误判断进入学习模式
       ACALL DELAY30MS   ;延时去抖动
       JB K4,KP31OUT
       ACALL OPEN_T0     ;打开T0计时判断长按
XH8:   JBC Z,XUEXI8      ;长按跳转到学习8,并清零长按标志
       JNB K4,XH8
       CPL LED8          ;OUT8状态取反
       RET
XUEXI8:                  ;学习8
       MOV DPTR,#0E00H   ;第8扇区
       ACALL PDSQ        ;读数判断扇区是否为空
       MOV P1,#0FEH      ;LED8
       SETB D            ;学习模式标志位置1
       ACALL OPEN_T0     ;开T0进行等待计时
DZ8:   ACALL IR_IN       ;在5S内循环调用红外接收程序
       JBC z,XEND8       ;5S后没接收到新数据则退出
       JNB X,DZ8         ;接收完成标志为0则循环等待

       MOV DPTR,#0E00H   ;第8扇区起始地址;存入新键值   
       MOV R0,#20H       ;RAM中接收到的键值起始存放地址     
       MOV R1,#4         ;写4个字节
LP8:   MOV A,@R0
       ACALL EEPROMW     ;写一字节
       INC R0            ;内存地址加一
       INC DPTR          ;地址指针加一
       DJNZ R1,LP8       ;循环写完4字节
XEND8: CLR D             ;退出学习模式
       SETB LED8         ;关灯
       RET               ;退出

KP31OUT:
       SETB P3.1
       RET

;-----------------------
DELAY30MS:               ;6M/1T模式延时约30mS
       MOV R7,#6  
DL1:   MOV R6,#100
DL0:   MOV R5,#150
       DJNZ R5,$   
       DJNZ R6,DL0
       DJNZ R7,DL1
       RET

;-----------------------
OPEN_T0:                 ;打开T0计时
       MOV TH0,#3CH      ;定时器0初值
       MOV TL0,#0B0H     ;内部约6MHz(100ms)
       CLR Z             ;清长按标志
       CLR X             ;接收完成标志位清零
       SETB TR0          ;打开T0
       RET

;-----------------------
T0INT:                                  ;T0中断(判断长按)
       MOV TH0,#3CH      ;重装初值
       MOV TL0,#0B0H     ;内部约6MHz(100ms)
       INC 45H                       ;中断计数约100ms一次
       MOV A,45H
       CJNE A,#30,TOUT1  ;100ms*30=3s
       MOV 45H,#0        ;中断计数满30清零
       SETB Z                       ;长按标志位置1
       CLR TR0           ;关闭T0
TOUT1: RETI

;-----------------------
PDSQ:  ACALL EEPROMR     ;读1个字节判断扇区是否为空
       CJNE A,#0FFH,ERASE;扇区不为空则擦除扇区
       RET

;-----------------------
;EEPROM相关操作
;-----------------------
ERASE:;擦除
       MOV ISP_ADDRH,DPH   ;送高地址
       MOV ISP_ADDRL,DPL   ;送低地址
       MOV ISP_CONTR,#83H  ;允许ISP/IAP操作(6~12MHz)
       MOV ISP_CMD,#03H    ;扇区擦除
       ACALL ISPCF         ;触发IAP
       ACALL ISP_DISABLE   ;禁止ISP/IAP操作
       RET
;----------------------
EEPROMW:;写
       MOV ISP_DATA,A      ;ACC里是要写入的数据
       MOV ISP_ADDRH,DPH   ;送高地址
       MOV ISP_ADDRL,DPL   ;送低地址
       MOV ISP_CONTR,#83H  ;允许ISP/IAP操作(6~12MHz)
       MOV ISP_CMD,#02H    ;送写命令
       ACALL ISPCF         ;触发IAP
       ACALL ISP_DISABLE   ;禁止ISP/IAP操作
       RET
;----------------------
EEPROMR: ;读
       MOV ISP_ADDRH,DPH   ;送高地址
       MOV ISP_ADDRL,DPL   ;送低地址
       MOV ISP_CONTR,#83H  ;允许ISP/IAP操作(6~12MHz)
       MOV ISP_CMD,#01H    ;送读命令
       ACALL ISPCF         ;触发IAP
       MOV A,ISP_DATA      ;读出的数据放到ACC
       ACALL ISP_DISABLE   ;禁止ISP/IAP操作
       RET
;----------------------
ISPCF: ;触发ISP/IAP
       MOV ISP_TRIG, #46H  ;以MCU型号来定;STC12C2052(46H/0B9H)
       MOV ISP_TRIG, #0B9H ;11F和15F系列相同(5AH/0A5H)
       NOP
       RET
;----------------------
ISP_DISABLE: ;禁止ISP/IAP操作(出于安全考虑才要)
       MOV ISP_CONTR,#00H
       MOV ISP_CMD,#00H
       MOV ISP_TRIG,#00H
       MOV ISP_ADDRH,#0FFH
       MOV ISP_ADDRL,#0FFH
       RET
;-----------------------
END
新程序的hex代码长度有1089字节,超过1K了,没法用我的那块STC12C1052了,1052才1K字节的ROMo(╯□╰)o......







评分

参与人数 5黑币 +89 收起 理由
qjzyx + 4 赞一个!
51黑ren + 18 很给力!
absflash + 12 焊功不错,漂亮,用汇编写完真是辛苦了,
madell + 5 赞一个!
admin + 50 共享资料的积分奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:1 发表于 2015-5-14 00:35 | 只看该作者
51黑有你更精彩!!
回复

使用道具 举报

板凳
ID:77496 发表于 2015-5-14 00:38 | 只看该作者
收藏了 有机会我也做一个,楼主的图片好像没有上传成功啊 期待中!!!!!!!!
回复

使用道具 举报

地板
ID:72947 发表于 2015-5-14 19:03 | 只看该作者
admin 发表于 2015-5-14 00:35
把楼主的程序贴出来一下 为大家省点黑币:

谢谢坛主了!图片因为之前没压缩,上传失败,现在补上了!

评分

参与人数 1黑币 +35 收起 理由
admin + 35 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

5#
ID:72947 发表于 2015-5-14 19:04 | 只看该作者
liuqin 发表于 2015-5-14 00:38
收藏了 有机会我也做一个,楼主的图片好像没有上传成功啊 期待中!!!!!!!!

图片已补上!谢谢支持!
回复

使用道具 举报

6#
ID:79481 发表于 2015-5-16 00:09 | 只看该作者
一个吊字已不能形容了!
回复

使用道具 举报

7#
ID:63588 发表于 2015-5-23 23:54 | 只看该作者
没有电路图完全没法做
回复

使用道具 举报

8#
ID:77205 发表于 2015-5-24 16:33 | 只看该作者
太好了,可惜没有C程序
回复

使用道具 举报

9#
ID:70614 发表于 2015-5-25 07:19 | 只看该作者
你是个高手。谢谢分享, 向高手学习。
回复

使用道具 举报

10#
ID:72947 发表于 2015-5-25 19:59 | 只看该作者
云不肯说 发表于 2015-5-23 23:54
没有电路图完全没法做

最近挺忙的,没空用软件画了,这是手工画的,希望可以看得懂!“RF”是红外接收头;“P1.0~P1.7”和“地线GND”可以接上排针留出来,方便连接排线到继电器扩展板,这样就可以红外遥控控制8路继电器的通断了!

回复

使用道具 举报

11#
ID:72947 发表于 2015-5-25 20:14 | 只看该作者
lesson18 发表于 2015-5-24 16:33
太好了,可惜没有C程序

学习下汇编也好的,可以多了解一下单片机的内部结构!我是两个都会一点点,但是这个程序我没有用C语言写过,所以暂时无法提供C版本的!有需要的自己翻译一下就好了,而且翻译后你还能顺便学到一点汇编语言!
回复

使用道具 举报

12#
ID:72947 发表于 2015-5-25 20:15 | 只看该作者
星星一眨眼 发表于 2015-5-25 07:19
你是个高手。谢谢分享, 向高手学习。

谢谢支持!我也是在学习路上!
回复

使用道具 举报

13#
ID:79544 发表于 2015-9-18 22:14 | 只看该作者
不懂汇编啊
回复

使用道具 举报

14#
ID:72947 发表于 2015-9-19 08:54 | 只看该作者

嘿嘿,汇编其实也不是很难,但是用起来很繁琐的,我是简单的程序才用汇编写,不然头都要大啊!在这里公布个教程算了 51单片机汇编语言教程.pdf (15.69 MB, 下载次数: 78)
回复

使用道具 举报

15#
ID:79544 发表于 2015-9-19 10:43 | 只看该作者
qq704661078 发表于 2015-9-19 08:54
嘿嘿,汇编其实也不是很难,但是用起来很繁琐的,我是简单的程序才用汇编写,不然头都要大啊!在这里公布 ...

我的编译器编译不了,要什么编译器?
回复

使用道具 举报

16#
ID:72947 发表于 2015-9-19 11:43 | 只看该作者
腾飞的龙 发表于 2015-9-19 10:43
我的编译器编译不了,要什么编译器?

用 Keil uVision2 啊,汇编程序的后缀是( .asm );C语言的后缀是(.c );你用对没有?
回复

使用道具 举报

17#
ID:79544 发表于 2015-9-19 14:37 | 只看该作者
就是.asm。不编译
回复

使用道具 举报

18#
ID:79544 发表于 2015-9-19 14:37 | 只看该作者
要把你程序里的;注释掉是吧
回复

使用道具 举报

19#
ID:79544 发表于 2015-9-19 14:44 | 只看该作者
好啦现在编译通过下进去试试。谢谢分享!
回复

使用道具 举报

20#
ID:72947 发表于 2015-9-19 15:12 | 只看该作者
本帖最后由 qq704661078 于 2015-9-19 15:15 编辑
腾飞的龙 发表于 2015-9-19 14:37
要把你程序里的;注释掉是吧

去掉么?不用啊,“;”号后面就是注释嘛,跟C的“//”一个意思,不知道你怎么会编译不了……有些语句前面“;”注释掉是可以不要那几句,不影响程序功能的!只是为了省ROM
回复

使用道具 举报

21#
ID:72947 发表于 2015-9-19 15:25 | 只看该作者
腾飞的龙 发表于 2015-9-19 14:37
要把你程序里的;注释掉是吧

我之前用STC12C1052单片机,只有1KB(0~1023字节)ROM,如果不把那些能省的省掉,ROM就不够装了,现在这个程序编译出来的代码长度刚好1010字节,只差13个字节就装满了……
如果你有大点容量的单片机,比如STC12C2052/4052/56**系列的都行(其他系列的EEPROM相关寄存器地址不同),也可以把我那些用“;”注释掉的代码用起来的!
回复

使用道具 举报

22#
ID:79544 发表于 2015-9-19 18:13 | 只看该作者
哦谢谢,学习啦,感觉c顺手,第一次接触汇编。
回复

使用道具 举报

23#
ID:79544 发表于 2015-9-26 15:44 | 只看该作者
楼主你好;按你的程序下进单片机怎么没有红外输出啊,看着学习都正常,就是没有红外输出,红外发射管通过pnp三极管控制发射管的正极,发射管的负极接地。P3.7脚通过1k电阻接三极管的基极驱动红外发射管,这样一个对吧。请指教。谢谢!
回复

使用道具 举报

24#
ID:79544 发表于 2015-9-26 16:00 | 只看该作者
qq704661078 发表于 2015-5-14 19:04
图片已补上!谢谢支持!

楼主你好。用遥控器直接遥控板子8个指示灯也不亮。哪里出错啦?再就是你的板子上红外接收头旁边的小LED时红外发射管吗?谢谢
回复

使用道具 举报

25#
ID:79544 发表于 2015-9-26 16:12 | 只看该作者
楼主你好,我用的是STC12C5608AD的单片机,以前没接触汇编,下载了你的汇编教程,改了IO口。指示灯还是P1口,按键改成P2口,接收头改在P3.2,现在控制不了,哪里的问题呀谢谢指教。
回复

使用道具 举报

26#
ID:79544 发表于 2015-9-26 22:01 | 只看该作者
qq704661078 发表于 2015-9-19 08:54
嘿嘿,汇编其实也不是很难,但是用起来很繁琐的,我是简单的程序才用汇编写,不然头都要大啊!在这里公布 ...

谢谢你的汇编教程,很好,又学到新东西啦。呵呵,就是你的这个程序我下进单片机,怎么控制不了
回复

使用道具 举报

27#
ID:72947 发表于 2015-11-17 22:59 | 只看该作者
腾飞的龙 发表于 2015-9-26 16:00
楼主你好。用遥控器直接遥控板子8个指示灯也不亮。哪里出错啦?再就是你的板子上红外接收头旁边的小LED时 ...

晕,我这个程序可不是用来发射的,接收头那个LED也只是普通LED,程序只是接收红外信号解码,然后可以学习8个遥控的键跟板上的8个按键对应,方便用红外遥控和板上的按键都能灵活的控制8路I/O口输出...
回复

使用道具 举报

28#
ID:72947 发表于 2015-11-17 23:02 | 只看该作者
腾飞的龙 发表于 2015-9-26 16:00
楼主你好。用遥控器直接遥控板子8个指示灯也不亮。哪里出错啦?再就是你的板子上红外接收头旁边的小LED时 ...

要学习才可以控制嘛,比如我想用红外遥控器的“1键”控制板上的LED1亮,那我就得长按板上控制LED1的按键进入学习模式,然后遥控对着接收头按“1键”,学习成功了,遥控器的“1键”才可以控制板上的LED1;明白没?
回复

使用道具 举报

29#
ID:72947 发表于 2015-11-17 23:06 | 只看该作者
腾飞的龙 发表于 2015-9-26 15:44
楼主你好;按你的程序下进单片机怎么没有红外输出啊,看着学习都正常,就是没有红外输出,红外发射管通过pn ...

你误解了我的程序功能了,我这个不是用来实现    “复制红外遥控器”   ,所以是没有红外发射功能的!我板上也没有红外发射管,你想要    “复制红外遥控器”   的程序论坛里也有的,搜一下就出来了
回复

使用道具 举报

30#
ID:79544 发表于 2015-11-18 16:50 | 只看该作者
qq704661078 发表于 2015-11-17 23:06
你误解了我的程序功能了,我这个不是用来实现    “复制红外遥控器”   ,所以是没有红外发射功能的!我 ...

谢谢指教,学习啦,
回复

使用道具 举报

31#
ID:95342 发表于 2015-11-19 23:13 | 只看该作者
楼主太感谢了
回复

使用道具 举报

32#
ID:95342 发表于 2015-11-19 23:15 | 只看该作者
希望楼主以后多发点有关无线知识大家一块交流学习学习
回复

使用道具 举报

33#
ID:95342 发表于 2015-11-19 23:20 | 只看该作者
qq704661078 发表于 2015-5-14 19:03
谢谢坛主了!图片因为之前没压缩,上传失败,现在补上了!

大赞一个
回复

使用道具 举报

34#
ID:44267 发表于 2015-11-24 11:45 | 只看该作者
一个吊字已不能形容了!
回复

使用道具 举报

35#
ID:99987 发表于 2015-12-24 11:47 | 只看该作者
汇编的程序不错,现在很少了。非常适合。汇编非常适合,现在很少了,原来基础都是汇编,

非常棒,看程序,硬件就可以搭起来了。感谢

作者很人性化,为了我们节省黑币,程序无私奉献

评分

参与人数 1黑币 +50 收起 理由
admin + 50 赞一个!

查看全部评分

回复

使用道具 举报

36#
ID:99624 发表于 2015-12-26 23:43 | 只看该作者
楼主的程序,注释得这么详细,我一个对汇编不怎么感冒的人都看的懂了三分。赶紧收藏,问一下这个程序能学习空调的编码吗?空调的编码比较长,网上下过好多程序都失败了..
回复

使用道具 举报

37#
ID:72947 发表于 2015-12-27 01:01 | 只看该作者
51黑ren 发表于 2015-12-26 23:43
楼主的程序,注释得这么详细,我一个对汇编不怎么感冒的人都看的懂了三分。赶紧收藏,问一下这个程序能学习 ...

空调遥控的编码好长的,比如格力的一个键的键码长度是9个码也就是72位,修改一下应该可以配对得上,我这个程序是以MP3的遥控编码格式编的,其他遥控没试过...还有一种配对方法是记录高低电平的时长,也是最能适应各种遥控器的,不过现在暂时抽不出时间调试这种方案!
回复

使用道具 举报

38#
ID:72947 发表于 2015-12-27 01:03 | 只看该作者
madell 发表于 2015-12-24 12:05
作者很人性化,为了我们节省黑币,程序无私奉献

程序有更新,感兴趣的话请参考最新程序,之前的有Bug......o(╯□╰)o
回复

使用道具 举报

39#
ID:99987 发表于 2015-12-29 11:20 | 只看该作者
效果不错,谢谢分享
回复

使用道具 举报

40#
ID:101285 发表于 2015-12-30 21:52 | 只看该作者
好棒的功能,学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表