#include <reg52.h>
//定义位选端口 使用3-8译码器
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
sbit IRD = P3^2;
//重定义
typedef unsigned int uint;
typedef unsigned char uchar;
//根据遥控器的排布设置的显示 前几个没有定义显示0;
uchar code smgduan[21]={0x00,0x00,0x00,
0x77,0x7c,0x39,
0x5e,0x79,0x71,
0x3f,0X76,0x00,
0x06,0x5b,0x4f,
0x66,0x6d,0x7d,
0x07,0x7f,0x6f};
//定义全局变量
uchar num=0;
//发射器信号; 遥控器每个按键的发射的值
uchar Codemath[21]={0x45,0x45,0x47, // 电源, mode , 静音
0x44,0x40,0x43, // 暂停, 左快进, 右快进
0x07,0x15,0x09, // EQ , VOL- , VOL+
0x16,0x19,0x0d, // 0 , RPT , U/SD
0x0c,0x18,0x5e, // 1 , 2 , 3
0x08,0x1c,0x5a, // 4 , 5 , 6
0x42,0x52,0x4a}; // 7 , 8 , 9
DisplayData[8]={0};//位选数据
//存数据接收遥控器数组的数组
uchar ExredData[4]={0,0,0,0};
//函数声明
void intnum(); //这个函数在调用函数之后提前声明
以上就简单的定义端口 和数组的定义;
//大概10uS的延时
void delay (uint i)
{
while(i--);
}
//中断初始化;
void InterruptInit ()
{
EX0 = 1;//允许外部中断0;
IT0 = 1;//下降沿触发;
EA = 1;//开总中段
IRD = 1;//拉高初始数据电平
}
写了一个延时函数;用于与遥控器通讯,与遥控器通讯使用的是PPM码(脉冲位置调制码,脉冲串之间的时间间隔来实现信号调制) 所以对延时要求较多;利用外部中断实现连接接收器;可以利用中断子程序来实现数据接收;
/外部中断0 服务程序;
void Exred () interrupt 0
{
uint c=0; //计算时间
uchar x=0;
uchar i=0;
uchar time=0;
delay(700);
if (!IRD) //IRD 没变高
{
c=0;
while ((!IRD) & (c<900)) //继续等待一段时间 超时跳出
{
delay(1);
c++;
}
if(IRD)
{
c=0;
while(IRD & (c<500)) //等待4500us 高电平 结束;
{
delay(1);
c++;
}
for (x=0;x<4;x++) //4个数据
{
for (i=0;i<8;i++)//每个数据8位;
{
c=0;
while ((!IRD) & (c<60)) //等待560us 低电平结束
{
delay(1);
c++;
}
c=0;
while (IRD & (c<500)) //计算高电平时间
{
delay(10);//0.1ms
c++;
time++;
}
if (time>40)
{
return ; //通讯失败
}
ExredData[x] >>= 1;//先接收低位
if (time>=8) //说明是传的是1
{
ExredData[x] |= 0x80; //高位给1;
}
time =0; //清除时间 准备下一个数据;
}
}
//num++; //通讯成功 数码管前进
for (i=7;i>0;i--)
{
DisplayData[i] = DisplayData[i-1];
}
}
}
}
产生中断后通过下图流程判断是否进入数据处理,起始码必须的正确接收后才开始处理数据,接收4个字节的数据,如下;
起始码对上后,利用循环接收数据,数据0/1 是通过高电平时间确定的,如下图,通过判断高电平时间来确定是0/1;我选择的中间值来判断;
void intnum()
{
if (ExredData[2] == ~ExredData[3])//判段数据是否正确;
{
uchar j=1;
for(j=1;j<21;j++)
{
if( ExredData[2] == Codemath[j])
{
DisplayData[0] = smgduan[j];
}
}
}
}
void DigDisplay()//实现8个8段数码管循环显示
{
uchar i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(7):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(6):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(5):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(4):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(3):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(2):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(1):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(0):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=DisplayData[i];//发送数据
delay(100); //间隔一段时间扫描
P0=0x00;//消隐
}
}
//主函数
int main ()
{
uchar i=0;
InterruptInit (); //初始化中断
while (1)
{
intnum();//收到的数据处理
DigDisplay();//显示数据;
if (ExredData[2]==Codemath[0])
{
for (i=0;i<8;i++)
DisplayData[i] =0;
}
}
return 0;
}
将接收到的数据判断按下的是遥控器的那个类容,然后将内容转换通过8个数码管显示;既实现按下什么,显示什么.