搜索
bottom↓
回复: 8

终于将我的电视机遥控器的码给解了!

[复制链接]

出0入0汤圆

发表于 2009-3-4 21:43:03 | 显示全部楼层 |阅读模式
时间测量法解码遥控器。
//main.c
//ICC-AVR application builder : 2009-2-27 10:31:21
// Target : M16
// Crystal: 7.3728Mhz

#include <iom16v.h>
#include <macros.h>
#include  "ext_fuc.h"
#include "rm_hs0038.h"
#include "rm_hs0038.c"

#define  datalen  50

int timeout=5,count;// 程序超时
unsigned char exitflag=0;
unsigned char timeoutflag=1;
unsigned int hlevel[datalen],llevel[datalen],gtime[datalen];
void port_init(void)
{
    PORTA = 0x00;
    DDRA  = 0x00;
    PORTB = 0xff;
    DDRB  = 0xff;
    PORTC = 0x00; //m103 output only
    DDRC  = 0xff;
    PORTD = 0x00;
    DDRD  = 0xff;
}

//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
    CLI(); //disable all interrupts
    port_init();
    timer0_init();
    timer1_init();
    MCUCR = 0x00;
    GICR  = 0x00;
    TIMSK = 0x00; //timer interrupt sources
    SEI(); //re-enable interrupts
//all peripherals are now initialized
}

void BEP(int sec)
{
    int i;
    for (i=0;i<sec*1000;i++)
    {
        Delayus(500);
        NOT_BIT(PORTC,PC0);
    }
}
//***************************************
void stoptimer1()
{
          TCCR1A=0x00;
    TCCR1B = 0x00;
}

starttimer1()
{
    TCNT1H=0x00;
        TCNT1L=0x00;
    TCCR1A=0x00;
    TCCR1B = 0x02;
}

gettimelen(unsigned int *Data )
{
    char tmph,tmpl;
    int tr;
        /*
    tmph=TCNT1H;

    tmpl=TCNT1L;
    tr=tmph;
    tr=tr<<8;
    tr=tr|tmpl;
        */
        tr=TCNT1;
    *Data=tr;
       
       
return;
}

void DataParse()
{
    int i=0;
       
    for (i=0;i<datalen;i++)
    {
        hlevel=(hlevel/10)*11;
        
            }
               
                       
        return;

}//红外数据处理分析

void DataParse1()
{
    int i=0;
       
    for (i=0;i<datalen;i++)
    {
        llevel=(llevel/10)*11;
        
            }
               
                       
        return;

}

void ErrorDisplay()
{
}       
void DataDisplay()
{
}//结果显示
void initdim(unsigned int *dim,unsigned int len)
{
    int i;
    unsigned int *tmp;
    tmp=dim;
    for (i=0;i<len;i++)
    {
        *tmp=0;
        tmp++;
    }
        return;
}
//***************************************

void timer1_init(void)
{
    TCCR1B = 0x00; //stop
    TCNT1H = 0x00; //setup
    TCNT1L = 0x00;
    OCR1AH = 0x00;
    OCR1AL = 0x51;
    OCR1BH = 0x00;
    OCR1BL = 0x51;
    ICR1H  = 0x00;
    ICR1L  = 0x51;
    TCCR1A = 0x00;
    //TCCR1B = 0x01; //start Timer
}

//***************************************
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1000Hz
// actual value: 1001.739Hz (0.2%)
void timer0_init(void)
{
    TCCR0 = 0x00; //stop
    TCNT0 = 0x8D; //set count
    OCR0  = 0x73;  //set compare
    TCCR0 = 0x03; //start timer
}

#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
    if (count>=timeout*1000)
    {
        count=0;
        TCCR0=0x00;
        timeoutflag=1;
        exitflag=1;

        TIMSK=0x00;
    }
    count++;
    TCNT0 = 0x8D; //reload counter value
}

//***************************************
void main(void)
{
    uchar tmp;
    unsigned char firstrunflag=1,initflag;
    int i;

    init_devices();

    CLR_BIT(PORTB,PB0);
//SET_BIT(PORTD,PD7);
    while (1)
    {   
            init7461();
        initdim(hlevel,datalen);
        initdim(llevel,datalen);
        timeoutflag=0;//超时标志复位
        exitflag=0;
        initflag=0;
        firstrunflag=1;
        timer0_init();
        timer1_init();
        TIMSK = 0x01;
        
         
        for (i=0;i<datalen;i++)
        {
                         detectdownpulse(&exitflag);//捕捉下降升沿
            //detectrisepulse(&exitflag);//捕捉上升沿
            if (timeoutflag) goto timeouted;
            NOT_BIT(PORTB,PB6);//指示灯
            if (!firstrunflag)
            {
                stoptimer1();//停计时器
                gettimelen(&llevel[i-1]);//取高电平持续时间(原始编码),实际输出波形为原始编码的反码
            }
            firstrunflag=0;//首次运行标志
            starttimer1();//启动计时器
                       
                        detectrisepulse(&exitflag);//捕捉上升沿
            if (timeoutflag) goto timeouted;
            NOT_BIT(PORTB,PB7);//指示灯
            stoptimer1();//停计时器
            gettimelen(&hlevel);//取低电平持续时间(原始编码),实际输出波形为原始编码的反码
            starttimer1();//启动计时器
        }
timeouted:
        if (timeoutflag!=1)
        {
            DataParse();//红外数据处理分析
                        DataParse1();
                        DeCode(hlevel,llevel);
            if (LC7461.decode_error) {ErrorDisplay();}//结果显示
                        else {DataDisplay();}//解码结果在LC7461.usercode里面
            tmp=GET_BIT(PINA,PA7);
            PORTB=Set_Value(PORTB,PB0,tmp);
        }

    }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2009-3-4 21:44:15 | 显示全部楼层
//EXT_FUC.h

#define uchar unsigned char
#define uint unsigned int
#define SET_BIT(io,bit) ( io |= (1<<bit) ) //example: SET_BIT
#define CLR_BIT(io,bit) ( io &= ~(1<<bit) ) //example: CLR_BIT
#define NOT_BIT(io ,bit) (io ^=   (1<<bit)); //example: NOT_BIT
#define GET_BIT(io ,bit) ( (io & (1<<bit))>>bit ) //example: GET_BIT
int Led_Shift=0;

void Delayus(uint US)
{
    uint i;
    US=US*5/4;                           //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
    for ( i=0;i<US;i++);
}

//精确定义毫秒
void Delayms(uint MS)
{
    uint i,j;
    for ( i=0;i<MS;i++)
        for (j=0;j<1141;j++);        //1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}

//定义函数,设置寄存器某一位的值,返回修改后的寄存器的值
uchar Set_Value(uchar Byte_Data,uchar Bit_Num,uchar Value)
{

    if (Value==1)
    {
        SET_BIT(Byte_Data,Bit_Num);
    }

    if (Value==0)
    {
        CLR_BIT(Byte_Data,Bit_Num);
    }
    return Byte_Data;
}

uint DtRisePulse(volatile uchar *ByteVal,unsigned char BitVal,unsigned char *exitflag)//检测某字节某位0-1的变化,第一个参数为地址类型
{
char tmp;
//while ((tmp=GET_BIT(*ByteVal,BitVal))==1)
//{if (*exitflag==1) return 0;}

while ((tmp=GET_BIT(*ByteVal,BitVal))==0)
{if (*exitflag==1) return 0;}

return 1;
}

uint DtDownPulse(volatile uchar *ByteVal,unsigned char BitVal,unsigned char *exitflag)//检测某字节某位1-0的变化,第一个参数为地址类型
{
char tmp;
//while ((tmp=GET_BIT(*ByteVal,BitVal))==0)
//{if (*exitflag==1) return 0;}

while ((tmp=GET_BIT(*ByteVal,BitVal))==1)
{if (*exitflag==1) return 0;}

return 1;
}

出0入0汤圆

 楼主| 发表于 2009-3-4 21:45:45 | 显示全部楼层
//rm_hs0038.h
#define ControllPort  PINA
#define ControllPin   PA7
#define sint  unsigned char
sint detectrisepulse(unsigned char *exitflag);
sint detectdownpulse(unsigned char *exitflag);
unsigned char nearby(int compin,int compin1,int weakvalue);
void init7461();
struct rm_scode {
const char *p;//码型注释
unsigned int QDH;//前导码高电平持续时间
unsigned int QDL;//前导码低电平持续时间
unsigned int HI;//码1的持续时间
unsigned int LI;//码0的持续时间
int usercode;//用户码
unsigned char datacode;//数据码
int usercode_not;//用户码反码
unsigned char datacode_not;//数据码反码
int decode_error;//解码错误标志
}LC7461;

出0入0汤圆

 楼主| 发表于 2009-3-4 21:47:55 | 显示全部楼层
//rm_hs0038.c
sint detectrisepulse(unsigned char *exitflag)
{
char tmp;
tmp=DtRisePulse(&ControllPort,ControllPin,exitflag);
return tmp;
}
sint detectdownpulse(unsigned char *exitflag)
{
char tmp;
tmp=DtDownPulse(&ControllPort,ControllPin,exitflag);
return tmp;
}


void init7461()
{
LC7461.p="LC7461";
LC7461.QDH=9000;
LC7461.QDL=4500;
LC7461.HI=2250;
LC7461.LI=1250;
LC7461.usercode=0;
LC7461.datacode=0;
LC7461.usercode_not=0;
LC7461.datacode_not=0;
LC7461.decode_error=0;
}

unsigned char nearby(int compin,int compin1,int weakvalue)
{
if ((compin-compin1)>=0)
{
if ((compin-compin1)<=weakvalue) return 1;
}
else
{
if ((-(compin-compin1))<=weakvalue) return 1;
}
return 0;
}

//检查前导码,判断前导码类型 参数一:高电平持续时间  参数二:低电平持续时间
int CheckQD(unsigned int HLevel,unsigned int LLevel)
{
unsigned char tmp,tmp1;
tmp=nearby(LC7461.QDH,HLevel,500);
tmp1=nearby(LC7461.QDL,LLevel,500);
if (tmp&&tmp1) return 1;
//这儿加其他前导码型
return 0;
}


//解码,参数一:截获的高电平时间数据  参数二:截获的低电平时间数据
void DeCode(unsigned int *HData,unsigned int *LData)
{
int i,da,codetmp=0x0;
unsigned int *tmp,*tmp1,*tmp2,*tmp3;
tmp=HData;
tmp1=LData;


switch (CheckQD(*tmp,*tmp1)){
case 1:
//解用户码
tmp++;
tmp1++;
for (i=0;i<13;i++)
{
da=DataTran(*tmp,*tmp1);
if (da==-1)
{
break;
}
codetmp|=da;
codetmp=codetmp<<1;
tmp++;
tmp1++;
}
codetmp=codetmp>>1;
LC7461.usercode=codetmp;

//解用户反码
for (i=0;i<13;i++)
{
da=DataTran(*tmp,*tmp1);
if (da==-1)
{
break;
}
LC7461.usercode_not|=da;
LC7461.usercode_not<<=1;
tmp++;
tmp1++;
}
LC7461.usercode_not>>=1;

if ((LC7461.usercode^LC7461.usercode_not)!=0x1fff)
{
LC7461.decode_error=1;
break;
}

//解数据
codetmp=0x0;
for (i=0;i<8;i++)
{
da=DataTran(*tmp,*tmp1);
if (da==-1)
{
break;
}
codetmp|=da;
codetmp<<=1;
tmp++;
tmp1++;
}
codetmp>>=1;
LC7461.datacode=codetmp;


//解数据反码
codetmp=0x0;
for (i=0;i<8;i++)
{
da=DataTran(*tmp,*tmp1);
if (da==-1)
{
break;

}
codetmp|=da;
codetmp<<=1;
tmp++;
tmp1++;
}
codetmp>>=1;
LC7461.datacode_not=codetmp;

if ((LC7461.datacode^LC7461.datacode_not)!=0xff)
{
LC7461.decode_error=1;
break;
}
//
//
break;
default:
return;
}
return;
}

int  DataTran(int hd,int ld)
{
int tmp;
tmp=hd+ld;
if (nearby(tmp,LC7461.HI,200)) return 1;
if (nearby(tmp,LC7461.LI,200)) return 0;
return -1;

}

出0入0汤圆

 楼主| 发表于 2009-3-4 21:49:21 | 显示全部楼层
遥控接收头接在PORTA     PA7引脚上。

出0入0汤圆

发表于 2009-3-4 23:43:55 | 显示全部楼层
这么长的程序???你用的是什么样的遥控器哦?要这么复杂的解码程序?我的遥控器好像没有多长的程序就搞定拉,还是用汇编写的。我的遥控器是SAA3010芯片,很好读编码

出0入0汤圆

发表于 2009-3-5 08:44:31 | 显示全部楼层
早就搞定过了

出0入0汤圆

 楼主| 发表于 2009-3-5 09:10:15 | 显示全部楼层
这个可以改造成通用程序,不占用ICP引脚。

出0入0汤圆

发表于 2009-3-5 20:59:16 | 显示全部楼层
够长了,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 20:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表