|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2008-8-22 12:09:18
|
显示全部楼层
经过几天的测试,问题任然没有解决,我把我的编解码程序贴上来。看那位高人指导下。
编码用的51,12MHZ 解码用的AVR m8 1MHZ
编码程序。
#include <REGX51.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define IR_WF P1_3//数据发射端口
#define IR P1_0//指示灯
uchar data btt=0;
uint data count=0; //延时计数器
static uint endcount=0; //终止延时计数
uchar bdata flag=0; //红外发送标志
uchar bdata IR_SendBuf[5]={0x01,0xfe,0x57,0x58,};
uchar bdata timp=0;
delay_mm(uint ms)
{ // 延时子程序
uchar i;
while(ms--)
{
for(i = 0; i< 250; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void SendIRdata(void)
{
int i;
uchar bdata irdata=0;
uchar bdata tklme=0;
////////////////////////////////////////////////
for(tklme=50;tklme>0;tklme--) //发送50次前导码
{
endcount=40;//发送1ms
count=0;
IR_WF=1;
TR0=1;
do{}while(count<=endcount);
//停止3ms
IR_WF=0;
TR0=0;
endcount=120;
count=0;
TR0=1;
do{}while(count<=endcount);
TR0=0;
endcount=0;
irdata=0;
}
//////////////////////////////////////
//发送1ms的起始码
endcount=40;
count=0;
IR_WF=1;
TR0=1;
do{}while(count<=endcount);
//不发送4ms
IR_WF=0;
TR0=0;
endcount=160;
count=0;
TR0=1;
do{}while(count<=endcount);
TR0=0;
endcount=0;
irdata=0;
//////////////////发送4字节数据///////////////////////
for(btt=0;btt<4;btt++)
{
irdata=IR_SendBuf[btt];
for(i=0;i<8;i++)
{
//先发送500us(即解码中0.5ms的低电平)
endcount=20;
count=0;
IR_WF=1;
TR0=1;
do{}while(count<=endcount);
TR0=0;
endcount=0;
count=0;
//停止发送信号(即解码中的高电平)
if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=60; //1为宽的高电平1500US
}
else
{
endcount=40; //0为窄的高电平1000us
}
IR_WF=0;
TR0=1;
do{}while(count<endcount);
TR0=0;
count=0;
endcount=0;
irdata=irdata>>1;
};
}
//////////////////////////////////////////////
TR0=0;
count=0;
// endcount=100;
// IR_WF=1;
// TR0=1;
// do{}while(count<endcount);
// TR0=0;
endcount=0;
// count=0;
IR_WF=0;
}
//定时器0;25us中断一次
void timer0(void) interrupt 1 using 2//25us
{
TH0=0xff;
TL0=0xf4;
count++;
}
void main(void)
{
uchar v=0;
delay_mm(100);
count = 0;
flag = 0;
IR_WF= 0;
TMOD = 0x01; //设定时器0为16位模式1
IE0=1;
ET0 = 1; //定时器0中断允许
TH0=0xff;
TL0=0xf4;
TR0 = 0;
EA = 1; //允许CPU中断
while(1)
{
IR= 0;
for(v=15;v>0;v--)
delay_mm(100);
IR_WF=0; //发送前端口低
IR= 1; //指示灯亮
SendIRdata();
for(v=15;v>0;v--)
delay_mm(100);
}
}
解码部分:
//包含所需头文件
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdint.h>
#include <avr/wdt.h>
#define FREQ 1
#define BIT(x) (1<<(x))
#define uchar unsigned char
#define uint unsigned int
uchar sttf=0;
uchar sreg=0;
uchar sfgh1=0;
uchar bitcnt=0;
uint newFall=0;
uint oldFall=0;
uchar fiasf=0;
uchar data0=0;
uchar uc_overcon=0;
unsigned long vvvv=0;
unsigned int ui_ringt=0;
unsigned int ui_Falling=0;
unsigned char IR[8]={0x11,0x22,0x33,0x44,0x55,};
void DelayMs(uint t)
{
uint p;
for(p=t;p>0;p--)
_delay_loop_2(FREQ * 250);
}
//定时器T1溢出中断服务程序
//#pragma interrupt_handler timer1_ovf_isr:9
//void timer1_ovf_isr(void)
SIGNAL(SIG_OVERFLOW1)
{
uc_overcon++;
}
//定时器T1输入捕捉中断服务程序
//#pragma interrupt_handler timer1_capt_isr:6
//void timer1_capt_isr(void)
SIGNAL(SIG_INPUT_CAPTURE1)
{
if(PINB&_BV(PB0))
{
ui_ringt=ICR1;
TCCR1B=0x00;
TCCR1B|=0X82;//设置成下降沿中断
uc_overcon=0;//益出计数器开始记数
}
else
{
ui_Falling=ICR1;
TCCR1B=0x00;
TCCR1B|=0xC2;//设置成上升沿中断
vvvv=(unsigned long)ui_Falling-(unsigned long)ui_ringt;//+(unsigned long)uc_overcon*0x10000/500;
ui_Falling=0;
ui_ringt=0;
uc_overcon=0;
}
/////////////////////header信号高电平4MS/////////////////////////
if((vvvv>3800) && (vvvv<4100))
{
bitcnt=0;
data0=0;
vvvv=0;
fiasf=0;
}
if((vvvv>850) && (vvvv<1050)) // "0"信号高电平1MS
{
sttf=0;
vvvv=0;
bitcnt++;
data0=(data0>>1)+sttf;
}
if((vvvv>1400) && (vvvv<1600)) //“1”信号高电平1.5MS
{
sttf=1;
vvvv=0;
bitcnt++;
data0=((data0>>1)+sttf);
}
///////////////大于头信号时间退出/////////////////////////
if(vvvv>4200)
{
TCCR1A = 0x00;
TCCR1B = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;//输入捕捉匹配值
TCCR1A = 0x00;
TCCR1B = 0x81;//启动定时器
bitcnt=0;
vvvv=0;
return;
}
if(bitcnt==7) //接收8位数据满
{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=data0;
IR[0]=data0;
data0=0;
}
else if(bitcnt==15) //接收16位满
{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=data0;
IR[1]=data0;
data0=0;
}
else if(bitcnt==23) //接收24位满
{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=data0;
IR[2]=data0;
data0=0;
}
else if(bitcnt==31) //接收32位满
{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=data0;
IR[2]=data0;
data0=0;
sreg = SREG;
cli(); //禁止所有中断
TCCR1A = 0x00;
TCCR1B = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;//输入捕捉匹配值
TCCR1A = 0x00;
TCCR1B = 0x81;//启动定时器
SREG=sreg;
bitcnt=0;
}
else if(bitcnt>=32) //接收8位满
{
loop_until_bit_is_set(UCSRA,UDRE);
UDR=data0;
sreg = SREG;
cli(); //禁止所有中断
TCCR1A = 0x00;
TCCR1B = 0x00;
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;//输入捕捉匹配值
TCCR1A = 0x00;
TCCR1B = 0x81;//启动定时器
SREG=sreg;
vvvv=0;
data0=0;
bitcnt=0;
}
}
int main( void )
{
DelayMs(100);
cli(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
TCCR1B=0x00;
PORTB=0B00000000; //PB0(ICP)上拉使能
DDRB =0B00000000; //定义输入
PORTC =0B00000000; //定义输入
DDRC =0B00000000; //PC4上拉使能
PORTD =0B00000100;
DDRD =0B00000010;
TCCR1B|=0xC2;//上升沿,1/8分频
TIMSK|=0X24;//定时器,和扑获中断
UCSRB = 0x00;//禁止中断
UCSRA = 0x00;
UCSRC = _BV(URSEL) | 0x36;
UBRRL = 0x05;
UBRRH = 0x00;
UCSRB = _BV(TXEN);//接收使能、发送使能、(调试用)
sei();//开全局中断
while(1)
{
asm("nop");
}
} |
|