首页 > 其他分享 >21_红外遥控

21_红外遥控

时间:2023-11-30 15:11:47浏览次数:31  
标签:21 遥控 IR unsigned char 红外 include void define

红外遥控

介绍

image-20231129190715228

硬件电路

image-20231129191035748

基本发送和接收

image-20231129201010474

NEC编码

image-20231129201127650

image-20231129201528564

遥控器键码

image-20231129201944042

51单片机的外部中断

image-20231129202009226

外部中断寄存器

image-20231129202114484

红外遥控 VOL-/VOL+

Timer0.c

#include <REGX52.H>

void Timer0_Init(void)
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0;				//设置定时初始值
	TH0 = 0;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 0;				//定时器0不计时
}

void Timer0_SetCounter(unsigned int Value)
{
	TH0=Value/256;
	TL0=Value%256;
}

unsigned int Timer0_GetCounter()
{
	return (TH0<<8)|TL0;
}

void Timer0_Run(unsigned char Flag)
{
	TR0=Flag;
}

Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0_Init(void);

void Timer0_SetCounter(unsigned int Value);

unsigned int Timer0_GetCounter();

void Timer0_Run(unsigned char Flag);

#endif

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
		}
	}
}

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();

unsigned char IR_GetDataFlag();

unsigned char IR_GetRepeatFlag();

unsigned char IR_GetAddress();

unsigned char IR_GetCommand();

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"
#include "IR.h"

unsigned char Num;
unsigned char Address;
unsigned char Command;

void main()
{
	LCD_Init();
	IR_Init();
	LCD_ShowString(1,1,"ADDR  CMD  NUM");
	LCD_ShowString(2,1,"00    00   00");
	P2=0xFF;
	while(1)
	{
		if(IR_GetDataFlag() || IR_GetRepeatFlag())
		{
			Address=IR_GetAddress();
			Command=IR_GetCommand();
			LCD_ShowHexNum(2,1,Address,2);
			LCD_ShowHexNum(2,7,Command,2);
			if(Command==IR_VOL_MINUS)
			{
				Num--;
			}
			if(Command==IR_VOL_ADD)
			{
				Num++;
			}
			LCD_ShowNum(2,12,Num,3);
		}
	}
}

运行效果

VID_20231130_142656

红外遥控电机调速

Motor.c

#include <REGX52.H>
#include "Timer1.h"

sbit Motor=P1^0;

unsigned char Counter,Compare;

void Motor_Init()
{
	Timer1_Init();
}

void Motor_SetSpeed(unsigned char Speed)
{
	Compare=Speed;
}

void Timer1_Routine() interrupt 3
{
	TL1 = 0x9C;				//设置定时初始值
	TH1 = 0xFF;				//设置定时初始值
	Counter++;
	Counter%=100;
	if(Counter<Compare)
	{
		Motor=1;
	}
	else
	{
		Motor=0;
	}
}

Motor.h

#ifndef __MOTOR_H__
#define __MOTOR_H__

void Motor_Init();
void Motor_SetSpeed(unsigned char Speed);

#endif

Timer1.c

#include <REGX52.H>

/**
* @brief 定时器1初始化,100微秒@12.000MHz
  * @param 无
  * @retval 无
  */
void Timer1_Init(void)
{
	TMOD &= 0x0F;			//设置定时器模式
	TMOD |= 0x10;			//设置定时器模式
	TL1 = 0x9C;				//设置定时初始值
	TH1 = 0xFF;				//设置定时初始值
	TF1 = 0;				//清除TF0标志
	TR1 = 1;				//定时器0开始计时
	ET1=1;
	EA=1;
	PT1=0;
}

/* 定时器中断函数模板
void Timer1_Routine() interrupt 3
{
	static unsigned int T1Count;
	TL1 = 0x9C;				//设置定时初始值
	TH1 = 0xFF;				//设置定时初始值
	T1Count++;
	if(T1Count>=1000)
	{
		T1Count=0;
		
	}
}
*/

Timer1.h

#ifndef __TIMER1_H__
#define __TIMER1_H__

void Timer1_Init(void);

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "Nixie.h"
#include "Motor.h"
#include "IR.h"

unsigned char Command,Speed;

void main()
{
	Motor_Init();
	IR_Init();
	while(1)
	{
		if(IR_GetDataFlag())
		{
			Command=IR_GetCommand();
			
			switch(Command)
			{
				case IR_0:Motor_SetSpeed(0);Speed=0;break;
				case IR_1:Motor_SetSpeed(50);Speed=1;break;
				case IR_2:Motor_SetSpeed(75);Speed=2;break;
				case IR_3:Motor_SetSpeed(100);Speed=3;break;
			}
		}
		Nixie(1,Speed);
	}
}

标签:21,遥控,IR,unsigned,char,红外,include,void,define
From: https://www.cnblogs.com/mzx233/p/17867423.html

相关文章

  • 【Vulnhub 靶场】【Coffee Addicts: 1】【简单-中等】【20210520】
    1、环境介绍靶场介绍:https://www.vulnhub.com/entry/coffee-addicts-1,699/靶场下载:https://download.vulnhub.com/coffeeaddicts/coffeeaddicts.ova靶场难度:简单-中等发布日期:2021年5月20日文件大小:1.3GB靶场作者:BadByte靶场描述:我们的咖啡店被黑客入侵了!!你能修复......
  • 11.29实验21
    实验21:观察者模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解观察者模式的动机,掌握该模式的结构;2、能够利用观察者模式解决实际问题。[实验任务一]:股票提醒当股票的价格上涨或下降5%时,会通知持有该股票的股民,当股民听到价格上涨的消息时会买股票,当价格下降时......
  • jdk21-虚拟线程
    jdk文档:https://openjdk.org/jeps/444关键内容整理虚拟线程是轻量级线程,可显著减少编写、维护和观察高吞吐量并发应用程序的工作量。默认情况下,直接使用API创建的虚拟线程(而不是通过创建的虚拟线程)现在也会在其整个生命周期内受到监视,并且可以通过观察虚拟线程部分......
  • AGC021 解题笔记
    好久没写一整场CF或者AT的题解了,所以写一篇。C有点意思的题。考虑先放横再放竖,若确定所有横的位置,那么每列独立。所以记\(f_i\)表示第\(i\)列最多放多少个,考虑放一个横对\(f_i\)的影响。若\(n\)为奇数,那么第一行放满显然最优。若某时\(A>1\),那么放一个\(2\times......
  • E800与GS2110 通讯。
    ......
  • P7470 [NOI Online 2021 提高组] 岛屿探险
    我永远喜欢数据结构。题目传送门给出\(n\)个二元组\((a_i,b_i)\),有\(q\)次询问,每次给出\(l_i,r_i,c_i,d_i\),求有多少个\(j\)满足\(j\in[l_i,r_i]\)且\(a_j\oplusc_i\le\min\{b_j,d_i\}\)。\(n,q\le10^5\),设值域为\(V\),\(|V|\le2^{24}\)。\(2.00\,\text......
  • 义无反顾马督工,Bert-vits2V210复刻马督工实践(Python3.10)
    Bert-vits2更新了版本V210,修正了日/英的bert对齐问题,效果进一步优化;对底模使用的数据进行优化和加量,减少finetune失败以及电音的可能性;日语bert更换了模型,完善了多语言推理。更多情报请参考Bert-vits2官网:https://github.com/fishaudio/Bert-VITS2/releases/tag/2.1最近的事......
  • 2023-2024-1 20211327 myxxd(课上测试)
    myxxd(课上测试)学***d的使用,提交至少3个应用截图xxd的主要功能是什么?需要使用什么系统调用来实现?写出你的推导过程,命令xxd主要用于查看文件的十六进制表示,并提供了一些额外的功能,如生成C语言风格的数组表示。它的主要功能包括:查看文件的十六进制表示:显示文件内容的十......
  • [WARNING] The POM for com.alibaba:druid:jar:1.1.21 is invalid, transitive depend
    这个警告表明Maven在尝试下载或处理com.alibaba:druid:1.1.21这个依赖项时遇到了问题。警告的具体内容是说POM(ProjectObjectModel)文件无效,这可能会导致Maven无法正确地处理传递性依赖关系。有几种可能的原因和解决方法:1.网络问题:Maven可能无法从Maven仓库正确下载d......
  • 软件设计实验 21:观察者模式
    实验21:观察者模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解观察者模式的动机,掌握该模式的结构;2、能够利用观察者模式解决实际问题。 [实验任务一]:股票提醒当股票的价格上涨或下降5%时,会通知持有该股票的股民,当股民听到价格上涨的消息时会买股票,当价......