#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define IR (IRIN==0)
unsigned char Y0;
unsigned char Rcv = 0;
unsigned char IRCOM[4];
unsigned char tempdata[4];
sbit IRIN = P1^7;
sbit DQ = P3^7;
void send_temp();
void do_key(uchar pt)
{
/*******************************
;================================
;****** 红外遥控器键值表 ******
; 45 46 47
; 44 40 43
; 07 15 09
; 16 19 0d
; 0c 18 5e
; 08 1c 5a
; 42 52 4a
;================================
********************************/
Y0=0xff;
switch(pt)
{
case 0x0c: Y0=0x31; break;
case 0x18: Y0=0x32; break;
case 0x5e: Y0=0x33; break;
case 0x08: Y0=0x34; break;
case 0x1c: Y0=0x35; break;
case 0x5a: Y0=0x36; break;
case 0x42: Y0=0x37; break;
case 0x52: Y0=0x38; break;
case 0x4a: Y0=0x39; break;
case 0x16: Y0=0x30; break;
case 0x45: Y0=0x40; break;
case 0x46: Y0=0x41; break;
case 0x47: Y0=0x42; break;
case 0x44: Y0=0x43; break;
case 0x40: Y0=0x44; break;
case 0x43: Y0=0x45; break;
case 0x07: Y0=0x46; break;
case 0x15: Y0=0x47; break;
case 0x09: Y0=0x48; break;
case 0x19: Y0=0x49; break;
case 0x0d: Y0=0x4a; break;
default : Y0=pt;break;
}
}
void IRdelay(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
void IR_DO(void)
{
unsigned char j,k,N=0;
IRdelay(35);
if (IRIN==1)
{
return;
}
//确认IR信号出现
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
IRdelay(1);
for (j=0;j<4;j++) //收集四组数据
{
for (k=0;k<8;k++) //每组数据有8位
{
while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
IRdelay(1);
while (!IRIN) //等 IR 变为高电平
IRdelay(1);
while (IRIN) //计算IR高电平时长
{
IRdelay(1);
N++;
if (N>=30)
{
EX0=1;
return;
} //0.14ms计数过长自动离开。
} //高电平计数完毕
IRCOM[j]=IRCOM[j] >> 1; //数据最高位补“0”
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //数据最高位补“1”
N=0;
}
}
if (IRCOM[2]!=~IRCOM[3])
{
EX0=1;
return;
}
do_key(IRCOM[2]);
Rcv=' ';
}
/*
void smg_test()
{
uchar i;
uint j;
for(i=0;i<18;i++)
{
for(j=0;j<20000;j++)
{
P1=0;
P0=led[i];
P0=0xff;
}
}
delay_ms(1000);
for(i=0;i<6;i++)
{
for(j=0;j<20000;j++)
{
P0=led[0];
P1=swh[i];
P1=0xff;
}
}
}
///延时函数,大约是一毫秒/z
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
} */
void RS232_Init()
{
SCON = 0x50; //串口工作方式为1,串行允许接受
TMOD = 0x22; //定时器1工作在方式2
//PCON = 0x80; //SMOD = 1; 波特率加倍
//TH1 = 0xfa; //波特率 9600bps fosc="11".0592MHz
//TL1 = 0xfa;
TH1 = 0xfd;
TL1 = 0xfd;
ES = 1; //开串口中断
TR1 = 1; //允许定时器1工作
EA = 1; //开总中断
}
//串口通讯
//按下按钮,单片机发送数据"Come On!\r\n"给主机
//单片机晶振:11.0592MHz
//波特率: 9600bps
//串口发送一个字节
void SendChar(uchar dat)
{
SBUF = dat; //待发送的数据写入缓冲区
while(!TI); //等待发送完成
TI = 0; //清零发送标志位
}
void INT_UartRcv(void) interrupt 4
{
if(RI) //查询接收标志位(有数据发送过来时置为1)
{
RI = 0; //接收标志位清零
Rcv = SBUF; //存储缓冲区的数据
SendChar(Rcv); //让从电脑上传到单片机的数据,传回的电脑显示
}
}
void dly(uint t)
{
for(;t>0;t--);
}
void reset()
{
uchar presence=1;
while(presence)
{
while(presence)
{
DQ=1;
_nop_();_nop_();
DQ=0;
dly(50);
DQ=1;
dly(6);
presence=DQ;
}
dly(45);
presence=~DQ;
}
DQ=1;
}
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
DQ=0;_nop_();_nop_();_nop_();_nop_();_nop_();
DQ=val&0x01;
dly(6);
val=val/2;
}
DQ=1;
_nop_();
}
uchar read_byte(void)
{
uchar i;
uchar value=0;
for(i=8;i>0;i--)
{
DQ=1;_nop_();_nop_();
value>>=1;
DQ=0;
_nop_();_nop_();_nop_();_nop_();
DQ=1;_nop_();_nop_();_nop_();_nop_();
if(DQ)value|=0x80;
dly(6);
}
DQ=1;
return(value);
}
void read_temp()
{
uchar a,b;
uchar tflag; //负号标志
uint t=0; //读取的温度
EA=0;
reset();
write_byte(0xcc);
write_byte(0xbe);
a=read_byte(); //读取高字节
b=read_byte(); //读取低字节
reset();
write_byte(0xcc);
write_byte(0x44);
//处理读取温度t
t=b;
t<<=8; //值左移8位
t=t|a; //合并高低位数值
if(t<0xfff) //判断温度是为正还是为负
tflag=1; //温度为正数
else
{
tflag=0; //温度为负数
t=~t+1; //负值换算
}
t=t*(0.625); //温度扩大10倍,精确到1位小数
tempdata[1]=t%1000/100; //十位数
tempdata[2]=t%100/10; //个位数
tempdata[3]=t%10; //小数位
tempdata[1]+=0x30;
tempdata[2]+=0x30;
tempdata[3]+=0x30;
if (tempdata[0]==1);
else if (tflag)
tempdata[0]=0x20; //符号位
else
tempdata[0]='-';
EA=1;
}
void send_temp()
{
read_temp();
SendChar(tempdata[0]);
SendChar(tempdata[1]);
SendChar(tempdata[2]);
SendChar('.');
SendChar(tempdata[3]);
SendChar(' ');
SendChar(' ');
SendChar(' ');
SendChar(' ');
SendChar(Y0);
SendChar(' ');
SendChar(' ');
SendChar(' ');
SendChar(' ');
Rcv = 0;
}
void main()
{
RS232_Init();
while(1)
{
if(IR) IR_DO();
if(Rcv==' ') send_temp();
}
}