标题:
红外控制时钟(遥控器51单片机程序)
[打印本页]
作者:
das
时间:
2015-4-18 03:59
标题:
红外控制时钟(遥控器51单片机程序)
#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#define DataPort P2 //8位数据口(硬件)
#define Busy 0x80
#define LED P0
//#define HLED P3
#define uchar unsigned char
#define uint unsigned int
sbit jia=P1^1;
sbit jian=P1^2;
sbit IR=P3^2;
sbit P1_6=P1^6;
sbit P1_7=P1^7;
sbit jiguang=P1^5;
unsigned char a[4];
unsigned int LowTime,HighTime; //
uchar yaokong;
uchar SecondL = 0; //时间秒低位
uchar SecondH = 0; //时间秒高位
uchar MinuteL =2; //时间分低位
uchar MinuteH =3; //时间分高
uchar hourh=0;
uchar hourl=7;
bit kai=0;
uchar yueh=0,yuel=5;
uchar rih=2,ril=8;
uchar xingqi=3;
unsigned char IRCode[4],num, shu;
//uchar ircount;
//uchar irtime[33];
//uchar irdate[33];
//uchar irnum;
//uchar irflag;
//sbit irflag=P3^2;
// irrecOK;
//uchar ircode[4];
//uchar irvalue;
//uchar dsirOK;
//uchar code16H[8];
//uchar irtranOK;
/*********************************************
引脚位定义
**********************************************/
sbit RS=P3^7; //寄存器选择输入端(硬件)
sbit RW=P3^6; //读写控制输入端(硬件)
sbit E =P3^5; //使能信号输入端(硬件)
/*********************************************
函数名称: delay
函数功能: 简易延时函数,us级延时
函数输入: j-延时时间控制变量
函数输出: 无
**********************************************/
void delay(unsigned int j)
{
for(j;j>0;j--);
}
/*********************************************
函数名称: Delay5Ms
函数功能: 固定延时时间延时函数,延时5ms
函数输入: 无
函数输出: 无
**********************************************/
void DelayA(void)
{
unsigned int TempCyc;
for (TempCyc=0;
TempCyc<3500; TempCyc++); //3.5ms
}
void DelayB(void)
{
unsigned int TempCyc;
for (TempCyc=0; TempCyc<840; TempCyc++); // 0.84ms
}
void Delay5Ms(void)
{
unsigned int TempCyc = 4552;
while(TempCyc--);
}
/*********************************************
函数名称: Lcddelay
函数功能: LCD毫秒级延时函数
函数输入: MS-延时时间为MS*ms
函数输出: 无
**********************************************/
void Lcddelay(uint MS)
{
unsigned char i,j;
while(MS!=0)
{
j = 4;
while(j!=0)
{
i=0xf0;
while(i!=0){i--;}
j--;
}
MS--;
}
}
/*********************************************
函数名称: WaitForEnable
函数功能: 检测lcd状态。注意有的LCD检测忙时会一直处
于忙状态,导致程序不能正常工作,这时可以
讲忙检测屏蔽掉试试。
函数输入: 无
函数输出: 无
**********************************************/
void WaitForEnable(void)
{
DataPort=0xff;
RS=0;
RW=1;
Lcddelay(5);
_nop_();
E=1;
_nop_();
_nop_();
while(DataPort&Busy);
E=0;
}
/*********************************************
函数名称: LcdWriteCommand
函数功能: 向LCD写命令
函数输入: CMD-LCD命令
AttribC-忙检测使能变量
函数输出: 无
**********************************************/
void LcdWriteCommand(unsigned char CMD)
{
RS=0;
RW=0;
_nop_();
DataPort=CMD;
Lcddelay(5);
_nop_();
E=1;
_nop_();
_nop_();
E=0;
}
/*********************************************
函数名称: LocateXY
函数功能: 确定LCD的坐标
函数输入: polx-LCD横坐标
poly-LCD纵坐标
函数输出: 无
**********************************************/
void LocateXY(char polx,char poly)
{
unsigned char temp;
temp=polx&0xf;
poly&=0x01;
if(poly) temp|=0x40;
temp|=0x80;
LcdWriteCommand(temp);
}
/*********************************************
函数名称: LcdWriteData
函数功能: 向LCD写数据
函数输入: DataW-LCD数据
函数输出: 无
**********************************************/
void LcdWriteData(char DataW)
{
RS=1;
RW=0;
_nop_();
DataPort=DataW;
Lcddelay(5);
_nop_();
E=1;
_nop_();
_nop_();
E=0;
}
/*********************************************
函数名称: DispOneChar
函数功能: 在指定位置显示单个字符
函数输入: x-横坐标
y-纵坐标
Wlata-字符数据(单个)
函数输出: 无
**********************************************/
void DispOneChar(unsigned char x,unsigned char y,unsigned char WData)
{
LocateXY(x,y);
LcdWriteData(WData);
}
/*********************************************
函数名称: LcdReset
函数功能: LCD1602初始化
函数输入: 无
函数输出: 无
**********************************************/
void LcdReset(void)
{
LcdWriteCommand(0x38);
Lcddelay(5);
LcdWriteCommand(0x38);
Lcddelay(5);
LcdWriteCommand(0x38);
Lcddelay(5);
LcdWriteCommand(0x38);// 清屏
LcdWriteCommand(0x08);
LcdWriteCommand(0x01);
LcdWriteCommand(0x06);
LcdWriteCommand(0x0c);
}
/*********************************************
函数名称: DisplayListChar
函数功能: 在指定位置显示字符串
函数输入: x-横坐标
y-纵坐标
*Dlata-字符串数据指针
函数输出: 无
**********************************************/
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *SData,unsigned char L)
{
unsigned char i;
for(i=0;i<L;i++)
DispOneChar(X++,Y,SData[i]);
}
void Init_Timer(void)
{
TMOD = 0x11; //设定T1的工作模式为1,设定T0工作模式1
//----装入定时器初值 -----//
TH0 = 0x95; //100us定时
TL0 = 0x95;
TH1 = (65536-50000)/256; //50ms定时
TL1 = (65536-50000)%256;
IT0 = 1;
IP = 0x03;
EA = 1; // 开总中断
ET0 = 1; // 定时器0允许中断
ET1 = 1; // 定时器1允许中断
TR1 = 1; // 启动定时器1
TR0 = 1; // 启动定时器0
}
void Timer1_ISR() interrupt 3
{
uint cnt;
TH1 = (65536-50000)/256;
TL1 = (65536-50000)%256;
cnt++;
if(cnt >=20)
{
cnt = 0;
++SecondL;
if(SecondL == 10)
{
SecondL = 0;
++SecondH;
if(SecondH == 6)
{
SecondH = 0;
++MinuteL;
if(MinuteL == 10)
{
MinuteL = 0;
++MinuteH;
if(MinuteH==6)
{MinuteH=0;
++hourl;
if(hourl==10)
{ hourl=0;
++hourh;
if((hourh==2)&(hourl=4))
{hourh=0;hourl=0;
++ril;++xingqi;if(xingqi==8) xingqi=1;
if(ril==10)
{ril=0;++rih;
if((rih==3)&ril==1)
{
rih=1;ril=1;
++yuel;if(yuel==10)
{yuel=0;++yueh;
if((yueh==1)&(yuel==3)){ yuel=1;yueh=1; }
}
}
}
}
}
}
}
}
}
}
}
/*void ComOutChar(unsigned char OutData)
{
SBUF = OutData; //输出字符
while(!TI); //空语句判断字符是否发完
TI = 0; //清TI
}
void INT0Fun(void) interrupt 0 using 2
{
//unsigned char IRCode[2], IROK;
unsigned int TempCyc, TempCycA; EX0 = 0; //外部中断0关闭
IROK = 0;
DelayA(); //延时等待引导码的前半部结束
DelayA();
if (!P3_2) //检验前半部是否过早结束,防干扰
{
{
DelayA();
if (P3_2) //检验前半部是否过早结束,防干扰 ,检验是否是正确的输入信号
{
for (TempCyc=0; TempCyc<3500; TempCyc++)
if (!P3_2) break; //等待第一个位,
if (TempCyc<3500) //超时检验
for (TempCycA=0; TempCycA<4; TempCycA++)
{
for (TempCyc=0; TempCyc<8; TempCyc++)
{
while(!P3_2); //等待P3_2拉高,开始位的下部分
DelayB(); //这里没设超时,实际应用在多功能的设计时应设超时
IRCode[TempCycA] = IRCode[TempCycA]>>1;
if (P3_2) //当延时750us后P3_2仍为高则当前位为1
{
IRCode[TempCycA] = IRCode[TempCycA] | 0x80;
// for (TempCycB=0; TempCycB<840; TempCycB++)
// if (!P3_2) break; //等待下个位 当位1时高电平为1.5ms,
// if (TempCycB>840) //之前已延时了750us, 所以超时应大于1.5ms-750us
//; // goto endchk; //这里最大为1ms
}
else IRCode[TempCycA] = IRCode[TempCycA]&0x00;
}
}
// else // goto endchk;
}
// else // goto endchk;
// IROK++; //当自定码和数据码都完成时为2
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
if(IRCode[2]=IRCode[3])
DispOneChar(0,1,IRCode[2]+0x30);
}
} */
/*endchk: if (IROK==2)
{
ComOutChar(IRCode[0]);
ComOutChar(IRCode[1]); //连接PC串口查看自定义码和数据码
if (IRCode[1]==0x10) //1号键 //只演示点亮2只LED,读者可以自行扩展控制别的器件
P1_7 = ~P1_7; if (IRCode[1]==0x11) //2号键
P1_6 = ~P1_6; for (TempCyc=0; TempCyc<300; TempCyc++)
DelayA(); //延时
}
EX0 = 1;
} */
void busy()
{
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
DisplayListChar(0,0,"STC89c52Rc",10);
DisplayListChar(0,1,"hongwai yaokong",15);
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
}
void hled()
{char i, j;
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
DisplayListChar(0,0,"JIGUANFDENG$laba",16);
DisplayListChar(0,1,"note:p1.5kou",12);
for(j=30;j>0;j--)
for(i=30;i>0;i--)
{jiguang=0;
delay(500);
jiguang=1;
delay(500); }
}
void led()
{char i,j;
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
DisplayListChar(0,0,"liushuideng mode ",16);
DisplayListChar(0,1,"da dang jia zuo",15);
for(j=30;j>0;j--)
for(i=0;i<8;i++)
{LED=~(1<<i);
delay(500); }
}
void time()
{ uchar i; ET1=1;TR1=1;
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
DisplayListChar(0,0,"Time",4);
DispOneChar(9,0,':');
DispOneChar(6,0,':');
DispOneChar(4,0,hourh+0x30); //显示时间”分“的十位
DispOneChar(5,0,hourl+0x30); //显示时间”分“的个
DispOneChar(7,0,MinuteH+0x30); //显示时间”分“的十位
DispOneChar(8,0,MinuteL+0x30);
DisplayListChar(0,1,"2014",4);
DispOneChar(5,1,yueh+0x30); //显示时间”分“的十位
DispOneChar(6,1,yuel+0x30); //显示时间”分“的个
DispOneChar(7,1,'-');
DispOneChar(8,1,rih+0x30); //显示时间”分“的十位
DispOneChar(9,1,ril+0x30); //显示时间”分“的个位
DispOneChar(11,1,xingqi+0x30); //显示时间”秒“的十位
for(i=255;i>0;i--)
{
DispOneChar(8,0,MinuteL+0x30); //显示时间”分“的个位
DispOneChar(10,0,SecondH+0x30); //显示时间”秒“的十位
DispOneChar(11,0,SecondL+0x30); //显示时间”秒“的个位
}
// DispOneChar(12,1,SecondL+0x30); //显示
// delay(1000);
}
bit DeCode(void)
{
unsigned char i,j;
unsigned char temp;
LcdWriteCommand(0x01);
LcdWriteCommand(0x0c);
DisplayListChar(0,0,"start",4);
DispOneChar(4,0,':');
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
temp=temp>>1;
TH0=0;
TL0=0;
TR0=1;
while(IR==0);
TR0=0;
LowTime=TH0*256+TL0;
TH0=0;
TL0=0;
TR0=1;
while(IR==1);
TR0=0;
HighTime=TH0*256+TL0;
if((LowTime<370)||(LowTime>640))
return 0;
if((HighTime>420)&&(HighTime<620))
temp=temp&0x7f;
if((HighTime>1300)&&(HighTime<1800))
temp=temp|0x80;
}
a[i]=temp; }
if(a[2]=~a[3])return 1;
}
void codedisplay()
{uchar i;
i=0;
while(a[i]!="\0")
{ i++;
}
}
void yaokong1()
{
LcdWriteCommand(0x0c);
DisplayListChar(0,0,"enter the label",15);
EA=1;
ET1=0;
TR1=0;
ET0=1;
DispOneChar(0,1,a[0]/100+0x30);
DispOneChar(1,1,a[0]%100/10+0x30);
DispOneChar(2,1,a[0]%10+0x30);
while(1);
}
void key()
{uchar k;
P1=0xff;
k=P1;
if(k==0xff)
return;
Lcddelay(20);
if(k==0xff)
return;
while(P1!=0xff)
switch(k)
{case 0xf3:LcdWriteCommand(0x01); break;
case 0xFF:LcdWriteCommand(0x0c);DisplayListChar(0,0,"open the 1602",13); break;
case 0xfd:busy();yaokong1();break;
case 0xfb: hled(); break;
case 0xf7:time(); break;
case 0xef:led(); break;
}
}
void main(void)
{
shu=0;
LcdReset(); //液晶初始化
Init_Timer(); //Timer0、Timer1初始化
DisplayListChar(0,0,"name:da dang jia",16);
DisplayListChar(0,1,"note:20121003920",16);
yaokong=1; kai=0;
while(1)
{
key();
}
}
void Int0(void) interrupt 0
{EX0=0;
TH0=0;
TL0=0;
TR0=1;
while(IR==0);
TR0=0;
LowTime=TH0*256+TL0;
TH0=0;
TL0=0;
TR0=1;
while(IR==1);
TR0=0;
HighTime=TH0*256+TL0;
if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))
{
if(DeCode()==1)
{
codedisplay();}}
EX0=1;
}
复制代码
作者:
GUOPK
时间:
2015-4-18 05:21
不知是解码什么型号的遥控,电路图????
作者:
bhjyqjs
时间:
2015-6-2 09:02
支持楼主的分享精神
作者:
bhjyqjs
时间:
2015-6-2 09:06
解码思路清晰,程序写的很不错
作者:
默开
时间:
2015-11-28 20:55
木有电路图,,,,,看程序表示理解起来不容易
作者:
铃恋仙
时间:
2018-10-28 18:54
这个遥控怎么接?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1