本帖最后由 l764583152 于 2014-9-4 20:17 编辑
#include<reg52.h>
#include<intrins.h> //移位头文件
#define uint unsigned int
#define uchar unsigned char //宏定义
sbit PWM = P2^7; //用来声明P2.7口为程序所要控制的端口,"sbit"是KEIL专门用来声明某位IO口
sbit ir=P3^3; //红外数据接收
uchar ir
time; //红外时间
uchar startflag; //开始接收标志位
uchar irdata[33]; //接收的数据 包括引导码一共33位
uchar bitnum; //第几位数据
uchar irreceok; //接收完毕标志位
uchar ircode[4]; //数据存放
uchar irprosok; //解码完毕标志位
uchar PWM_ON ; //定义低电平时间
uchar CYCLE;
uchar vvalue;
void Delay(uint del)
{
uint i,j;
for(i=0; i<del; i++)
for(j=0; j<450; j++) //这个是通过软件
仿真得出的数
;
}
void Delay_1ms(uint i) //定时子程序 定时1毫秒
{
uchar x,j;
for(j=0;j<i;j++)
for(x=0;x<=148;x++)
;
}
void time0init0 (void) //定时器0初始化
{
TMOD=0X02; //工作方式定义 8位重装定时器
TH0=0X00; //高8位预装
TL0=0X00; //低8位预装
//IE=0X82 //开启总中断及定时器0中断
ET0=1; //开定时器0中断
EA=1; //开总中断
TR0=1; //启动定时器
}
void Time1(void)
{
TMOD=0x10; //定时器设置 1ms in 12M crystal
TH0=(65536-1000)/256;
TL0=(65536-1000)%256; //定时1mS
IE=0x88; //打开中断
TR1=1; //定时器打开
}
void int1init(void)
{
IT1=1; //定义外部中断1为下降沿触发
EX1=1; //开外部中断1
EA=1; //开总中断
//IE=0X84; //开总中断及外部中断1
}
void display(void)
{
if(vvalue==0x45)PWM_ON=0;
else if(vvalue==0x46)PWM_ON=2;
else if(vvalue==0x47)PWM_ON=4;
else if(vvalue==0x44)PWM_ON=6;
else if(vvalue==0x40)PWM_ON=10;
else PWM_ON=10;
}
void irpros(void) //数据解码
{
uchar k,i,j;
uchar value;
k=17;
for(i=0;i<8;i++)
{
value=value>>1;
if(irdata[k]>6)
{
value=value | 0x80; // 置1
}
k++;
}
vvalue=value;
irprosok=1; //解码完毕
}
void main()
{
time0init0();
int1init();
Time1();
PWM = 1;
while(1)
{
if(irreceok)
{
irpros();
irreceok=0;
}
if(irprosok)
{
irprosok=0;
}
display();
}
}
void time0init () interrupt 1 //定时器0服务子程序
{
irtime++; //最大加到255
}
void int1 () interrupt 2 //外部中断1服务子程序
{
if(startflag)
{
if(irtime>47) //检测引导码
{
bitnum=0;
}
irdata[bitnum]=irtime; //装入引导码
irtime=0; //定时器清0
bitnum++;
if(bitnum==33) //数据接收完毕
{
bitnum=0;
irreceok=1;
}
}
else
{
startflag=1; //第一次进入中断后,因为定时器定时的irtime不为0,此时需要清0,标志位startflag定义后没初始化系统默认为0,那么if语句通不过,立即跳到else随即irtime清0,startflag置1.
irtime=0;
}
}
void tim(void) interrupt 1 using 1
{
static unsigned char count;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;//定时1mS
if(count==PWM_ON)
{
PWM = 0; //直流电机转
}
count++;
if(count == CYCLE)
{
count=0;
if(PWM_ON!=0) //如果左右时间是0 保持原来状态
{
PWM = 1; //直流电机不转
}
}
}
unsigned char dat;
void main()
{
IT1=1;
EX1=1;
EA=1;
while(1)
{
把dat用数码管显出来,看遥控的值!
}
}
void Delay140us() //@12.000MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 158;
do
{
while (--j);
} while (--i);
}
void exint1()interrupt 2
{
unsigned char j,k,Time;
unsigned int err;
Time=0;
gd=1;
if(IRIN==0) //确认是否真的接收到正确的信号
{
err=1000; //1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去
{
Delay140us();
err--;
}
if(IRIN==1) //如果正确等到9ms低电平
{
err=500;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去
{
Delay140us();
err--;
}
for(k=0;k<4;k++) //共有4组数据
{
for(j=0;j<8;j++) //接收一组数据
{
err=60;
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
{
Delay140us();
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{
Delay140us();//0.14ms
Time++;
err--;
if(Time>30)
{
return;
}
}
IrValue[k]>>=1; //k表示第几组数据
if(Time>=8) //如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完时间要重新赋值
}
}
}
if(IrValue[0]!=~IrValue[1])
{
return;
}
else
{
dat=IrValue[2];
}
}
}
我一直用这个!看合不合你要求呢!
好的 谢谢 我看看
一周热门 更多>