OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 32416|回复: 0

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

[复制链接]

98

主题

408

帖子

3

精华

金牌会员

Rank: 6Rank: 6

积分
1280
金钱
1280
注册时间
2010-12-14
在线时间
0 小时
发表于 2010-12-16 00:34:22 | 显示全部楼层 |阅读模式
本实验移植自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);

    }
}


希望openedv能给大家提供一个友好的技术交流平台!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 13:55

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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