红外遥控切歌(好运来/天空之城)、红外模块的应用

目录

一、主函数

 二、红外模块(IR)

1.IR.c

2.IR.h


一、主函数

/*定时器1初始化*/
void Timer1Init()
{
		
		TMOD |= 0x10;
		TL1 = 0x18;
		TH1 = 0xFC;
		TR1 = 1;
		ET1 = 1;
		EA = 1;
		PT1 = 0;
}


void main()
{
		IR_Init();
		Timer1Init();
		while(1)
		{
				/*按键控制*/
//			if(k1==0)
//			{
//					delay(100);
//					if(k1==0)
//					{
//							falg = 1;
//							TR1 = 0;
//							MusicSelect = 0;
//					}
//				while(!k1);
//			}
//			
//			if(k2==0)
//			{
//					delay(100);
//					if(k2==0)
//					{
//							falg = 2;
//							TR1 = 0;
//							MusicSelect = 0;
//					}
//				while(!k2);
//			}

				/*红外遥控*/
				if(IR_GetDataFlag()||IR_GetRepeatFlag())            //判断是否收到数据(IR_GetDataFlag()按一下|IR_GetRepeatFlag()长按)
				{
						Command = IR_GetCommand();            //获取遥控器命令码
						if(Command==IR_PREVIOUS){falg = 1;TR1 = 0;MusicSelect = 0;} //判断建码一致  切第一首歌
						if(Command==IR_NEXT)  {falg = 2;TR1 = 0;MusicSelect = 0;}   //判断建码一致  切第二首歌
				}
			
			switch(falg)
			{
				case 1:
									if(Music1[MusicSelect]!=0xFF)//判断是否等于终止标志位
							{
									FreqSelect = Music1[MusicSelect];//获取音符对应的频率
									MusicSelect++;           //MusicSelect++转换至音符长度
									delay(SPEED/4*Music1[MusicSelect]);//选择音符对应的时间长度(时值)
									MusicSelect++;         //MusicSelect++转换至下一个音符
									TR1 = 0;
									delay(5);                    //音符间短暂停顿
									TR1 = 1;
							}
									else                //如果是停止标识符清零重新播放
							{
									TR1 = 0;
									MusicSelect = 0;
							}			
							break;
				case 2:
									if(Music2[MusicSelect]!=0xFF)//判断是否等于终止标志位
							{
									FreqSelect = Music2[MusicSelect];//获取音符对应的频率
									MusicSelect++;          //MusicSelect++转换至音符长度
									delay(SPEED/4*Music2[MusicSelect]);//选择音符对应的时间长度(时值)
									MusicSelect++;        //MusicSelect++转换至下一个音符
									TR1 = 0;
									delay(5);                //音符间短暂停顿
									TR1 = 1;
							}
									else                  //如果是停止标识符清零重新播放
							{
									TR1 = 0;
									MusicSelect = 0;
							}			
							break;
				}			
		}
	
}

void Timer1_Routine() interrupt 3
{
		if(FreqSelect)   //判断是否为休止符
		{
				/*取对应频率值的重装载值到定时器*/
				TL1 = FreqTable_L[FreqSelect];   //设置定时器初值
				TH1 = FreqTable_H[FreqSelect];	 //设置定时器初值
				Buzz = !Buzz;//翻转蜂鸣器IO口
		}
}

 二、红外模块(IR)

1.IR.c

#include <REGX52.H>
#include "Timer0.h"
#include "Int0.h"

unsigned int IR_Time;
unsigned char IR_State;

unsigned char IR_Data[4];
unsigned char IR_pData;

unsigned char IR_DataFlag;
unsigned char IR_RepeatFlag;
unsigned char IR_Address;
unsigned char IR_Command;

/**
  * @brief  红外遥控初始化
  * @param  无
  * @retval 无
  */
void IR_Init(void)
{
	Timer0_Init();
	Int0_Init();
}

/**
  * @brief  红外遥控获取收到数据帧标志位
  * @param  无
  * @retval 是否收到数据帧,1为收到,0为未收到
  */
unsigned char IR_GetDataFlag(void)
{
	if(IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}

/**
  * @brief  红外遥控获取收到连发帧标志位
  * @param  无
  * @retval 是否收到连发帧,1为收到,0为未收到
  */
unsigned char IR_GetRepeatFlag(void)
{
	if(IR_RepeatFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

/**
  * @brief  红外遥控获取收到的地址数据
  * @param  无
  * @retval 收到的地址数据
  */
unsigned char IR_GetAddress(void)
{
	return IR_Address;
}

/**
  * @brief  红外遥控获取收到的命令数据
  * @param  无
  * @retval 收到的命令数据
  */
unsigned char IR_GetCommand(void)
{
	return IR_Command;
}

//外部中断0中断函数,下降沿触发执行
void Int0_Routine(void) interrupt 0
{
	if(IR_State==0)				//状态0,空闲状态
	{
		Timer0_SetCounter(0);	//定时计数器清0
		Timer0_Run(1);			//定时器启动
		IR_State=1;				//置状态为1
	}
	else if(IR_State==1)		//状态1,等待Start信号或Repeat信号
	{
		IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间
		Timer0_SetCounter(0);	//定时计数器清0
		//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)
		if(IR_Time>12442-500 && IR_Time<12442+500)
		{
			IR_State=2;			//置状态为2
		}
		//如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)
		else if(IR_Time>10368-500 && IR_Time<10368+500)
		{
			IR_RepeatFlag=1;	//置收到连发帧标志位为1
			Timer0_Run(0);		//定时器停止
			IR_State=0;			//置状态为0
		}
		else					//接收出错
		{
			IR_State=1;			//置状态为1
		}
	}
	else if(IR_State==2)		//状态2,接收数据
	{
		IR_Time=Timer0_GetCounter();	//获取上一次中断到此次中断的时间
		Timer0_SetCounter(0);	//定时计数器清0
		//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)
		if(IR_Time>1032-500 && IR_Time<1032+500)
		{
			IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));	//数据对应位清0
			IR_pData++;			//数据位置指针自增
		}
		//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)
		else if(IR_Time>2074-500 && IR_Time<2074+500)
		{
			IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	//数据对应位置1
			IR_pData++;			//数据位置指针自增
		}
		else					//接收出错
		{
			IR_pData=0;			//数据位置指针清0
			IR_State=1;			//置状态为1
		}
		if(IR_pData>=32)		//如果接收到了32位数据
		{
			IR_pData=0;			//数据位置指针清0
			if((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))	//数据验证
			{
				IR_Address=IR_Data[0];	//转存数据
				IR_Command=IR_Data[2];
				IR_DataFlag=1;	//置收到连发帧标志位为1
			}
			Timer0_Run(0);		//定时器停止
			IR_State=0;			//置状态为0
		}
	}
}

2.IR.h

#ifndef __IR_H__
#define __IR_H__
/*红外遥控的键值*/
#define IR_POWER		0x45
#define IR_MODE			0x46
#define IR_MUTE			0x47
#define IR_START_STOP	0x44
#define IR_PREVIOUS		0x40
#define IR_NEXT			0x43
#define IR_EQ			0x07
#define IR_VOL_MINUS	0x15
#define IR_VOL_ADD		0x09
#define IR_0			0x16
#define IR_RPT			0x19
#define IR_USD			0x0D
#define IR_1			0x0C
#define IR_2			0x18
#define IR_3			0x5E
#define IR_4			0x08
#define IR_5			0x1C
#define IR_6			0x5A
#define IR_7			0x42
#define IR_8			0x52
#define IR_9			0x4A

void IR_Init(void);
unsigned char IR_GetDataFlag(void);
unsigned char IR_GetRepeatFlag(void);
unsigned char IR_GetAddress(void);
unsigned char IR_GetCommand(void);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不惑梦蝶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值