单片机用的是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[ 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++;
}
}
|