打印
[IoT技术交流]

M051学习笔记--红外遥控器实验

[复制链接]
1316|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
原贴链接:http://www.openedv.com/forum.php?mod=viewthread&tid=67


M051学习笔记--红外遥控器实验

本实验移植自Alientek STM32 Mini 开发板的空外遥控实验!!!
   


remote.h
---------------------------------------------------------------------------------
#ifndef __RED_H
#define __RED_H
#include "Driver/DrvGPIO.h"
#define RDATA  DrvGPIO_GetBit(E_PORT3,E_PIN2) //EINT0 PIN
//红外遥控识别码(ID),每款遥控器的该值基本都不一样,但也有一样的.
//我们选用的遥控器识别码为0
#define REMOTE_ID 0      

extern uint8_t Remote_Cnt;    //按键次数,此次按下键的次数
extern uint8_t Remote_Rdy;    //红外接收到数据
extern uint32_t Remote_Odr;   //命令暂存处
void Remote_Init(void);    //红外传感器接收头引脚初始化
uint8_t Remote_Process(void);   //红外接收到数据处理
uint8_t Pulse_Width_Check(void);//检查脉宽         
#endif


remote.c
-----------------------------------------------------------------------
#include "remote.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#include "DrvUART.h"
            
uint32_t Remote_Odr=0;       //命令暂存处
uint8_t  Remote_Cnt=0;    //按键次数,此次按下键的次数
uint8_t  Remote_Rdy=0;    //红外接收到数据   

void INT_Callback_Function(void);
void Remote_Init(void)
{                             
    //采用EINT0的输入
     DrvGPIO_Open(E_PORT3,E_PIN2,E_IO_INPUT);
     DrvGPIO_InitFunction(E_FUNC_EXTINT0);
     DrvGPIO_EnableEINT(E_EINT0_PIN,E_IO_FALLING,E_MODE_EDGE,(EINT_CALLBACK)INT_Callback_Function); //E_EINT0_PIN P3.2
}   
//检测脉冲宽度
//最长脉宽为5ms
//返回值:x,代表脉宽为x*50us(x=1~100);
uint8_t Pulse_Width_Check(void)
{
    uint8_t t=0;     
    while(RDATA)
    {     
        t++;
        //最小延时为26us,实际延时为x+26us,在12M 下面
        DrvSYS_Delay(24); //50us 26us起始误差                     
        if(t==100)return t; //超时溢出
    }
    return t;
}               
//处理红外接收  
/*-------------------------协议--------------------------
开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了
接着是发送4个8位二进制码,第一二个是遥控识别码(REMOTE_ID),第一个为
正码(0),第二个为反码(255),接着两个数据是键值,第一个为正码
第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲,
表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可
以认为是持续按下该键.
---------------------------------------------------------*/         
//外部中断服务程序      
void INT_Callback_Function(void)
{      
    uint8_t res=0;
    uint8_t OK=0;
    uint8_t RODATA=0;           
    while(1)
    {        
        if(RDATA)//有高脉冲出现
        {
            res=Pulse_Width_Check();//获得此次高脉冲宽度     
            if(res==100)break;//非有用信号 >5ms
            if(res>=80&&res<100)OK=1; //获得前导位(4.5ms)
            else if(res>=35&&res<80)  //按键次数加一(2ms)
            {                                          
                Remote_Rdy=1;//接受到数据
                Remote_Cnt++;//按键次数增加
                break;
            }
            else if(res>=20&&res<35)RODATA=1;//1.5ms
            else if(res>=4&&res<20)RODATA=0;//500us
            if(OK)
            {
                Remote_Odr<<=1;
                Remote_Odr+=RODATA;
                Remote_Cnt=0; //按键次数清零
            }   
        }                                      
    }                  
}  
//处理红外键盘
//返回相应的键值
uint8_t Remote_Process(void)
{               
    uint8_t t1,t2;   
    t1=Remote_Odr>>24; //红外解码
    t2=(Remote_Odr>>16)&0xff;
     Remote_Rdy=0;//清除标记               
    if(t1==(uint8_t)~t2&&t1==REMOTE_ID)//检验遥控识别码(ID)
    {
        t1=Remote_Odr>>8;
        t2=Remote_Odr;     
        if(t1==(uint8_t)~t2)return t1; //处理键值  
    }     
    return 0;
}


Test.c
-------------------------------------------------------------------------------------
#include <stdio.h>

---------------------------------------------------------------------------------------------------------*/

#include "Driver/DrvTIMER.h"
#include "Driver/DrvGPIO.h"
#include "Driver/DrvSYS.h"
#include "Driver/DrvUART.h"
#include "remote.h"

int TestRemoteOK (void)
{    uint8_t key;
  
    STR_UART_T param;


    /* Unlock the locked registers before access */
      UNLOCKREG(x);

    /* Enable the 12MHz oscillator oscillation */
    DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);

    /* Waiting for 12M Xtal stable */
    while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);
   
    /* HCLK clock source. 0: external 12MHz; 4:internal 22MHz RC oscillator */
    DrvSYS_SelectHCLKSource(0);

    DrvSYS_SetClockDivider(E_SYS_HCLK_DIV, 0); /* HCLK clock frequency = HCLK clock source / (HCLK_N + 1) */

    DrvGPIO_InitFunction(E_FUNC_UART0);
   
    /* Select UART Clock Source From 12MHz */
    DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC,0);
   
    param.u32BaudRate        = 57600;
    param.u8cDataBits        = DRVUART_DATABITS_8;
    param.u8cStopBits        = DRVUART_STOPBITS_1;
    param.u8cParity          = DRVUART_PARITY_NONE;
    param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;
    param.u8TimeOut             = 0;
    DrvUART_Open(UART_PORT0, &param);

     Remote_Init();        //初始化红外接收

    while(1)
    {      
        if(Remote_Rdy)
        {   
        
            key=Remote_Process();
            
            switch(key)
            {
                case 0:
                 
                    break;
                case 162:
                    printf("Power\n");
                    break;
                case 98:
                    printf("VOL+\n");
                    break;
                case 2:
                    printf("VOL-\n");
                    break;
                case 226:
                    printf("CH+\n");
                    break;
                case 194:
                    printf("CH-\n");
                    break;
                case 34:
                    printf("RECALL\n");
                    break;
                case 56:
                    printf("0\n");
                    break;
                case 224:
                    printf("1\n");
                    break;
                case 168:
                    printf("2\n");
                    break;
                case 144:
                    printf("3\n");
                    break;
                case 104:
                    printf("4\n");
                    break;
                case 152:
                    printf("5\n");
                    break;
                case 176:
                    printf("6\n");
                    break;
                case 48:
                    printf("7\n");
                    break;
                case 24:
                    printf("8\n");
                    break;
                case 122:
                    printf("9\n");
                    break;
                case 16:
                    printf("10\n");
                    break;
                case 90:
                    printf("11\n");
                    break;
                case 66:
                    printf("12\n");
                    break;
                case 82:
                    printf("13\n");
                    break;
            }
        }else DrvSYS_Delay(10000);

    }
}

使用特权

评论回复
评论
LED2013 2019-3-30 21:36 回复TA
如果有个图片或者视频小实验就好了 
沙发
xinpian101| | 2019-3-27 19:16 | 只看该作者
多谢分享,极具参考价值。

使用特权

评论回复
板凳
wahahaheihei| | 2019-3-27 19:27 | 只看该作者
要学习红外的原理。

使用特权

评论回复
地板
wanduzi| | 2019-3-28 09:47 | 只看该作者
学习一下红外原理。

使用特权

评论回复
5
捉虫天师| | 2019-3-29 12:55 | 只看该作者
有个贴是介绍原理的。

使用特权

评论回复
6
huahuagg| | 2019-3-29 23:44 | 只看该作者
懂原来就非常容易提高了。

使用特权

评论回复
7
jiekou001| | 2019-3-30 16:49 | 只看该作者
这是啥意思,直接串口就可以?

使用特权

评论回复
8
QFGL| | 2019-11-18 08:54 | 只看该作者
有个问题,您这个脉宽检测的时候,最大也不会检测到9毫秒呀!uint8_t Pulse_Width_Check(void),这个API,这样写的意义是什么?

使用特权

评论回复
9
zhuotuzi| | 2019-11-18 23:57 | 只看该作者
有点奇怪,没看明白

使用特权

评论回复
10
xuanhuanzi| | 2019-11-29 13:12 | 只看该作者
确实难以理解,我脑子不够了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

41

帖子

0

粉丝