搜索
bottom↓
回复: 18

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

[复制链接]

出0入0汤圆

发表于 2010-11-25 12:53:36 | 显示全部楼层 |阅读模式
本实验移植自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);

    }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2010-11-25 14:23:06 | 显示全部楼层
收藏了

出0入0汤圆

发表于 2010-12-17 08:45:44 | 显示全部楼层
收藏了

出0入0汤圆

发表于 2010-12-17 09:09:53 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-18 08:30:23 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-12-21 18:35:29 | 显示全部楼层
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; //按键次数清零
}   
我想问一下楼主,这里的时间4.5ms、2ms、1.5ms 、500us 是怎么确定的,你怎么知道的呢?那些键值是怎么算出来的呢?例如以Remote_Odr=144为例,怎么算得Remote_Odr的值为144的呢?

出0入0汤圆

 楼主| 发表于 2010-12-30 22:11:42 | 显示全部楼层
这个是遥控器的时序啊!
请看我们Alientek的手册部分说明:


(原文件名:ourdev_577839.jpg)

出0入0汤圆

发表于 2010-12-30 23:36:51 | 显示全部楼层
谢谢分享。现在用的是合泰HT6221发射,STC中断接收解码。正有意等拿到芯唐开发板后试一下。好象HT6221的编码时序跟NEC的一模一样。

出0入0汤圆

发表于 2011-1-1 22:08:03 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-1-19 21:42:58 | 显示全部楼层
谢谢分享。开始学习M051,也尝试着从红外遥控解码开始。

出0入0汤圆

发表于 2011-1-20 11:24:31 | 显示全部楼层
nuc120 进中断1,却只能进一次。不知道哪里还需要设置。。。

出0入0汤圆

发表于 2011-1-20 14:08:12 | 显示全部楼层
学习一下。

出0入0汤圆

发表于 2011-1-20 14:12:55 | 显示全部楼层
能进多次了,就是中断程序出来后还会时不时进去下。。。太灵敏了。。。

出100入0汤圆

发表于 2011-3-14 22:44:11 | 显示全部楼层
楼主的程序在新唐送的开发板上调试通过,谢谢分享。
发现一个问题,只要使能TIMER0~3中的任意一个,解码程序就得不到正确的结果。怀疑是楼主程序中用到的库函数DrvSYS_Delay()中使用到的SysTick timer与TIMER0~3有冲突。下面是初始化TIMER1的函数,一执行这个函数就不能正确解码,不执行则一切正常。请楼主和高手指点,谢谢!
void TMR1_Init(void)
{
        /* Enable Timer0 clock source */
    APBCLK |= TMR1_CLKEN;
        /* Select Timer0 clock source as external 12M */  
        CLKSEL1 = (CLKSEL1 & (~TM1_CLK)) | TM1_12M;        

        /* Reset IP TMR1 */
        IPRSTC2 |= TMR1_RST;
        IPRSTC2 &= ~TMR1_RST;

        /* Select timer1 Operation mode as period mode */       
        TCSR1 &= ~TMR_MODE;
        TCSR1 |= MODE_PERIOD;               

        /* Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
        TCSR1 = TCSR1 & 0xFFFFFF00;                // Set Prescale [0~255]
        TCMPR1 = 12000000;                                // Set TCMPR [0~16777215]

        /* Enable timer1 interrupt */
        TCSR1 |= TMR_IE;               
        NVIC_ISER |= TMR1_INT;       

        /* Reset timer1 counter */
        TCSR1 |= CRST;       

        /* Enable Timer1 */                                       
        TCSR1 |= CEN;                       
}

出0入0汤圆

发表于 2011-3-15 16:52:48 | 显示全部楼层
回复【9楼】greatwall2
谢谢分享。开始学习m051,也尝试着从红外遥控解码开始。
-----------------------------------------------------------------------

我这边有卖板和M051芯片,有需要的话可以找我哦!

出0入0汤圆

发表于 2011-7-15 10:58:55 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-7-21 17:30:06 | 显示全部楼层
mark

出0入112汤圆

发表于 2011-7-21 22:48:15 | 显示全部楼层
回复【楼主位】okelec
-----------------------------------------------------------------------

请教!
M051广州那里有得买?赛格有吗?价格怎样?

出0入112汤圆

发表于 2011-7-21 22:53:43 | 显示全部楼层
回复【楼主位】okelec
-----------------------------------------------------------------------

请教!
M051广州那里有得买?赛格有吗?价格怎样?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-1 22:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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