找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5296|回复: 7
收起左侧

51掉电模式下,红外头,INT1外部中断唤醒,需要遥控器按2次的问题。

[复制链接]
ID:70095 发表于 2014-12-7 17:08 | 显示全部楼层 |阅读模式
单片机用的是STC12C5A60S2,晶振11.0592MHz。

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

----
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[ i] = 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++;
    }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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