历史上的今天
返回首页

历史上的今天

今天是:2025年02月01日(星期六)

2018年02月01日 | STC单片机解码HT6121/6122遥控器

2018-02-01 来源:eefocus

/*************    功能说明    ************** 

红外接收程序。适用于市场上用量最大的HT6121/6122及其兼容IC的编码。 

对于用户码与User_code定义不同的遥控器,程序会将用户码一起从串口输出。 

使用模拟串口发送监控显示编码,显示内容为ASCII码和中文。 

 

本接收程序基于状态机的方式,占用CPU的时间非常少。 

******************************************/ 


/*************    用户系统配置    **************/ 

#define MAIN_Fosc        12000000L    //定义主时钟, 模拟串口和红外接收会自动适应。5~36MHz 

#define D_TIMER0        125            //选择定时器时间, us, 红外接收要求在60us~250us之间 

#define    User_code        0xFD02        //定义红外接收用户码 


/*************    以下宏定义用户请勿修改    **************/ 
#include    "reg51.H" 
#define    uchar    unsigned char 
#define uint    unsigned int 

#define freq_base            (MAIN_Fosc / 1200) 
#define Timer0_Reload        (65536 - (D_TIMER0 * freq_base / 10000)) 




/*************    本地常量声明    **************/ 



/*************    本地变量声明    **************/ 
sbit    P_TXD1 = P3^1;        //定义模拟串口发送脚,打印信息用 
sbit    P_IR_RX = P0^1;        //定义红外接收输入端口 

bit        P_IR_RX_temp;        //Last sample 
bit        B_IR_Sync;            //已收到同步标志 
uchar    IR_SampleCnt;        //采样计数 
uchar    IR_BitCnt;            //编码位数 
uchar    IR_UserH;            //用户码(地址)高字节 
uchar    IR_UserL;            //用户码(地址)低字节 
uchar    IR_data;            //数据原码 
uchar    IR_DataShit;        //数据反码 

bit        B_IrUserErr;        //User code error flag 
bit        B_IR_Press;            //Key press flag,include repeat key. 
uchar    IR_code;            //IR code    红外键码 


/*************    本地函数声明    **************/ 
void    Tx1Send(uchar dat); 
uchar    HEX2ASCII(uchar dat); 
void    InitTimer(void); 
void    PrintString(unsigned char code *puts); 



/*************  外部函数和变量声明 *****************/ 



/********************* 主函数 *************************/ 
void main(void) 

    InitTimer();        //初始化Timer 
     
    PrintString("****** STC系列MCU红外接收程序 2010-12-10 ******\r\n");    //上电后串口发送一条提示信息 

    while(1) 
    { 
        if(B_IR_Press)        //有IR键按下 
        { 
            PrintString("红外码: 0x");            //提示红外键码 
            Tx1Send(HEX2ASCII(IR_code >> 4));    //键码高半字节 
            Tx1Send(HEX2ASCII(IR_code));        //键码低半字节 
            if(B_IrUserErr)                        //用户码错误,则发送用户码 
            { 
                Tx1Send(’ ’);                    //发空格 
                Tx1Send(’ ’);                    //发空格 
                PrintString("用户码: 0x");        //提示用户码 
                Tx1Send(HEX2ASCII(IR_UserH >> 4));    //用户码高字节的高半字节 
                Tx1Send(HEX2ASCII(IR_UserH));        //用户码高字节的低半字节 
                Tx1Send(HEX2ASCII(IR_UserL >> 4));    //用户码低字节的高半字节 
                Tx1Send(HEX2ASCII(IR_UserL));        //用户码低字节的低半字节 
            } 
            Tx1Send(0x0d);        //发回车 
            Tx1Send(0x0a);        //发回车 
            B_IR_Press = 0;        //清除IR键按下标志 
        } 
    } 



/********************* 十六进制转ASCII函数 *************************/ 
uchar    HEX2ASCII(uchar dat) 

    dat &= 0x0f; 
    if(dat <= 9)    return (dat + ’0’);    //数字0~9 
    return (dat - 10 + ’A’);            //字母A~F 





//******************************************************************* 
//*********************** IR Remote Module ************************** 

//*********************** IR Remote Module ************************** 
//this programme is used for Receive IR Remote (HT6121). 

//data format: Synchro,AddressH,AddressL,data,/data, (total 32 bit). 

//send a frame(85ms), pause 23ms, send synchro of another frame, pause 94ms 

//data rate: 108ms/Frame 


//Synchro:low=9ms,high=4.5/2.25ms,low=0.5626ms 
//Bit0:high=0.5626ms,low=0.5626ms 
//Bit1:high=1.6879ms,low=0.5626ms 
//frame sPACe = 23 ms or 96 ms 

/******************** 红外采样时间宏定义, 用户不要随意修改    *******************/ 

#if ((D_TIMER0 <= 250) && (D_TIMER0 >= 60)) 
    #define    D_IR_sample            D_TIMER0        //定义采样时间,在60us~250us之间 
#endif 

#define D_IR_SYNC_MAX        (15000/D_IR_sample)    //SYNC max time 
#define D_IR_SYNC_MIN        (9700 /D_IR_sample)    //SYNC min time 
#define D_IR_SYNC_DIVIDE    (12375/D_IR_sample)    //decide data 0 or 1 
#define D_IR_DATA_MAX        (3000 /D_IR_sample)    //data max time 
#define D_IR_DATA_MIN        (600  /D_IR_sample)    //data min time 
#define D_IR_DATA_DIVIDE    (1687 /D_IR_sample)    //decide data 0 or 1 
#define D_IR_BIT_NUMBER        32                    //bit number 

//******************************************************************************************* 
//**************************** IR RECEIVE MODULE ******************************************** 

void IR_RX_HT6121(void) 

    uchar    SampleTime; 

    IR_SampleCnt++;                            //Sample + 1 

    F0 = P_IR_RX_temp;                        //Save Last sample status 
    P_IR_RX_temp = P_IR_RX;                    //Read current status 
    if(F0 && !P_IR_RX_temp)                    //Last sample is high,and current sample is low, so is fall edge 
    { 
        SampleTime = IR_SampleCnt;            //get the sample time 
        IR_SampleCnt = 0;                    //Clear the sample counter 

             if(SampleTime > D_IR_SYNC_MAX)        B_IR_Sync = 0;    //large the Maxim SYNC time, then error 
        else if(SampleTime >= D_IR_SYNC_MIN)                    //SYNC 
        { 
            if(SampleTime >= D_IR_SYNC_DIVIDE) 
            { 
                B_IR_Sync = 1;                    //has received SYNC 
                IR_BitCnt = D_IR_BIT_NUMBER;    //Load bit number 
            } 
        } 
        else if(B_IR_Sync)                        //has received SYNC 
        { 
            if(SampleTime > D_IR_DATA_MAX)        B_IR_Sync=0;    //data samlpe time to large 
            else 
            { 
                IR_DataShit >>= 1;                    //data shift right 1 bit 
                if(SampleTime >= D_IR_DATA_DIVIDE)    IR_DataShit |= 0x80;    //devide data 0 or 1 
                if(--IR_BitCnt == 0)                //bit number is over? 
                { 
                    B_IR_Sync = 0;                    //Clear SYNC 
                    if(~IR_DataShit == IR_data)        //判断数据正反码 
                    { 
                        if((IR_UserH == (User_code / 256)) && 
                            IR_UserL == (User_code % 256)) 
                                B_IrUserErr = 0;    //User code is righe 
                        else    B_IrUserErr = 1;    //user code is wrong 
                             
                        IR_code      = IR_data; 
                        B_IR_Press   = 1;            //数据有效 
                    } 
                } 
                else if((IR_BitCnt & 7)== 0)        //one byte receive 
                { 
                    IR_UserL = IR_UserH;            //Save the User code high byte 
                    IR_UserH = IR_data;                //Save the User code low byte 
                    IR_data  = IR_DataShit;            //Save the IR data byte 
                } 
            } 
        } 
    } 



/**************** Timer初始化函数 ******************************/ 
void InitTimer(void) 

    TMOD = 0;        //for STC15Fxxx系列    Timer0 as 16bit reload timer. 
    TH0 = Timer0_Reload / 256; 
    TL0 = Timer0_Reload % 256; 
    ET0 = 1; 
    TR0 = 1; 

    EA  = 1; 



/********************** Timer0中断函数************************/ 
void timer0 (void) interrupt 1 

    IR_RX_HT6121(); 



/********************** 模拟串口相关函数************************/ 

void    BitTime(void)    //位时间函数 

    uint i; 
    i = ((MAIN_Fosc / 100) * 104) / 140000 - 1;        //根据主时钟来计算位时间 
    while(--i); 


//模拟串口发送 
void    Tx1Send(uchar dat)        //9600,N,8,1        发送一个字节 

    uchar    i; 
    EA = 0; 
    P_TXD1 = 0; 
    BitTime(); 
    for(i=0; i<8; i++) 
    { 
        if(dat & 1)        P_TXD1 = 1; 
        else            P_TXD1 = 0; 
        dat >>= 1; 
        BitTime(); 
    } 
    P_TXD1 = 1; 
    EA = 1; 
    BitTime(); 
    BitTime(); 


void PrintString(unsigned char code *puts)        //发送一串字符串 

    for (; *puts != 0;    puts++)  Tx1Send(*puts);     //遇到停止符0结束 


推荐阅读

史海拾趣

中科银河芯(GXCAS)公司的发展小趣事
输入信号的电压范围决定了三极管何时截止、何时饱和导通。
德崧电子(D-SWITCH)公司的发展小趣事

在激烈的市场竞争中,德崧电子始终坚持品质为先的经营理念。公司从原材料采购到生产加工,再到成品检验,每一个环节都严格把控,确保产品质量。这种对品质的坚守不仅赢得了客户的信任,也为公司赢得了良好的口碑。正是凭借着过硬的产品质量和优质的服务,德崧电子在电子开关行业中树立了良好的品牌形象。

Ametek公司的发展小趣事

在激烈的市场竞争中,德崧电子始终坚持品质为先的经营理念。公司从原材料采购到生产加工,再到成品检验,每一个环节都严格把控,确保产品质量。这种对品质的坚守不仅赢得了客户的信任,也为公司赢得了良好的口碑。正是凭借着过硬的产品质量和优质的服务,德崧电子在电子开关行业中树立了良好的品牌形象。

Gamma Microelectronics ( APM )公司的发展小趣事

G24i的成立可以追溯到2006年,它自称是世界上首家生产商业化应用等级DSSC的公司。公司的技术根基源自瑞士洛桑联邦理工学院的M. Gratzel团队,该团队是DSSC技术的先驱。G24i由美国Kanorka Technologies公司投资,而Kanorka则得到了美国军方的资助。这一强大的技术背景为G24i的商业化之路奠定了坚实的基础。公司成立后不久,便致力于将实验室级别的DSSC技术推向市场,开启了其商业化探索的征程。

AK-Nord_GmbH公司的发展小趣事

AK-Nord_GmbH深知人才是企业发展的核心。因此,公司注重人才培养和团队建设。公司定期举办内部培训和交流活动,提升员工的专业技能和团队协作能力。同时,公司还积极引进外部优秀人才,为公司的创新发展注入新的活力。这些举措使得AK-Nord_GmbH的团队逐渐壮大,为公司的发展提供了有力的人才保障。

Avel Lindberg公司的发展小趣事

为了确保产品质量和客户满意度,AK-Nord_GmbH投入大量资源建设质量管理体系。公司引入了国际先进的质量管理标准和流程,对产品的研发、生产、测试等各个环节进行严格把控。同时,公司还建立了完善的客户服务体系,及时响应客户需求和处理问题。这些举措有效提升了公司的产品质量和客户满意度,为公司赢得了良好的口碑。

问答坊 | AI 解惑

dsp入门需要注意的事项

在作硬件之前,需要看的资料有: 1.芯片数据手册,描述该器件的引脚信号、片上资源、电气指标和机械特性(如封装等),在做硬件前必看(TMS320F281x数据手册SPRS174J) 2.某一系列DSP的CPU和指令集用户指南,描述该系列DSP的CPU结构、内部寄存器 ...…

查看全部问答>

求项目课题

刚刚学习了单片机知识,想要做个项目实践一下,请高手提供一下初学者适宜的课题,谢谢!…

查看全部问答>

求计算机体系结构:定量研究方法(第3版)答案

就是那个Paterson和Henessy的CA:AQA,给我份答案,谢谢。我在网上找不到。 …

查看全部问答>

EE_FPGA零起点入门教程(8月23日已更新)

EE_FPGA V2.0原理图 https://bbs.eeworld.com.cn/thread-299838-1-1.html   EE_FPGA学习板系列https://bbs.eeworld.com.cn/thread-286584-1-1.html EE_FPGA 2.0之【焊接宝典】 最终版https://bbs.eeworld.com.cn/thread-231149-1-1.html ...…

查看全部问答>

各位大牛帮我想一下这个方案吧

本帖最后由 paulhyde 于 2014-9-15 03:33 编辑 最近在参加沈阳市机器人大赛,有个问题一直没解决:机器人识别铁片问题,铁片是银白色的,直径6CM,机器人离铁片有80cm左右,铁片放在白纸上面,之前用过摄像头,但是颜色区别比较小基本识别不了,也 ...…

查看全部问答>

圆点博士四轴飞行器电路图规划

2012-10-26: 四轴飞行器线路图规划: 上面详述了四轴飞行器所用的各传感器资料,下面开始线路图规划。1)         四轴飞行器总指挥:STM32是首选,资料多,容易买。用STM32F103就差不多了 。2)     ...…

查看全部问答>

大家都是在淘宝哪一家店买的材料呀

大家都是在淘宝哪一家店买的材料呀,能便宜点的学生党真的没有多少钱…

查看全部问答>