这是用1602液晶+1838红外遥控+ds18b20+ds1302做的一个万年历...刚上电的时候液晶显示的时钟正常行走,可是只要红外遥控一按下按键,整个程序就停止了,时间显示就一直定在那里!!!我找了好多天都找不到什么问题!!求大神解答!!!
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P1^0; //位声明
sbit rw=P1^1;
sbit IO=P2^0;
sbit SCLK=P2^1;
sbit DQ=P2^2;
sbit RST=P2^4;
sbit en=P2^5;
sbit dula=P2^6;
sbit wela=P2^7;
sbit IR=P3^2;
//sbit beep=P2^3;
uchar low
time,hightime; //储存低,高电平脉宽
uchar a[4]; //储存用户码,键码
int temper; //储存温度的值
uchar code table1[]="WELCOME!"; //初始显示
uchar code table2[]="Loading...";
uchar code table3[]="20 - - ";
uchar code table4[]=" : : ";
uchar numt;
/************************基本定义*************************/
/**********************延时函数定义***********************/
void delayms(uint xms) //延时若干毫秒
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void delayus(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<1;j++);
}
/****************************end***************************/
/**************************ds1302部分**********************/
void write_byte1302(uchar dat) //写8位的数据
{
uchar i;
SCLK=0;
for(i=0;i<8;i++)
{
IO=dat&0x01;
SCLK=1;
SCLK=0;
dat>>=1;
}
}
void write_1302(uchar cmd,uchar dat) //写入字节数据
{
RST=0;
SCLK=0;
RST=1;
write_byte1302(cmd);
write_byte1302(dat);
SCLK=1;
RST=0;
}
uchar read_byte1302() //读8位数据
{
uchar i,dat;
for(i=0;i<8;i++)
{
dat>>=1;
if(IO==1)
dat|=0x80;
SCLK=1;
SCLK=0;
}
return dat;
}
uchar read_1302(uchar cmd) //读字节数据
{
uchar dat;
RST=0;
SCLK=0;
RST=1;
write_byte1302(cmd);
dat=read_byte1302();
SCLK=1;
RST=0;
return dat;
}
/******************************end******************************/
/**************************ds18b20部分*************************/
uchar reset_18b20() //ds18b20复位
{
uchar num;
DQ=0;
delayus(29);
DQ=1;
delayus(3);
num=DQ;
delayus(25);
return (num);
}
uchar read_bit() //读一位数据
{
uchar i;
DQ=0;
DQ=1;
for(i=0;i>3;i++);
return (DQ);
}
void write_bit(uchar dat) //写一位数据
{
DQ=0;
if(dat==1)
DQ=1;
delayus(5);
DQ=1;
}
uchar read_byte() //读一个字节数据
{
uchar dat=0;
uchar i;
for(i=0;i<8;i++)
{
if(read_bit())
dat|=0x01<<i;
delayus(1);
}
return (dat);
}
void write_byte(uchar dat) //写一个字节数据
{
uchar i,j;
for(i=0;i<8;i++)
{
j=((dat>>i)&0x01);
write_bit(j);
delayus(1);
}
}
int read_temp() //读取温度的值
{
uchar templ,temph;
int temp;
reset_18b20();
write_byte(0xcc);
write_byte(0x44);
delayus(10000);
reset_18b20();
write_byte(0xcc);
write_byte(0xbe);
templ=read_byte();
temph=read_byte();
temp=templ+temph*256;
return (temp);
}
/***************************end***************************/
/*************************红外遥控部分********************/
bit IR_jiema(void) //解四个字节的码并把码分别储存到数组a中
{
uchar i,j;
uchar temp;
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; //0
if((hightime>1300)&&(hightime<1800))
temp=temp|0x80; //1
}
a[i]=temp;
}
if(a[2]=~a[3]) //键码与键的反码校验
return 1;
}
/*************************end****************************/
/*************************1602部分***********************/
void write_com(uchar com)
{
rs=0;
P0=com;
delayms(1);
en=1;
delayms(1);
en=0;
}
void write_date(uchar date)
{
rs=1;
P0=date;
delayms(1);
en=1;
delayms(1);
en=0;
}
void write_temp(uchar add,uchar date)
{
write_com(0x80+0x40+add);
write_date(date);
}
void write_clk(uchar add,uchar date)
{
write_com(0x80+add);
write_date(0x30+date);
}
/****************************end*************************/
/*************************初始化***********************/
void init_1602()
{
uchar num;
rw=0;
en=0;
dula=0;
wela=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
write_com(0x80+4);
for(num=0;num<8;num++)
{
write_date(table1[num]);
delayms(1);
}
delayms(2000);
write_com(0x80+4);
for(num=0;num<10;num++)
{
write_date(table2[num]);
delayms(1);
}
delayms(3000);
write_com(0x01);
}
void init_1302()
{
write_1302(0x8e,0x00);
write_1302(0x90,0xa5);
write_1302(0x80,((55/10)<<4|(55%10)));//秒
write_1302(0x82,((59/10)<<4|(59%10)));//分
write_1302(0x84,((22/10)<<4|(22%10)));//时
write_1302(0x86,((29/10)<<4|(29%10)));//日
write_1302(0x88,((7/10)<<4|(7%10)));//月
write_1302(0x8c,(13/10)<<4|(13%10));//年
write_1302(0x8a,(1/10)<<4|(1%10));//星期
write_1302(0x8e,0x80);
}
void init_1838() //红外遥控初始化
{
EA=1;
EX0=1;
ET0=1;
IT0=1;
TMOD=0x01;
TH0=0;
TL0=0;
TR0=0;
}
/*********************************end******************************/
/******************************显示部分*****************************/
void display_1302_18b20()
{
uint readvalue;
uint sec,sec1,sec2,min,min1,min2,hr,hr1,hr2,date,date1,date2,mon,mon1,mon2,year,year1,year2,day;
readvalue=read_1302(0x81);//读秒
sec=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//转化秒
sec1=sec/10;
sec2=sec%10;
write_clk(0x46,sec1);//写秒
write_clk(0x47,sec2);
readvalue=read_1302(0x83);//读分
min=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//转化分
min1=min/10;
min2=min%10;
write_clk(0x43,min1);//写分
write_clk(0x44,min2);
readvalue=read_1302(0x85);//读时
hr=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//转化时
hr1=hr/10;
hr2=hr%10;
write_clk(0x40,hr1);//写时
write_clk(0x41,hr2);
readvalue=read_1302(0x87);//读日
date=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//转化日
date1=date/10;
date2=date%10;
write_clk(0x09,date1);//写日
write_clk(0x0a,date2);
readvalue=read_1302(0x89);//读月
mon=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//转化月
mon1=mon/10;
mon2=mon%10;
write_clk(0x06,mon1);//写月
write_clk(0x07,mon2);
readvalue=read_1302(0x8d);//读年
year=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//转化年
year1=year/10;
year2=year%10;
write_clk(3,year1);//写年
write_clk(4,year2);
readvalue=read_1302(0x8b); //写星期
day=((readvalue&0x70)>>4)*10+(readvalue&0x0f);
switch (day)
{
case 1:write_com(0x80+0x0c);
write_date('M');
write_com(0x80+0x0d);
write_date('O');
write_com(0x80+0x0e);
write_date('N');
break;
case 2:write_com(0x80+0x0c);
write_date('T');
write_com(0x80+0x0d);
write_date('U');
write_com(0x80+0x0e);
write_date('E');
break;
case 3:write_com(0x80+0x0c);
write_date('W');
write_com(0x80+0x0d);
write_date('E');
write_com(0x80+0x0e);
write_date('D');
break;
case 4:write_com(0x80+0x0c);
write_date('T');
write_com(0x80+0x0d);
write_date('H');
write_com(0x80+0x0e);
write_date('U');
break;
case 5:write_com(0x80+0x0c);
write_date('F');
write_com(0x80+0x0d);
write_date('R');
write_com(0x80+0x0e);
write_date('I');
break;
case 6:write_com(0x80+0x0c);
write_date('S');
write_com(0x80+0x0d);
write_date('A');
write_com(0x80+0x0e);
write_date('T');
break;
case 7:write_com(0x80+0x0c);
write_date('S');
write_com(0x80+0x0d);
write_date('U');
write_com(0x80+0x0e);
write_date('N');
break;
}
temper=read_temp(); //显示温度
if(temper<0)
{
write_temp(0x0b,'-');
temper=0-temper;
}
else
write_temp(0x0b,'+');
write_temp(0x0c,0x30+(temper>>4)%100/10); //温度十位
write_temp(0x0d,0x30+(temper>>4)%10); //温度个位
write_temp(0x0e,'.');
write_temp(0x0f,0x30+((temper&0x000f)*62.5)/100); //温度小数点后一位
}
void display_1838() //红外解码显示
{
//uchar num;
if(a[2]==0x44)
{
write_com(0x80);
write_date(0x0f);
}
}
/******************************end*************************/
/****************************主函数**************************/
void main()
{
uchar num;
init_1602();
init_1838();
write_com(0x80+1);
for(num=0;num<10;num++)
{
write_date(table3[num]);
delayms(1);
}
write_com(0x80+0x40);
for(num=0;num<8;num++)
{
write_date(table4[num]);
delayms(1);
}
init_1302();
while(1)
{
display_1302_18b20();
}
}
void Int0() 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(IR_jiema()==1)
{
display_1838();
}
}
EX0=1;
}
试过了,不关那里的事阿,那只是检验功能键码解码是否正确而已,一个"="就可是了...
while循环本来就给了它跳出来的条件了阿,像while(IR==0);那样,就是只要检测到它是低电平的话就跳出来啦;
一周热门 更多>