本帖最后由 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, ¶m);
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);
}
} |