找回密码
 立即注册

QQ登录

只需一步,快速开始

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

如何给单片机遥控器加掉电唤醒模式?汇编语言

[复制链接]
跳转到指定楼层
楼主
遥控器是控制灯的   15f104w单片机芯片
程序是通过反编译改过来的     怎么加入掉电唤醒模式   我试了很多次都没成功
程序里有一段不加入(如图) 遥控成功率就降低很多是什么原因


;    LED灯遥控程序
;   
;          15F104W  12C5A60S2                 11.0592M
;==========================================================================
;标号==============指令================================地址===机器码=======
;==========================================================================
                                   count_1      EQU 08H;  
                                   count_2      EQU 09H;

                               set_count_1  EQU 0CH;
                                   set_count_2  EQU 0DH;
                                   irdata                EQU 0EH;         
                                   ircode            EQU 0FH;
                                   
                                   keyflag EQU 20H.0;  按键标志位         按下=1
                               irflag  EQU 20H.1;  红外发射标志         发射=1        

                                   KA   EQU  P3.0;           开关
                               KB   EQU  P3.1;           变光
                               KC   EQU  P3.2;           亮度加
                               KD   EQU  P3.3;           亮度减
                                   IR   EQU  P3.4;           输出
                                   LED  EQU  P3.5;           指示灯

                                   SETB KA;           
                                   SETB KB;           
                                   SETB KC;           
                                   SETB KD;           
                                   
                   ORG 0000H
                   LJMP     main;   ;开始时跳转转到初始化程序中   
;==========================================================================
                   ORG 000BH  
                   LJMP     timer0;
;==========================================================================
main:                           MOV      SP,#0x20;
                   LCALL    timer0_init;          //定时0初始化                 
                   MOV   count_1,#00H    //中断计数先清0     
                   MOV   count_2,#00H                     
                   CLR   irflag   //红外发射标志先置0  
;==========================================================================
C01C4:            LCALL    keyscan;  //键值扫描  
                                  JNB      keyflag,C01C4         //若有按键按下
                                  CLR LED;  
                                  LCALL DELAY20MS;
                                  LCALL DELAY20MS;
                                  LCALL    ir_send;  //发送红外编码
                                  JNB KA,$;
                                  JNB KB,$;
                                  LCALL DELAY20MS;
                                  JNB KA,$;
                                  JNB KB,$;
                                CLR      keyflag; //按键标志清零
                                  SETB LED;
                                  SJMP     C01C4                                                   
//---------------------------------------------------------------------------
//void keyscan() // 按键扫描  
keyscan:
                     LCALL DELAY20MS;
                                         JB       ka,C01EE;                //A键按下                                    
                                      MOV      irdata,#0x01;
                                         SETB     keyflag;
                                         RET;         

C01EE:               JB       kb,C01F6;                //B键按下                                       
                                      MOV      irdata,#0x06;
                                         SETB     keyflag;
                                         RET;

C01F6:               JB       kc,C01FE;                //C键按下
                                      MOV      irdata,#0x12;
                                      SETB     keyflag;
                                         RET

C01FE:               JB       kd,C0206;                //D键按下
                                      MOV      irdata,#0x1E;
                                      SETB     keyflag;
C0206:               RET   
;==========================================================================
//发送红外数据  void ir_send()
ir_send:           MOV   set_count_1,#02H; //发送编码中的引导码(9ms高电平+4.5ms低电平)  
                   MOV   set_count_2,#9EH;                  
                   SETB  irflag  ////红外发射标志      
                                   LCALL TX_TIME;   //定时器发送
                                                
                   MOV   set_count_1,#01H; //发送编码中的4.5ms低电平
                   MOV   set_count_2,#50H;                 
                   CLR   irflag      //红外发射标志   低电平则不发射   
                                   LCALL TX_TIME;    //定时器发送  
                                                
                   MOV   ircode,#80H;   //发送16位用户码的前1-8位   
                   LCALL ir_sendbyte    //红外发送一个字节数据
                                                
                   MOV   ircode,#7FH;   //发送16位用户码的前9-16位
                   LCALL ir_sendbyte    //红外发送一个字节数据  
                                                
                   MOV   ircode,irdata; //发送8位数据码     
                   LCALL ir_sendbyte    //红外发送一个字节数据
                                                
                   MOV   A,irdata;
                   CPL   A ;              取反                  
                   MOV   ircode,A       //发送8位数据反码      
                   LCALL ir_sendbyte    //红外发送一个字节数据  

                   MOV   set_count_1,#00H; //发送编码中的0.56ms高电平
                   MOV   set_count_2,#23H;               
                   SETB  irflag        //红外发射标志
                                   LCALL TX_TIME;   //定时器发送   

;                                   SETB  IR    ;//发射完了关闭红外发射二极管  
;                       RET;
;   不加入下面这部分程序 遥控成功概率变低很多               
                   LCALL DELAY23MS   //延时23ms(编码中的23ms低电平)                  
                   MOV   set_count_1,#02H;  //发送编码中的引导码(9ms高电平+4.5ms低电平)  
                   MOV   set_count_2,#9EH;           
                   SETB  irflag  
                                   LCALL TX_TIME;  //定时器发送                                                           
                   MOV   set_count_1,#01H    //发送编码中的4.5ms低电平  
                   MOV   set_count_2,#50H                  
                   CLR   irflag   
                   LCALL TX_TIME;  //定时器发送   
                   MOV   set_count_1,#00H     //发送编码中的0.56ms高电平   
                   MOV   set_count_2,#23H;                    
                   SETB  irflag  
                   LCALL TX_TIME;  //定时器发送                             
                                   SETB  IR    ;//发射完了关闭红外发射二极管  
                       RET;                                                                                                
;----------------------------------------------------------------------------------
//红外发送一个字节数据
ir_sendbyte:       MOV   R7,#0x00;
Q0223:             MOV   set_count_1,#00H; //发送编码中的0.56ms高电平
                   MOV   set_count_2,#23H;                 
                   SETB  irflag   //红外发射标志  启动红外发射二极管发射   
                                   LCALL TX_TIME;  //定时器发送
                                   MOV   A,ircode        //判断红外编码最低位,若为1则1.69ms的低电平
                   JNB   ACC.0,Q024C               
                   MOV   set_count_1,#00H;    //为0则0.565ms的低电平  
                   MOV   set_count_2,#82H;                  
                   SJMP  Q0252                        
Q024C:             MOV   set_count_1,#00H;                    
                   MOV   set_count_2,#0x2B;               
Q0252:             CLR   irflag    //红外发射标志    低电平则不发射   
                            LCALL TX_TIME;   //定时器发送
                                   MOV   A,ircode        //判断红外编码最低位,若为1则1.69ms的低电平  
                   CLR   C                       
                   RRC   A       //将数据右移,即从低位到高位发送           
                   MOV   ircode ,A                     
                   INC   R7                          
                   CJNE  R7,#0x08,Q0223              
                   RET  
;------------------------------------------------------------------------------------------------                                                               
//定时器发送                                            
TX_TIME:           MOV   count_1,#00H;  //中断计数先清0               
                   MOV   count_2,#00H;                  
                   SETB  TR0          //开启定时器0            
Q0232:             CLR   C            //等待发送完            
                   MOV   A,count_2;
                   SUBB  A,set_count_2;
                   MOV   A,count_1;
                   SUBB  A,set_count_1;
        
                   JC    Q0232                     
                   CLR   TR0          //关闭定时器0              
                                   RET;      
;==========================================================================
//定时器0中断  timer0_interrupt  
timer0:                                                                                            
                             PUSH  ACC                          
                   INC   count_2;
                   MOV   A,count_2;
                   JNZ   Q02B3                  
                   INC   count_1;
Q02B3:             JNB   irflag,Q02BA ; //有发射标志,则发射38khz的矩形波         
                   CPL   IR;      
                   SJMP  Q02BC                       
Q02BA:             SETB  IR;//否则不发射,即相当于发射编码中的低电平      
Q02BC:             POP   ACC  

                   RETI   
;==========================================================================
//定时器0初始化
timer0_init:       MOV   TMOD,#02H    //定时0 8位自动重装模式               
                                   MOV   TH0,#0F3H;   //定时13us,38K红外矩形波        
                   MOV   TL0,#0E6H;                  
                                   SETB  EA   
                   SETB  ET0                          ;
               ;    SETB  TR0
                   RET                                                                 
;==========================================================================
//延时  
DELAY20MS:   ;误差 -0.000000000003us                        单片机小精灵生成  11.0592        1T
    MOV R7,#0C1H
DL1:
    MOV R6,#72H
DL0:
    MOV R5,#01H
    DJNZ R5,$
    DJNZ R6,DL0
    DJNZ R7,DL1
    RET

;==========================================================================
DELAY23MS:   ;误差 -0.054253472225us                        单片机小精灵生成  11.0592        1T
    MOV R7,#38H
DL3:
    MOV R6,#0FCH
DL2:
    MOV R5,#03H
    DJNZ R5,$
    DJNZ R6,DL2
    DJNZ R7,DL3
    MOV R5,#01H
    DJNZ R5,$
    RET            
//---------------------------------------------------------------------------
DELAY500MS:   ;误差 -0.000000000063us                        单片机小精灵生成  11.0592        1T
    MOV R7,#5DH
DL5:
    MOV R6,#0B2H
DL4:
    MOV R5,#52H
    DJNZ R5,$
    DJNZ R6,DL4
    DJNZ R7,DL5
    RET              

;==========================================================================

END;




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

使用道具 举报

沙发
ID:624769 发表于 2021-9-11 15:54 | 只看该作者
粗看了一遍你的代码,

C01C4:            LCALL    keyscan;  //键值扫描  
                                  JNB      keyflag,C01C4         //若有按键按下
                                  CLR LED;  
                                  LCALL DELAY20MS;
                                  LCALL DELAY20MS;
                                  LCALL    ir_send;  //发送红外编码
                                  JNB KA,$;
                                  JNB KB,$;
                                  LCALL DELAY20MS;
                                  JNB KA,$;
                                  JNB KB,$;
                                CLR      keyflag; //按键标志清零
                                  SETB LED;
                                  SJMP     C01C4      

这里构成了死循环, 单片机会一直周而复始复始的反复执行这段代码. 你LCALL出去的分支,也都有RET回来。也没有找到 类似 MOV  PCON,#02H 这类关机指令; 那么,你为什么需要掉电唤醒呢? 不存在掉电,何来唤醒?
回复

使用道具 举报

板凳
ID:261025 发表于 2021-9-11 17:11 | 只看该作者
188610329 发表于 2021-9-11 15:54
粗看了一遍你的代码,

C01C4:            LCALL    keyscan;  //键值扫描  

我发的是没加掉电唤醒的源程序    我试着加掉电唤醒只是led亮了 看电流没有发射就死机了  不知道应该怎么加
回复

使用道具 举报

地板
ID:624769 发表于 2021-9-11 17:55 | 只看该作者
418854190 发表于 2021-9-11 17:11
我发的是没加掉电唤醒的源程序    我试着加掉电唤醒只是led亮了 看电流没有发射就死机了  不知道应该怎么 ...

不是…… 掉电唤醒的定义,你理解么?
你先让单片机关机(自主掉电 PowerDown),然后通过中断触发,单片机又开机,这个过程叫掉电唤醒。掉电唤醒一般是没有程序的,只要开了外部中断,当你执行了ShutDown指令之后,就能通过外部中断唤醒,换句话说,大多的掉电唤醒,都是只有看到关机指令通常是: MOV PCON,#02H , 而没有唤醒指令的,所以,你说你加掉电唤醒“源程序”,啥程序?
回复

使用道具 举报

5#
ID:401564 发表于 2021-9-11 19:04 | 只看该作者
用什么"单片机小精灵"呀,STC下载器那有,官方的它不行吗?
MOV PCON,#02H就是掉电了
想要唤醒是要开启中断的,你想要哪个唤醒就开启哪个中断
比如,你要外部中断INT0唤醒,
那就:
CLR EI0;这个要先清除
SETB EX0;
SETB  EA;
然后,当外部中断触发之后,就会进入中断程序
还有,ORG 0000H前面不要有指令,main标号前面也要有一个ORG 100H,要跳过中断向量区的
你这程序太乱了...............你应该用C,没事别乱玩汇编
回复

使用道具 举报

6#
ID:261025 发表于 2021-9-11 20:12 | 只看该作者
Y_G_G 发表于 2021-9-11 19:04
用什么"单片机小精灵"呀,STC下载器那有,官方的它不行吗?
MOV PCON,#02H就是掉电了
想要唤醒是要开启中断 ...

不习惯用官方的计算器  
加了ORG 100H掉电唤醒正常了之前没加 唤醒后就死机了
现在INT0 INT1 INT2 INT3 INT4都可以唤醒了
没专门学过编程  都是自己没事琢磨玩的 C语言改不明白 一改就错  汇编还能改改编编   
回复

使用道具 举报

7#
ID:401564 发表于 2021-9-11 21:17 | 只看该作者
418854190 发表于 2021-9-11 20:12
不习惯用官方的计算器  
加了ORG 100H掉电唤醒正常了之前没加 唤醒后就死机了
现在INT0 INT1 INT2 INT ...

你要去看一下这个单片机的中断向量最高地址是多少,不跳过的话,程序一执行就进入中断,进入中断之后就乱,后果不可知,ORH 100H是一个大概值,反正空间有的是
用汇编要很了解硬件的,而且代码量是很大的,像你这种直接复制的,估计过一段时间再看,基本就是什么思路都找不着了
回复

使用道具 举报

8#
ID:261025 发表于 2021-9-11 21:59 | 只看该作者
Y_G_G 发表于 2021-9-11 21:17
你要去看一下这个单片机的中断向量最高地址是多少,不跳过的话,程序一执行就进入中断,进入中断之后就乱,后 ...

官方提供的INT4中断入口是ORG   0083H    是不是在主程序前加的比它大就行
回复

使用道具 举报

9#
ID:401564 发表于 2021-9-12 07:11 | 只看该作者
418854190 发表于 2021-9-11 21:59
官方提供的INT4中断入口是ORG   0083H    是不是在主程序前加的比它大就行

对呀,这所谓的"向量地址"就是中断的地址,中断被触发后,程序就会跳转到这个地址,执行完中断之后,由RETI返回之前的代码,但不跳过的话,汇编是一条一条指令执行下来,那就是直接进入中断了,虽然说中断不开启,但执行的结果是"未知"的
回复

使用道具 举报

10#
ID:960619 发表于 2021-9-12 10:57 | 只看该作者
红外遥控唤醒掉电模式,红外接收我接外部中断0脚,进入掉进模式后,唤醒首先是进入外部中断0中断程序关闭该IO口的外部中断,这样该脚就能接收红外解码的功能了,还有将掉电模式标志清0,开机就不会再进入掉电模式。 按关机的话,标志位置1,先打开外部中断0允许中断,再进入掉电模式
回复

使用道具 举报

11#
ID:123289 发表于 2021-9-13 09:20 | 只看该作者
不是软件问题!
1、检测出掉电。(电源输入通道上,设置一个电压检测电路)
2、通知到CPU。(例如,使用INT0)
3、对应中断响应后,退出休眠。(大多是自然,退出)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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