打印

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

[复制链接]
5696|37
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 zhangyang86 于 2010-11-28 22:48 编辑

本实验移植自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);

    }
}

相关帖子

沙发
hsbjb| | 2010-11-25 16:52 | 只看该作者
只给程序似乎不能算笔记

使用特权

评论回复
板凳
xsgy123| | 2010-11-25 21:13 | 只看该作者
楼主精神可嘉,只是代码太多,心得写的有点少了

使用特权

评论回复
地板
hotpower| | 2010-11-26 06:36 | 只看该作者
算个例程吧

使用特权

评论回复
5
zhangyang86|  楼主 | 2010-11-28 23:26 | 只看该作者
:)

使用特权

评论回复
6
123jj| | 2010-11-29 06:54 | 只看该作者
呵呵!帮顶!

使用特权

评论回复
7
hotpower| | 2010-11-29 07:42 | 只看该作者

使用特权

评论回复
8
kyzb001| | 2010-11-29 10:37 | 只看该作者
:)    通俗易懂。

使用特权

评论回复
9
dfsa| | 2010-11-29 17:06 | 只看该作者
这个实验刚做过了,不过和楼主的开发板不同

使用特权

评论回复
10
zhangyang86|  楼主 | 2010-11-29 21:16 | 只看该作者
9# dfsa

你用的NUC**系列吧??
可行吧?

使用特权

评论回复
11
秋天落叶| | 2010-11-29 21:45 | 只看该作者
还不错的资料,最近在做一个相关的项目

使用特权

评论回复
12
无冕之王| | 2010-11-30 15:39 | 只看该作者
还不错的例程

使用特权

评论回复
13
pkat| | 2010-11-30 16:12 | 只看该作者
很实用的资料,不知源码能否拿来直接用

使用特权

评论回复
14
zhangyang86|  楼主 | 2010-11-30 17:05 | 只看该作者
源码是我测试了的,完全可以直接使用!!!我所有的源码,没有测试的是不发上来的,避免误导大家!!

使用特权

评论回复
15
bit6019| | 2010-11-30 23:50 | 只看该作者
不错的例程

使用特权

评论回复
16
zhangyang86|  楼主 | 2010-12-1 17:59 | 只看该作者
:)

使用特权

评论回复
17
hotpower| | 2010-12-1 20:25 | 只看该作者
有所图之

使用特权

评论回复
18
zhangyang86|  楼主 | 2010-12-10 11:31 | 只看该作者
:)

使用特权

评论回复
19
pkat| | 2010-12-10 18:54 | 只看该作者
源码确实挺好用的,谢谢楼主

使用特权

评论回复
20
apple| | 2010-12-11 00:09 | 只看该作者
路过

使用特权

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

本版积分规则

80

主题

916

帖子

51

粉丝