單片機用的是STC12C5A60S2,晶振11.0592MHz。
進入掉電模式的流程圖:
捕獲.JPG (21.35 KB, 下載次數: 159)
下載附件
2014-12-7 17:01 上傳
故障表現:進入wile循環后,已經進入掉電模式后,液晶屏會不定時自動的出現輸出的字符"D",或1分鐘,或5分鐘,或10分鐘(根據代碼會出現字符“D”是表示外部中斷喚醒,進入失?)。紅外遙控器按一次只會輸出一個“D”,無法完成整個解碼過程,連續按2次解碼正常。請問這是什么問題(下面有完整的電路圖,源代碼)?謝謝!
IMG_20141207_155431.jpg (139.33 KB, 下載次數: 154)
下載附件
2014-12-7 17:01 上傳
電路圖:點擊可放大
無標題.jpg (235.14 KB, 下載次數: 165)
下載附件
2014-12-7 17:08 上傳
----
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++;
}
}
|