谁有学习遥控器的代码参考啊?

kyzlin 2010-04-24 09:47:50
各位大侠,最近在做学习型遥控器,可是老是不对,那位好心的人给个代码参考一下啊?
...全文
203 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
lhbwhan 2011-03-26
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zmami 的回复:]
#include<reg52.h> //52单片机头文件,一般不要改动,里面包含特殊功能寄存器的定义
#include<intrins.h>

sbit hwx=P3^3; //定义红外接收脚,

code unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39……
[/Quote]

我的开发板上也是这个程序。单片机能确实解码,但是不管按下哪个遥控器按键,单片机上显示的编码都一样,也就是说所有按键的编码都一样。不知道是怎么回事?难道是遥控器坏了吗?高手求解。。。
zmami 2010-12-28
  • 打赏
  • 举报
回复
#include<reg52.h> //52单片机头文件,一般不要改动,里面包含特殊功能寄存器的定义
#include<intrins.h>

sbit hwx=P3^3; //定义红外接收脚,

code unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
//共阴数码管 0-9 a-f - 表
unsigned char l_tmpdate[8]={0,0,0x10,0,0};//显示管数据

unsigned char l_lhj[66]; //定义66位数组变量来存储接收的时间参数
void delay();//延时子函数
void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void main(void) //入口函数
{
EA=1; //首先开启总中断
EX1=1; //开启外部中断 1
IT1=1; // 设置成 下降沿触发方式
while(1){ //循环显示,接收都由中断处理
display(l_tmpdate,5);
}

}
void display(unsigned char *lp,unsigned char lc)//显示
{
unsigned char i; //定义变量
P2=0; //端口2为输出
P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管
for(i=0;i<lc;i++){ //循环显示
P2=table[lp[i]]; //查表法得到要显示数字的数码段
delay(); //延时
P2=0; //清0端口,准备显示下位
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
break;
P1++; //下一位数码管
}
}
void delay(void) //空5个指令
{
unsigned char i=13;
while(i)
i--;
}
void hongwai(void) interrupt 2 //外部中断 1 ,INT1(P3^3)连接红外线接收IC数据脚
{
unsigned char i,j,tmp;
EX1=0;
// hwx=1;
j=33; //传送一组数包括引导码1位,地址码8位加反码8位,指令码8位加反码8位,总共33位
i=0; //从第一维数组开始
tmp=100; //加八延时,
while(tmp){
tmp--;
}
if(hwx){ //然后再检测红线接收脚是有数据招收,有继续,没有则退出
EX1=1;
return;
}
while(j){ //循环接收33位数据,为何我们用到66位数组,我们可以不接收高电平时间常数,只接低电平常数就
//可以判断1或0了,在这里我们都接收,为串口调试软件接收计算波形
//还有一点要知道,接收波形是反向,在没有接收时端口为高电平
tmp=0;
l_lhj[i]=1; //时间量从1开始
while(!hwx){ //检测高低电平的变化
l_lhj[i]++; //没变继续加1
delay(); //加入延时,是因为我们采用8位二进来存储,如果不加延时,时间量将计满
tmp++; //此变量为防止干扰带来的死循环
if(tmp==250)
break;
}
i++;
tmp=0;
l_lhj[i]=1; //时间量从1开始
while(hwx){ //检测高低电平的变化
l_lhj[i]++; //没变继续加1
delay(); //同上
tmp++;
if(tmp==250)
break;
}
i++;
j--;
}
i=255; //加入循环延时,抗干扰
while(i){
tmp=255;
while(tmp){
P2=0XF0;
tmp--;
}
i--;
}
tmp=0;
for(i=3;i<19;i++,i++){ //处理地址位,对低电平时间数据的数理,这里我们只处理地址码和指令码,引导码和反码我们就忽略
tmp>>=1; //右移一位,接收低电平在前
if(l_lhj[i]>30) //检测低电平时间超过30就确认为1
tmp+=0x80;
}
l_tmpdate[0]=tmp/16; //分开2位以16进制显示
l_tmpdate[1]=tmp%16;
tmp=0;
for(i=35;i<51;i++,i++){ //同上,这里处理指令位
tmp>>=1;
if(l_lhj[i]>30)
tmp+=0x80;
}
l_tmpdate[3]=tmp/16;
l_tmpdate[4]=tmp%16;
EX1=1;
}
EmbeddedLong 2010-12-27
  • 打赏
  • 举报
回复
去年写过可惜不见了 楼猪去看看 郭天祥的那个论坛上有 是NEC协议的 不错哈 呵呵
kyzlin 2010-04-26
  • 打赏
  • 举报
回复
case 16://neg.
if (ir_code.bit1_low < ir_code.bit0_low)
{
step = 17;
}
else
{
step = 18;
}
break;
case 17://pos. ir_code.bit1_low < ir_code.bit0_low
if (recv_carrier_cycle > ir_code.lead_l)
{
return OK;
}
if (recv_carrier_cycle <= ir_code.bit1_low)
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if (ir_code.bit0_low <= recv_carrier_cycle)
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if ((recv_carrier_cycle - ir_code.bit1_low) < (ir_code.bit0_low - recv_carrier_cycle))
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
step = 16;
case 18://pos. ir_code.bit0_low < ir_code.bit1_low
if (recv_carrier_cycle > ir_code.lead_l)
{
return OK;
}

if (recv_carrier_cycle <= ir_code.bit0_low)
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if (ir_code.bit1_low <= recv_carrier_cycle)
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if ((recv_carrier_cycle - ir_code.bit0_low) < (ir_code.bit1_low - recv_carrier_cycle))
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
step = 16;
break;

}
}
}
return FALSE;

}

//学习至ir_code
//成功返回OK,失败返回FALSE
u8 ir_learn(void)
{
u16 temp = 0;

ir_power_on();
osc_setup(8);
TA1CTL = TASSEL_2 + ID_3 + MC_2 + TAIE; // SMCLK, 8 Div, Contmode int enable
TA1CCTL2 = CM_1 + CCIS_0 + SCS + CAP + CCIE; //上升沿捕捉,CCI2A,同步捕获,CCIFG0中断允许
temp = ir_ta1_capture_1mhz();
ir_stop();
osc_setup(1);
ir_power_off();

if (OK == temp)
{
if (count_bit != 8)
{
ir_code.data[ir_code.num] <<= count_bit;
ir_code.bit_num_last_data = 8 - count_bit;
ir_code.num ++;
}
else
{
ir_code.bit_num_last_data = 8;
}
////////////////////////////test//////////////////////////

/*uart_sendbyte(ir_code.carrier_cycle);
uart_sendbyte(ir_code.num);
uart_sendbyte(ir_code.lead_h >> 8);
uart_sendbyte(ir_code.lead_h);
uart_sendbyte(ir_code.lead_l >> 8);
uart_sendbyte(ir_code.lead_l);
uart_sendbyte(ir_code.bit1_high >> 8);
uart_sendbyte(ir_code.bit1_high);
uart_sendbyte(ir_code.bit1_low >> 8);
uart_sendbyte(ir_code.bit1_low);
uart_sendbyte(ir_code.bit0_high >> 8);
uart_sendbyte(ir_code.bit0_high);
uart_sendbyte(ir_code.bit0_low >> 8);
uart_sendbyte(ir_code.bit0_low);
uart_sendbyte(ir_code.bit_num_last_data);
for (u16 j = 0; j < 15; j++)
{
uart_sendbyte(ir_code.data[j]);
}
*/
/////////////////////////////////////////////////////////
return OK;
}
else
{
return FALSE;
}
}
kyzlin 2010-04-26
  • 打赏
  • 举报
回复
case 5: //解码数据
if (recv_carrier_cycle >> 8)
{
recv_int_stop_flag = 1;
recv_carrier_cycle -= ir_code.carrier_cycle; //低电平时间

if (recv_carrier_cycle > ir_code.lead_l)
{
recv_int_stop_flag = 0;
return OK;
}
else if (ir_code.bit1_low < ir_code.bit0_low)
{
if (recv_carrier_cycle <= ir_code.bit1_low)
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if (ir_code.bit0_low <= recv_carrier_cycle)
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if ((recv_carrier_cycle - ir_code.bit1_low) < (ir_code.bit0_low - recv_carrier_cycle))
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
}
else//ir_code.bit0_low < ir_code.bit1_low
{
if (recv_carrier_cycle <= ir_code.bit0_low)
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if (ir_code.bit1_low <= recv_carrier_cycle)
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else if ((recv_carrier_cycle - ir_code.bit0_low) < (ir_code.bit1_low - recv_carrier_cycle))
{
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
else
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
}
}
recv_int_stop_flag = 0;
}
break;

case 11://无载波 引导低
ir_code.lead_l = recv_carrier_cycle;
step = 12;
break;
case 12://BIT1 high
ir_code.bit1_high = recv_carrier_cycle;
step = 13;
break;
case 13://BIT1 low
ir_code.bit1_low = recv_carrier_cycle;
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
count_bit--;
step = 14;
break;
case 14://BIT0 high
ir_code.bit0_high = recv_carrier_cycle;
step = 15;
break;
case 15://BIT0 low
if (((recv_carrier_cycle <= ir_code.bit1_low) && ((ir_code.bit1_low - recv_carrier_cycle) < 50))
|| ((ir_code.bit1_low < recv_carrier_cycle) && ((recv_carrier_cycle - ir_code.bit1_low) < 50)))//误差为50
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
ir_code.bit0_high = 0;
step = 14;
}
else
{
ir_code.bit0_low = recv_carrier_cycle;
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
step = 16;
}
break;
kyzlin 2010-04-26
  • 打赏
  • 举报
回复
#include "../include/msp430x41x2.h"
#include "../include/ir.h"
#include "../include/e2rom.h"
#include "../include/time.h"

#include "../include/lcd.h"

#define ir_power_on() P1OUT |= BIT0
#define ir_power_off() P1OUT &= ~BIT0
#define ir_out0() P3OUT &= ~BIT1
#define ir_out1() P3OUT |= BIT1


typedef struct
{
u8 carrier_cycle; //载波周期时间
u8 num; //字节数
u16 lead_h; //引导高载波周期
u16 lead_l; //引导低时间
u16 bit1_high; //位1 高电平载波周期
u16 bit0_high; //位0 高电平载波周期
u16 bit1_low; //位1 低电平时间
u16 bit0_low; //位0 低电平时间
u8 bit_num_last_data;
u8 data[15]; //数据
} ir_code_t; //15 + 15

const u16 ir_config_addr[5] = {IR_CONFIG1_ADDR,IR_CONFIG2_ADDR,IR_CONFIG3_ADDR,IR_CONFIG4_ADDR,IR_CONFIG5_ADDR};


volatile u8 recv_int_flag = 0; //接收中断标志
volatile u8 recv_int_stop_flag = 0;
volatile u16 ta1_overflow = 0;
u16 recv_carrier_cycle = 0; //每次接收载波周期
u16 count_bit = 8; //学习数据位计数
ir_code_t ir_code; //红外码变量

void ir_init(void)
{
P1DIR |= BIT0; //电源控制输出
ir_power_off();
ir_out0();
P3DIR |= BIT1; // P3.1 output
P3SEL |= BIT1 + BIT0; //P3.1 P3.0 option select
}

void ir_stop(void)
{
TA1CTL = 0;
//TA1CCTL0 = 0;
TA1CCTL2 = 0;
TA1CCTL3 = 0;
}


//TA1 1MHZ capture
u8 ir_ta1_capture_1mhz(void)
{
u8 step = 0;

ta1_overflow = 0;
while (ta1_overflow < 154)
{
if (recv_int_flag)
{
recv_int_flag = 0;
switch (step)
{
case 0: //接收到IR信号,准备接收
TA1CCTL2 &= ~CM_1;
TA1CCTL2 |= CM_2;//neg.
recv_carrier_cycle = 0;
ir_code.carrier_cycle = 0xff;
ir_code.bit0_high = 0;
ir_code.bit0_low = 0;
ir_code.bit1_high = 0;
ir_code.bit1_low = 0;
ir_code.lead_h = 0;
ir_code.lead_l = 0;
ir_code.num = 0;
for (u16 i = 0; i < 16; i++)
{
ir_code.data[i] = 0;
}
count_bit = 8;
recv_int_stop_flag = 0;
ta1_overflow = 0;
step = 10;
break;
case 10://判断是否有载波
if (recv_carrier_cycle > 1000)//no
{
ir_code.lead_h = recv_carrier_cycle;
ir_code.carrier_cycle = 0;
TA1CCTL2 &= ~CM_2;
TA1CCTL2 |= CM_3;//both
step = 11;
}
else
{
TA1CCTL2 &= ~CM_2;
TA1CCTL2 |= CM_1;//pos.
step = 1;
}
break;
case 1: //开始接收,解码载波周期
ir_code.lead_h ++; //引导码高电平加1
if ((ir_code.lead_h > 10) && (20 < recv_carrier_cycle) && (recv_carrier_cycle < 30))//33k-50k
{
ir_code.carrier_cycle = recv_carrier_cycle; //记录载波周期
step = 2;
}
break;
case 2: //解码引导码
if (recv_carrier_cycle >> 8)
{
ir_code.lead_l = recv_carrier_cycle - ir_code.carrier_cycle;//记录引导码低电平
step = 3;
}
else
{
ir_code.lead_h ++; //引导码高电平加1
}
break;
case 3: //解码数据bit1
if (recv_carrier_cycle >> 8)
{
ir_code.bit1_low = recv_carrier_cycle - ir_code.carrier_cycle;//记录数据bit1低电平
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
step = 4;
}
else
{
ir_code.bit1_high ++; //数据bit1高电平加1
}
break;
case 4: //解码数据bit0
if (recv_carrier_cycle >> 8)
{
recv_carrier_cycle -= ir_code.carrier_cycle; //低电平时间
if (((recv_carrier_cycle <= ir_code.bit1_low) && ((ir_code.bit1_low - recv_carrier_cycle) < 10))
|| ((ir_code.bit1_low < recv_carrier_cycle) && ((recv_carrier_cycle - ir_code.bit1_low) < 10)))//误差为10
{
ir_code.data[ir_code.num] <<= 1;
ir_code.data[ir_code.num]++;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
ir_code.bit0_high = 0;
}
else
{
ir_code.bit0_low = recv_carrier_cycle;//记录数据bit0低电平
ir_code.data[ir_code.num] <<= 1;
if (!(--count_bit))
{
count_bit = 8;
ir_code.num ++;
}
step = 5;
}
}
else
{
ir_code.bit0_high ++;
}
break;
Peasant_Lee 2010-04-24
  • 打赏
  • 举报
回复
对方能接收到数据么?出问题的话,一般也就是红外发送的时候出问题了,一般的编码,只要对照编码规格书就不会有错的。。。
nhcxc 2010-04-24
  • 打赏
  • 举报
回复
如果是学习型的就要在EEPROM里面加对比函数。。
Peasant_Lee 2010-04-24
  • 打赏
  • 举报
回复
楼上是红外接收来控制电机的程序,不是发送的,呵呵
nhcxc 2010-04-24
  • 打赏
  • 举报
回复
上面的代码采用外部中断来实现接收。。接收放是1838的红外接收头。。已测试通过。。
nhcxc 2010-04-24
  • 打赏
  • 举报
回复
#include <reg52.h> //51芯片管脚定义头文件
#include <intrins.h> //内部包含延时函数 _nop_();

#define uchar unsigned char
#define uint unsigned int

//#define DELAYNUM 40 //该数值可以调节显示的速度
sbit SDATA_595=P1^5; //串行数据输入
sbit SCLK_595 =P1^6; //移位时钟脉冲
sbit RCK_595 =P1^7; //输出锁存器控制脉冲
sbit CS_LED8 =P1^1; //片选
sbit CS_1302 =P1^4;
sbit IRIN = P3^2; //红外接收器数据线
sbit BEEP = P3^7; //蜂鸣器驱动线
sbit DCMOTO = P3^4; //直流电机驱动线


//uchar code table[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e};
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar IRCOM[]={0x00,0x00,0x00,0x00,0x10,0x10};
uchar dis[8];

void delay(unsigned char x);
void display();
void beep();


/*******************************************************
* *
* 主函数 *
* *
*******************************************************/
main(void)
{
// uchar k;
TMOD|=0x01;
TH0=0Xfc;
TL0=0X66;
TR0=1;
EA=1;
ET0=1;
EX0=1;
IP=0X01;
CS_1302=0;
DCMOTO=0;
while(1)
{
dis[7]=table[IRCOM[4]];
dis[6]=table[IRCOM[5]];
// display();
if(IRCOM[2]==0x01) DCMOTO=~DCMOTO; //启动电机
if(IRCOM[2]==0x02) DCMOTO=0; //停止电机
}

} //end of main()

void timer0(void) interrupt 1
{
TH0=0Xfc;
TL0=0X66;
display();
}

/*******************************************************
* *
* 显示函数 *
* *
*******************************************************/

void display()
{
uchar num,c,i;
for(i=0;i<8;i++)
{
num=dis[i];
CS_LED8=0;
for(c=0;c<8;c++)
{
SCLK_595=0;
num=num<<1;
SDATA_595=CY;
SCLK_595=1;
SCLK_595=0;
}
num=~(1<<i);
for(c=0;c<8;c++)
{
SCLK_595=0;
num=num>>1;
SDATA_595=CY;
SCLK_595=1;
SCLK_595=0;
}
RCK_595=0;
_nop_();
_nop_();
RCK_595=1;
_nop_();
_nop_();
RCK_595=0;
delay(1);
CS_LED8=1;
}
}

void IR_IN() interrupt 0 //using 0
{
unsigned char j,k,N=0;
EA = 0;
delay(10);

if (IRIN==1)
{
EA =1;
return;
}
//确认IR信号出现
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
{
delay(1);
}
while (IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
{
delay(1);
}
for (j=0;j<4;j++) //收集四组数据
{
for (k=0;k<8;k++) //每组数据有8位
{
while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
{
delay(1);
}
while (!IRIN) //等 IR 变为高电平
{
delay(1);
}
while (IRIN) //计算IR高电平时长
{
delay(1);
N++;
} //高电平计数完毕
if (N>=30)
{
EA=1;
return; //0.14ms计数过长自动离开。
}
IRCOM[j]=IRCOM[j] >> 1; //数据最高位补“0”
if (N>7)
{
IRCOM[j] = IRCOM[j] | 0x80;
} //数据最高位补“
N=0;
}//end for k
}//end for j
/*
if (IRCOM[2]!=~IRCOM[3]) //接收时间是否正确
{
EA=1;
return;
}

if(IRCOM[0]!=0x00) //比较用户码
{
EA=1;
return;
}*/
IRCOM[4]=IRCOM[2] & 0x0F; //取键码的低四位
IRCOM[5]=IRCOM[2] >> 4; //右移4次,高四位变为低四位

beep();

EA = 1;
}

/**********************************************************/
void beep()
{
unsigned char i;
for (i=0;i<180;i++)
{
delay(6);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
}
/**********************************************************/
void delay(unsigned char x) //x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}
Peasant_Lee 2010-04-24
  • 打赏
  • 举报
回复
恩,也就是收到的数据不正确,能检测到对方收到的是什么数据么?你的遥控器的发送端是不是用一个红外发送管,然后用个三极管来驱动它的?那么你在发送的时候,是不是要定时器来完成发送的编码脉冲时序的?检查下这个编码脉冲时序。这些东西讲很难讲,呵呵,相对比较难调,特别是没有示波器来抓的话,更难搞。
kyzlin 2010-04-24
  • 打赏
  • 举报
回复
能收到数据啊,可是去控制设备的时候就不行了?

27,374

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧