?? dsdsfdsfdsf.c
字號:
//經過調節器試,終于將遙控調節器出來,原來自己犯了一個錯誤,
//那就是經過紅外掃描后,送過來的字碼一直存在緩沖區中,所以當按下一個鍵后
//就一直執行那個增加程序。
//解決方法,用一個標志位,當執行完后,標志位清0,就可以實現,按一次執行一次
//接法P1.0--P1.3接繼電器
//P3。7接蜂鳴器
//P0口為顯示的段碼輸入口
//P2口為位選端
//K1---1開 0---1關,K2--2開,1---2關,K3--3開,2--3關,K4--4開,3---4關
//K5---調用顯示定時間 UP---分調整 +----時調整
//K6----啟動定時 R---關定時
/*
;================================
;DT9122D 遙控器
;****** 紅外遙控器鍵值表 ******
; 10 03 01 06
; 09 1D 1F 0D
; 19 1B 11 15
; 17 12 16 4C
; 40 48 04 00
; 02 05 54 4D
; 0A 1E 0E 1A
; 1C 14 0F 0C
;================================
*/
//蔣龍健,2006.11.24修改
//功能描述:當按下相應的鍵時控制相應的繼電器開斷,可以啟動24小時定時功能,并以
//數碼管動態顯示,倒計時的方式顯示,同時可以關閉定時功能,
//功能的擴展:可以控制每一路的定時間并顯示相應的定時時間,在顯示上不能實現
//讓其一直顯示。在程序上還沒有完全能夠實現隨意的調用。
//假如幾個定時中斷同時使用就有點混亂。
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uchar x); //x*0.14MS
void beep();
sbit IRIN = P3^2; //紅外接收器數據線
sbit BEEP = P3^7; //蜂鳴器驅動線
uchar IRCOM[7];
bit REDIN;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;
sbit P25=P2^5;
sbit P26=P2^6;
sbit P27=P2^7;
#define Hidden 0xff; //消隱字符在字形碼表中的位置
uchar code BitTab[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,};//0111 1111
uchar code DispTab[14]={
0x3F,/*0*/
0x06,/*1*/
0x5B,/*2*/
0x4F,/*3*/
0x66,/*4*/
0x6D,/*5*/
0x7D,/*6*/
0x07,/*7*/
0x7F,/*8*/
0x6F,/*9*/
0x77,/*A*/
0x7C,/*b*/
};// 8, 9, - ,n,f
uchar DispBuf[8]; //8字節的顯示緩沖區
bit Sec; //1s到的標記
bit min;
bit hour; //1分的標記
bit minkey;
bit hourkey;
char SecValue=59; //秒計數值
char minvalue =59; //分計數值
char hourvalue=23;
char setmin;
char sethour;
uchar code TH0Val=0xF6;
uchar code TL0Val=0x3C;//當晶振為11.0592時,定時2.5ms的定時器初值
//經過精確調整,在值為63266時,定時時間為1.00043362s
void Init();
void KeyProc();
//void mDelay(unsigned int Delay) ;
//////////////////////////定時中斷////////////////////
void Timer0() interrupt 1
///////////////////動態數碼管的掃描程序//////////////////
{ uchar tmp;
static uchar dCount; //計數器,顯示程序通過它得知現正顯示哪個數碼管
static uint Count; //秒計數器
const uint CountNum=400; //預置值400*2.5=1000=1s
TH0=TH0Val;
TL0=TL0Val;
tmp=BitTab[dCount]; //根據當前的計數值取位值0111 1111
P2=P2|0xff; //P2與1111 1111B相或,將8位置1
P2=P2&tmp; //P2與取出的位值相與,將某一位清零0111 1111低位
tmp=DispBuf[dCount]; //根據當前的計數值取顯示緩沖待顯示值
tmp=DispTab[tmp]; //取字形碼
P0=tmp; //送出字形碼
dCount++; //計數值加1
if(dCount==8) //如果計數值等于6,則讓其回0
dCount=0;
//以下是秒計數的程序行
Count++; //計數器加1
if(Count>=CountNum) //到達預計數值
{ Count=0; //清零
Sec=1; //置位1s到標志
SecValue--; //秒值加1
if(SecValue<=-1)
{SecValue=59; //秒從0計到59
min=1;
minvalue--;}
if (SecValue>=60)
SecValue=0;
if (minvalue<=-1)
{minvalue=59;
hour=1;
hourvalue--;}
if (minvalue>=60)
minvalue=0;
if (hourvalue<=-1)
hourvalue=23;
if (hourvalue>=24)
hourvalue=0;
}
}
////////////////////////////////////////////////////////////////////
void Init()
{
IE = 0x81; //允許總中斷中斷,使能 INT0 外部中斷1000 0011
TCON = 0x01; //觸發方式為脈沖負邊沿觸發
IRIN=1; //I/O口初始化
TMOD=0x01;//00010001定時器0方式1
TH0=TH0Val;
TL0=TL0Val;
TR0=1; //T0開始運行
}
////////////////////////////////////////////////////////////////////
/////////////////////鍵盤程序///////////////////////////////////////////////////////////////
void KeyProc() //鍵值處理
{
switch (IRCOM[2])
{
case 0x15://開啟定時
{ET0=1;
minvalue=59;
SecValue=59;
hourvalue=23;
DispBuf[7]=hourvalue/10;
DispBuf[6]=hourvalue%10;
DispBuf[5]=10;
DispBuf[4]=minvalue/10;
DispBuf[3]=minvalue%10;
DispBuf[2]=10;
DispBuf[1]=SecValue/10;
DispBuf[0]=SecValue%10;
}
break;
case 0x11://關閉定時
{ P0=0xff;
minvalue=59;
SecValue=59;
hourvalue=23;
ET0=0;}break;
case 0X1d: //分加1
{
DispBuf[3]++;
if(DispBuf[3]>=10) //次高位由0加到5
{
DispBuf[3]=0;
DispBuf[4]++;
if(DispBuf[4]>=6)
DispBuf[4]=0;
}
setmin=DispBuf[4]*10+DispBuf[3];
minvalue=setmin;
} break;
case 0X09: //Stop
{
DispBuf[6]++;
if(DispBuf[6]>=10)
{
DispBuf[7]++;
DispBuf[6]=0;}
sethour=DispBuf[7]*10+DispBuf[6];
hourvalue=sethour;
if(hourvalue>=24)
{DispBuf[7]=0;
DispBuf[6]=0;}
} break;
//控制繼電器開關///////////////////
case 0x10://1開
{
P10=1;
DispBuf[7]=1;
DispBuf[6]=0;
DispBuf[5]=11;
DispBuf[4]=10;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200);
} break;
case 0x40://1關
{
P10=0;
DispBuf[7]=1;
DispBuf[6]=0;
DispBuf[5]=12;
DispBuf[4]=12;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
case 0x03://2開
{P11=1;
DispBuf[7]=2;
DispBuf[6]=0;
DispBuf[5]=11;
DispBuf[4]=10;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
case 0x48://2關
{P11=0;
DispBuf[7]=2;
DispBuf[6]=0;
DispBuf[5]=12;
DispBuf[4]=12;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
case 0x01://3開
{P12=1;
DispBuf[7]=3;
DispBuf[6]=0;
DispBuf[5]=11;
DispBuf[4]=10;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
case 0x04://3關
{P12=0;
DispBuf[7]=3;
DispBuf[6]=0;
DispBuf[5]=12;
DispBuf[4]=12;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
case 0x06://4開
{P13=1;
DispBuf[7]=4;
DispBuf[6]=0;
DispBuf[5]=11;
DispBuf[4]=10;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
case 0x00://4關
{P13=0;
DispBuf[7]=4;
DispBuf[6]=0;
DispBuf[5]=12;
DispBuf[4]=12;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
delay(200) ;
delay(200) ;
delay(200) ;}break;
////////////////////////////////////////
//調用顯示開關////////////////////
case 0x0d:
{
DispBuf[7]=hourvalue/10;
DispBuf[6]=hourvalue%10;
DispBuf[5]=10;
DispBuf[4]=minvalue/10;
DispBuf[3]=minvalue%10;
DispBuf[2]=10;
DispBuf[1]=SecValue/10;
DispBuf[0]=SecValue%10;
}break;
}//end switch
REDIN=0;
} //end keyproce
/*void mDelay(unsigned int Delay)
{ unsigned int i;
for(;Delay>0;Delay--)
{ for(i=0;i<124;i++)
{;}
}
}
*/
////////////////////////////////////////////////////////////////////////////////
void main()
{
Init();
P1=0x00;
DispBuf[7]=hourvalue/10;
DispBuf[6]=hourvalue%10;
DispBuf[5]=10;
DispBuf[4]=minvalue/10;
DispBuf[3]=minvalue%10;
DispBuf[2]=10;
DispBuf[1]=SecValue/10;
DispBuf[0]=SecValue%10;
for(;;)
{
if (REDIN)
{
KeyProc();
}
if(Sec) //1s時間到
{
DispBuf[1]=SecValue/10;
DispBuf[0]=SecValue%10;
Sec=0;
}
if(min)
{
DispBuf[4]=minvalue/10;
DispBuf[3]=minvalue%10;
min=0; //清除1秒到的標志
}
if(hour)
{ DispBuf[7]=hourvalue/10;
DispBuf[6]=hourvalue%10;
hour=0;
}
if (hourvalue==0&&minvalue==0&&SecValue==0)
{P1=0x00;//關閉繼電器
ET0=0;
P0=0xff;
DispBuf[7]=10;
DispBuf[6]=10;
DispBuf[5]=10;
DispBuf[4]=10;
DispBuf[3]=10;
DispBuf[2]=10;
DispBuf[1]=10;
DispBuf[0]=10;
}//關閉所有繼電器
}
}
/////////////////////////////紅外遙控解碼///////////////////////
void IR_IN() interrupt 0 using 0
{
unsigned char j,k,N=0;
EX0 = 0;
delay(15);
if (IRIN==1)
{ EX0 =1;
return;
}
//確認IR 信號出現
while (!IRIN) //irin=0,則!IRIN=1等IR 變為高電平,跳過9ms的前導低電平信號。
{delay(1);
}
for (j=0;j<4;j++) //收集四組數據
{
for (k=0;k<8;k++) //每組數據有8 位,
{
while (IRIN) //等 IR 變為低電平,跳過4.5ms 的前導高電平信號。
{
delay(1);
}
while (!IRIN) //等 IR 變為高電平,開始數據采集
{
delay(1);
}
while (IRIN) //計算IR高電平時長
{
delay(1);
N++;
if (N>=30)
{
EX0=1;
REDIN=0;
return;
} //0.14ms 計數過長自動離開。
} //高電平計數完畢
IRCOM[j]=IRCOM[j] >> 1; //數據最高位補“0”
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //數據最高位補“1”
N=0;
}//end for k
}//end for j
if (IRCOM[2]!=~IRCOM[3])
{ EX0=1;
REDIN=0;
return;
}
REDIN=1;
beep();
EX0 = 1;
}
////////////聲音報警////////////////
void beep()
{
unsigned char i;
for (i=0;i<100;i++)
{
delay(4);
BEEP=!BEEP; //BEEP 取反
}
BEEP=1; //關閉蜂鳴器
}
//////////////////用于遙控延時/////////////////
void delay(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -