自写简易红外遥控器代码遇到点问题求网友们帮忙看看~谢谢
/**********单片机外部晶振运用12MHZ****************************/
/****引导码:9ms载波,5ms无载波 ***/
//高电平表示方法为:载波1ms,2ms无载波.
//低电平表示方法为:载波1ms,1ms无载波.
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit red_io=P2^0;
uchar user_code,key;
bit flag;//标志位
uchar code data_table[]={0x00,0x01,0x02,0x03,0x04,0x05,
0x06,0x07,0x08,0x09,0x10,0x11, //数据码数组
0x12,0x13,0x14,0x15,0x16};
int count;//全局变量 count 计数进入中断次数
void delayms(int z)//以毫秒为单位的延时子函数
{
int i,j;
for(i=z;i>0;i--)
for(j=110;j>0;j--);
}
/**************************键盘扫描子函数*****************************/
void keyscan()
{
uchar temp;
P3=0xfe;//扫键盘第一行
temp=P3&0xf0;//如果第一行有键按下那么P3^4 P3^5 P^6 P3^7之中 的其中一个有电平变化为0
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xee:key=1;flag=1;break;//S1
case 0xde:key=2;flag=1;break;//S2
case 0xbe:key=3;flag=1;break;//S3
case 0x7e:key=4;flag=1;break;//S4
}
}
P3=0xfd;//扫键盘第二行
temp=P3&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xed:key=5;flag=1;break;//S5
case 0xdd:key=6;flag=1;break;//S6
case 0xbd:key=7;flag=1;break;//S7
case 0x7d:key=8;flag=1;break;//S8
}
}
P3=0xfb;//扫键盘第三行
temp=P3&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:key=9;flag=1;break;//S9
case 0xdb:key=10;flag=1;break;//S10
case 0xbb:key=11;flag=1;break;//S11
case 0x7b:key=12;flag=1;break;//S12
}
}
P3=0xf7;//扫键盘第四行
temp=P3&0xf0;
if(temp!=0xf0)
{
temp=P3;
switch(temp)
{
case 0xeb:key=13;flag=1;break;//S13
case 0xdb:key=14;flag=1;break;//S14
case 0xbb:key=15;flag=1;break;//S15
case 0x7b:key=16;flag=1;break;//S16
}
}
}
void init_timer0()
{
TMOD=0x02;//定时器0模式2自动装入8位数据
TH0=243;//38KHZ≈26us,半个周期则是13us,256-13==243
TL0=243;//低位用来执行重装数据到TH0处
EA=1;//打开总中断
ET0=1;//打开定时器中断
TR0=0;//暂时停止定时器0运作
}
/**************************红外发射模块*****************************/
void red_send(uchar dat)
{
uchar i,k;
init_timer0();//初始化定时器0
if(flag==1)//有按键按下时候
{
//count=0;
red_io=0;//先给红外线IO口赋0电平
TR0=1;//定时器0打开 开始计时
while(count!=692); //等待中断,当计数值count等于692时 载波持续9ms引导码,while条件为假退出死循环
count=0;//count清0
TR0=0;//停止计时
TH0=243;
TL0=243;
delayms(5);//无载波产生持续5ms引导码
for(i=0;i<8;i++)
{
if(user_code&0x01)//有高电平位置载波产生1ms,2ms不产生载波.
{
TR0=1;
while(count!=77);//1000us/13us == 77 ,1ms高电平载波信号
count=0;//count清0
TR0=0;
TH0=243;
TL0=243;
delayms(2);//2ms不产生载波
user_code>>=1;//右移1位
}
else
{
TR0=1;
while(count!=77);
count=0;//count清0
TR0=0;
TH0=243;
TL0=243;
delayms(1);//1ms不产生载波
user_code>>=1;//右移1位
}
}
for(k=0;k<8;k++)
{
if(dat&0x01)//有高电平位置载波产生1ms,2ms不产生载波.
{
TR0=1;
while(count!=77);//1000us/13us == 77 ,1ms高电平载波信号
count=0;//count清0
TR0=0;
TH0=243;
TL0=243;
delayms(2);//2ms不产生载波
dat>>=1;//右移1位
}
else
{
TR0=1;
while(count!=77);
count=0;//count清0
TR0=0;
TH0=243;
TL0=243;
delayms(1);//1ms不产生载波
dat>>=1;//右移1位
}
}
flag=0;//标志位清0
}
}
voidtime0() interrupt 1 //每13us进入中断一次
{
red_io=~red_io;//每进中断一次red_io取反一次,从而得到38khz载波
count++;//每进中断一次count计数一次
}
void main()
{
user_code=0x11;//用户码为1000 0001
while(1)
{
keyscan();
red_send(data_table);
}
}
问题是:仿真出来的结果,全是等距的方波并且方波频率不正确,这是怎么一回事? user_code=0x11;//用户码为1000 0001这时小错。可能原来是81H ,你改成11H
52单片机有定时器2,可以产生波型。比中断方法准确。中断方法也行,距离不是很远。
P2口最好有上拉,我有时P2操作三极管无法导通。
还有,有些协议可能最后还有一段结束信号,没有的话可能无法摇控设备。比如通常用的NEC协议, 很少有资料说最后还有个600us结束信号,前面写的再正确,没有最后的600us,设备始终不动作。
有兴趣可以看看我发的贴。 woshigeshuai 发表于 2012-11-16 08:11 static/image/common/back.gif
user_code=0x11;//用户码为1000 0001这时小错。可能原来是81H ,你改成11H
52单片机有定时器2,可以产生波 ...
谢谢.我是自己弄遥控自己弄解码的.能加你QQ吗? xtl2012 发表于 2012-11-16 08:17 static/image/common/back.gif
谢谢.我是自己弄遥控自己弄解码的.能加你QQ吗?
关于这个
我发过一个帖子
你可以搜索下
页:
[1]