[应用方案] 基于新唐MINI51的红外接收解码方案

[复制链接]
4942|18
 楼主| 缥缈九哥 发表于 2014-8-21 22:43 | 显示全部楼层 |阅读模式
本帖最后由 缥缈九哥 于 2014-8-21 23:25 编辑

/******************************************************************************
* @file     ir.c
* @brief    The Driver code for VS1838A with MINI54FDE
* @version  1.0.0
* @date     22, August, 2014
*
* @note
* Copyright (C) 2000-2014 PM9GZY by yuanxihua@21cn.com. All rights reserved.
******************************************************************************/
#include <stdio.h>
#include "Mini51Series.h"
/*
    红外线编码是数据传输和家用电器遥控常用的一种通讯方法,
其实质是一种脉宽调制的串行通讯。
    家电遥控中常用的红外线编码电路有μPD6121G型HT622型和7461型等。
μPD6121G遥控器的红外遥控系统的编码格式
    二进制“0”由0.56ms的间隔加0.565ms的脉冲表示;
    二进制“1”由0.56ms的间隔加1.685ms的脉冲表示。
每次发送的32位二进制码可分成两部分,其中
        前16位是遥控器辨识码,主要用于区别不同遥控器,
        后16位是操作码。这两个部分的后8位都是前8位的反码,用作数据校验。
每帧数据以9ms的间隔加4.5ms的脉冲作为数据头header信号。
    当键盘按下长达108ms时,发射端开始发送连续信号,与单次发送一样,
只是数据头header信号是由9ms的间隔加2.5ms的脉冲组成的。
*/
/*
_________________________________________________
|        MINI54FDE                                                LED                        |
|                                                                                                |
|        P25                                        <---                VS1838A                |
|        P24                                        --->                RED-LED                |
|_______________________________________________|
*/
#pragma anon_unions
#define TIME_INTERRUPT_PERIOD_US        128                //定时中断时间,用于计算下降沿到下降沿之间时间,也就是一个脉冲+间隙的时间
#define TIME_INFRARED_HEAD_US                13500        //数据头的时间:TH=9+4.5=13.5ms
#define TIME_INFRARED_REPEAT_US                11500        //当键盘按下长达108ms时,发送连续信号的数据头的时间:TH=9+2.5=11.5ms
#define TIME_INFRARED_ZERO_US                1125        //数据“0”的时间:T0=0.565+0.56=1.125ms
#define TIME_INFRARED_ONE_US                2245        //数据“1”的时间:T1=1.685+0.56=2.245ms

typedef enum  {IDLE=1,HEAD,DATA} irstatus_t;
typedef union {uint32_t data;struct {uint8_t data0;uint8_t data1;uint16_t address;};}irdata_t;
irdata_t ir;
uint32_t irticks=0,ircount=0,ledcount=0;
irstatus_t irwork=IDLE;
uint8_t disp_flag=0;
// The Timer1 default IRQ, declared in startup_Mini51.s.
void TMR1_IRQHandler(void)
{
        irticks++;ledcount++;
        TIMER_ClearIntFlag(TIMER1);
}
// The Port2/Port3/Port4 default IRQ, declared in startup_Mini51.s.
void GPIO234_IRQHandler(void)
{
        uint8_t irdata;

    if (P2->ISRC & BIT5)
    {    /* To check if P2.5 interrupt occurred */
                switch(irwork)
                {
                        case IDLE: irwork=HEAD;
                                break;
                        case HEAD: irwork=(irticks>((TIME_INFRARED_HEAD_US+TIME_INFRARED_REPEAT_US)/2)/TIME_INTERRUPT_PERIOD_US)?DATA:IDLE;
                                ir.data=0;ircount=0;
                                break;
                        case DATA: irdata=(irticks>((TIME_INFRARED_ZERO_US+TIME_INFRARED_ONE_US   )/2)/TIME_INTERRUPT_PERIOD_US)?1:0;
                                ir.data<<=1;ir.data|=irdata;ircount++;
                                if(ircount>=32){irwork=IDLE;disp_flag=1;}
                                break;
                }       
                irticks=0;        P2->ISRC = BIT5;
    }else
    {   /* Un-expected interrupt. Just clear all PORT2, PORT3 and PORT4 interrupts */
        P2->ISRC = P2->ISRC;        P3->ISRC = P3->ISRC;        P4->ISRC = P4->ISRC;
        printf("Un-expected interrupts. \n\r");
    }
}
void IR_test(void)
{
    /*Configure P24 for LED control */
    GPIO_SetMode(P2, BIT4, GPIO_PMD_OUTPUT);
       
        /*  Configure P2.5 as Quasi-bidirection mode and enable interrupt by falling edge trigger */
    GPIO_SetMode(P2, BIT5, GPIO_PMD_QUASI);
    GPIO_EnableInt(P2, 5, GPIO_INT_FALLING);
    NVIC_EnableIRQ(GPIO234_IRQn);
       
        // Enable IP clock
        CLK_EnableModuleClock(TMR1_MODULE);       
    // Select Timer 1 clock source from internal 22.1184MHz RC clock.
        CLK_SetModuleClock(TMR1_MODULE,CLK_CLKSEL1_TMR1_S_IRC22M,1);
        // configure timer to operate in specified mode.
        TIMER_Open(TIMER1, TIMER_PERIODIC_MODE, 7812);        //7.8125K = 0.128MS = 128US
        // start Timer counting
        TIMER_Start(TIMER1);
        // enable the Timer time-out interrupt function.
        TIMER_EnableInt(TIMER1);
    // Enable timer interrupt
    NVIC_EnableIRQ(TMR1_IRQn);
       
        while(1)
        {
                if(disp_flag)
                {
                        printf("ir.data=0x%x, ADDR=%04x DATA1=%02x /DATA1=%02x DATA0=%02x \n\r",
                                        ir.data,ir.address,ir.data1,0xff-ir.data1,ir.data0);
                        if((0xff-ir.data0)==ir.data1){P24^=1;}
                        disp_flag=0;
                }
        }
}

   
 楼主| 缥缈九哥 发表于 2014-8-21 22:45 | 显示全部楼层
顶起。哈哈
longmanwzw 发表于 2014-8-21 22:51 | 显示全部楼层
9哥帖子,必须顶起~~~
 楼主| 缥缈九哥 发表于 2014-8-21 22:51 | 显示全部楼层
抛块砖头,希望能引出玉。请兄弟们指正。
Harvard 发表于 2014-8-21 22:52 | 显示全部楼层
帮顶. 想问下机顶盒的遥控器上是如何实现可以接收 发送的 .是不是有2个红外管.还是????
zzm19900 发表于 2014-8-22 09:25 | 显示全部楼层
九哥的帖子果断顶起!建议九哥把整个工程文件分享一下,方便收藏。
wjsjdeng 发表于 2014-8-22 09:30 | 显示全部楼层
9g的顶起,
机顶盒的遥控器是有学习功能的..但没有红外接收头..
wjsjdeng 发表于 2014-8-22 09:33 | 显示全部楼层
红外学习电路?望大牛分析下.
红外发射管学习红外原理图.jpg
从小木丁丁 发表于 2014-8-22 13:45 来自手机 | 显示全部楼层
九哥的帖子都是神贴啊
haolaishi 发表于 2014-8-23 21:43 | 显示全部楼层
支持下九哥
lee9888 发表于 2015-2-16 11:56 | 显示全部楼层
好,谢谢,原来用的不是好好,这个试
598330983 发表于 2015-2-16 21:24 来自手机 | 显示全部楼层
学习电路肯定是软件层面的
ccw1986 发表于 2015-3-27 08:14 | 显示全部楼层
先生贴的代码肯定很有针对性
谢谢
顶起
 楼主| 缥缈九哥 发表于 2016-4-19 21:08 | 显示全部楼层
顶起呀。
拙见成章 发表于 2016-4-27 00:05 | 显示全部楼层
这个值#define TIME_INTERRUPT_PERIOD_US        128                //定时中断时间,用于计算下降沿到下降沿之间时间,也就是一个脉冲+间隙的时间
怎么计算出来的
feezai1 发表于 2016-5-2 21:34 | 显示全部楼层
MINI51的红外接收解码方案,好资料,收藏了,多谢9哥
cnb12345 发表于 2016-5-3 10:32 | 显示全部楼层
QQ715209572 发表于 2016-5-5 09:37 | 显示全部楼层
9哥的帖子一直都是神贴
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:童时不懂世事艰,笑谈学成锦衣还。岁月无声已先过,男儿有泪空自弹。    莫待沾霜愁上发,须嬴吐气喜开颜。拼搏半年誓如愿,不到长城心不甘。

67

主题

1868

帖子

271

粉丝
快速回复 在线客服 返回列表 返回顶部