📄 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 + -