微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 掉电模式下,红外头,INT1外部中断唤醒,需要遥控器按2次...

掉电模式下,红外头,INT1外部中断唤醒,需要遥控器按2次...

时间:10-02 整理:3721RD 点击:
单片机用的是STC12C5A60S2,晶振11.0592MHz。

进入掉电模式的流程图:


故障表现:进入wile循环后,已经进入掉电模式后,液晶屏会不定时自动的出现输出的字符"D",或1分钟,或5分钟,或10分钟(根据代码会出现字符“D”是表示外部中断唤醒,进入失败?)。红外遥控器按一次只会输出一个“D”,无法完成整个解码过程,连续按2次解码正常。请问这是什么问题(下面有完整的电路图,源代码)?谢谢!


电路图:点击可放大


----
C源代码:
/*STC12C5A60S2 11.0592MHz*/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P3^6; //1602数据/命令
sbit e=P3^7; //1602使能控制
sbit dyled=P0^0; //电源指示灯及用作测试
sbit j=P2^0; //继电器
sbit IR_INPUT = P3^3; //1838红外接收引脚
bit irflag = 0; //红外接收标志,收到一帧正确数据后置1
unsigned char ircode[4]; //红外代码接收
unsigned char disp[11];
unsigned char code Tab[16]="0123456789ABCDEF";
void InitInfrared()
{   
    IR_INPUT = 1;
    TMOD &= 0X0F;
    TMOD |= 0x10;
    TR1 = 0;
    ET1 = 0;
    IT1 = 1;
    EX1 = 1;
}
unsigned int GetHighTime()
{
    TH1 = 0;
    TL1 = 0;
    TR1 = 1;
    while(IR_INPUT)
    {
        if(TH1 > 0x40)
        {
            break;
        }
    }
    TR1 = 0;
    return(TH1 * 256 + TL1);
}
unsigned int GetLowTime()
{
    TH1 = 0;
    TL1 = 0;
    TR1 = 1;
    while(!IR_INPUT)
    {
        if(TH1 > 0x40)
        {
            break;
        }
    }
    TR1 = 0;
    return(TH1 * 256 + TL1);
}
void EXINT1_ISR() interrupt 2 //TNT1中断 红外一体接收头
{
    unsigned char i, j;
    unsigned int time;
    unsigned char byt;
    time = GetLowTime();
    if((time <7833) || (time > 8755))      
    {
        IE1 = 0;
        return;   
    }
    time = GetHighTime();
    if((time<3686) || (time > 4608))
    {
        IE1 = 0;
        return;
    }
    dyled=0; //遥控器按下按键,掉电唤醒后,程序到这里终止(唤醒后的一瞬间无晶起振或是起振不及时导致?)
    for(i=0; i<4; i++)
    {
        for(j=0; j<8; j++)
        {
            time = GetLowTime();
            if((time<313) ||(time >718))
            {
                IE1 = 0;
                return;
            }
            time = GetHighTime();
            if((time>313) && (time <718))
            {
                byt >>= 1;   
            }
            else if((time>1345) && (time<1751))
            {
                byt >>= 1;
                byt |= 0x80;
            }
            else
            {
                IE1 = 0;
                return;
            }
        }
        ircode = byt;
    }
    irflag = 1;
    IE1 = 0;
}
void delay_50us(uint t) //延时
{
    uint j;
    for(;t>0;t--)
    for(j=6245;j>0;j--);
}
void write_com(uchar com) //液晶屏写指令
{
    e=0;
    rs=0;
    P1=com;
    delay_50us(10);
    e=1;
    delay_50us(20);
    e=0;   
}
void write_data(uchar dat) //液晶屏写数据
{
    e=0;
    rs=1;
    P1=dat;
    delay_50us(10);
    e=1;
    delay_50us(20);
    e=0;   
}
void init() //液晶屏初始化
{
    delay_50us(300);
    write_com(0x38);
    delay_50us(100);
    write_com(0x38);
    delay_50us(100);
    write_com(0x38);
    delay_50us(100);
    write_com(0x38);
    write_com(0x38);
    write_com(0x08);
    write_com(0x01);
    write_com(0x06);
    write_com(0x0c);
}
void main(void)
{
    EA = 1; //开总中断
    InitInfrared(); //初始化红外功能
    init(); //液晶屏初始化
   while (1)
   {
        if (irflag)  //接收到红外数据时刷新显示
        {
            irflag = 0;
               
            write_com(0x01); //清屏
            delay_50us(10);
            write_com(0x80); //定位写出位置
            disp[0]=Tab[ircode[0]/16]; //二进制到十六进制赋值给红外码数组
            disp[1]=Tab[ircode[0]%16];
            disp[2]='-';
            disp[3]=Tab[ircode[1]/16];
            disp[4]=Tab[ircode[1]%16];
            disp[5]='-';
            disp[6]=Tab[ircode[2]/16];
            disp[7]=Tab[ircode[2]%16];
            disp[8]='-';
            disp[9]=Tab[ircode[3]/16];
            disp[10]=Tab[ircode[3]%16];
            
            write_data(disp[0]); //disp红外码数组,输出到1602液晶屏
            delay_50us(5);
            write_data(disp[1]);
            delay_50us(5);
            write_data(disp[2]);
            delay_50us(5);
            write_data(disp[3]);
            delay_50us(5);
            write_data(disp[4]);
            delay_50us(5);
            write_data(disp[5]);
            delay_50us(5);
            write_data(disp[6]);
            delay_50us(5);
            write_data(disp[7]);
            delay_50us(5);
            write_data(disp[8]);
            delay_50us(5);
            write_data(disp[9]);
            delay_50us(5);
            write_data(disp[10]);
            delay_50us(5);
            write_com(0x80+0x40);
            delay_50us(5);
            write_data(disp[4]);
            delay_50us(5);
            if((disp[0] == '4') && (disp[4] == 'C') && (disp[6] == '1') && (disp[7] == '4'))
            {
                dyled=~dyled;
                j=~j; //继电器响应红外按键信号
            }
        }
        dyled=1;
        PCON = 0X02; //掉电模式
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
               
        delay_50us(5);
        write_data(' ');
        delay_50us(5);
        write_data('D'); //已经进入掉电模式后,液晶屏会不定时出现输出的字符"D",或5秒 或7秒 或20秒(进入失败?)
        dyled=1;
        //delay_50us(50);
    }
}
----
STC12C5A60S2官方的掉电模式代码:
#include "reg51.h"
#include "intrins.h"
//External interrupt0 service routine
void exint1() interrupt 2           //(location at 0013H)
{
}
void main()
{
    IT1 = 1;                        //set INT1 int type (1:Falling 0:Low level)
    EX1 = 1;                        //enable INT1 interrupt
    EA = 1;                         //open global interrupt switch
    while (1)
    {
        INT1 = 1;                   //ready read INT1 port
        while (!INT1);              //check INT1
        _nop_();
        _nop_();
        PCON = 0x02;                //MCU power down
        _nop_();
        _nop_();
        P1++;
    }
}

应该是程序问题

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top