51单片机个人学习笔记16(红外遥控)

news2024/9/23 13:25:53

前言

本篇文章属于STC89C52单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。

[1-1] 课程简介_哔哩哔哩_bilibili

 一、红外遥控介绍

二、硬件电路

其中的三极管是低电平导通,红外信号发送时要进行调制,接受时要进行解调,OUT输出的就是解调后的方波,OUT要接到单片机的外部中断上,保证单片机能捕捉到这个信号 

三、基本发送与接受

 四、NEC编码

注意Data的逻辑0和逻辑1,不是单纯的高低电平,而是高低电平的组合,Repeat信号是当一个按键一直处于按下状态,就重复操作这个按键

五、遥控器键码

 六、51单片机的外部中断

七、外部中断寄存器

八、实例一(红外遥控) 

主要有Timer0.c 和 Int0.c 和IR.c 和 main.c

1.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 char Value)
{
	TH0=Value/256;
	TL0=Value%256;
}

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

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

 2.Int0.c 外部中断模块,使红外遥控的命令处于较高的优先级,保证数据不丢失

#include <REGX52.H>

void Int0_Init(void)
{
	IT0=1;
	IE0=0;
	EX0=1;
	EA=1;
	PX0=1;
}

/*中断函数模板
void Int0_Routine(void) interrupt 0
{
	
}
*/

3.IR.c 红外遥控模块 ,解码过程

#include <REGX52.H>
#include "Int0.h"
#include "Timer0.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;

void IR_Init(void)
{
	Timer0_Init();
	Int0_Init();
}

unsigned char IR_GetDataFlag(void)
{
	if (IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}


unsigned char IR_GetRepeatFlag(void)
{
	if (IR_RepeatFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

unsigned char IR_GetAddress(void)
{
	return IR_Address;
}

unsigned char IR_GetCommand(void)
{
	return IR_Command;
}


void Int0_Routine(void) interrupt 0
{
	if(IR_State==0)
	{
		Timer0_SetCounter(0);
		Timer0_Run(1);
		IR_State=1;
	}
	else if (IR_State==1)
	{
		IR_Time=Timer0_GetCounter();
		Timer0_SetCounter(0);
		if (IR_Time>13500-1000 && IR_Time<13500+1000)
		{
			IR_State=2;
		}
		else if (IR_Time>11250-1000 && IR_Time<11250+1000)
		{
			IR_RepeatFlag=1;
			Timer0_Run(0);
			IR_State=0;
		}
		else 
		{
			IR_State=1;
		}
	}
	else if (IR_State==2)
	{
		IR_Time=Timer0_GetCounter();
		Timer0_SetCounter(0);
		if (IR_Time>1120-500 && IR_Time<1120+500)
		{
			IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));
			IR_pData++;
		}
		else if (IR_Time>2250-500 && IR_Time<2250+500)
		{
			IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));
			IR_pData++;
		}
		else
		{
			IR_pData=0;
			IR_State=1;
		}
		if (IR_pData>=32)
		{
			IR_pData=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;
			}
			Timer0_Run(0);
			IR_State=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(void);
unsigned char IR_GetDataFlag(void);
unsigned char IR_GetRepeatFlag(void);
unsigned char IR_GetAddress(void);
unsigned char IR_GetCommand(void);


#endif

 4.main.c 主函数调用模块

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

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

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"ADD");
	LCD_ShowString(1,6,"CMD");
	LCD_ShowString(1,11,"Num");
	LCD_ShowString(2,1,"00");
	LCD_ShowString(2,6,"00");
	LCD_ShowString(2,11,"000");
	IR_Init();
	while(1)
	{
		if(IR_GetDataFlag() || IR_GetRepeatFlag())
		{
			Address=IR_GetAddress();
			Command=IR_GetCommand();
			
			LCD_ShowHexNum(2,1,Address,2);
			LCD_ShowHexNum(2,6,Command,2);
			
			if (Command==IR_VOL_MINUS)
			{
				Num--;
			}
			if (Command==IR_VOL_ADD)
			{
				Num++;
			}
			
			LCD_ShowNum(2,11,Num,3);
		}
	}
}

九、实例二(红外遥控电机调速)

先把电机模块化

Motor.c

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

sbit Motor=P1^0;

unsigned char Counter,Compare;

void Motor_Init(void)
{
	Timer1_Init();
}

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

void Timer1_Rountine() interrupt 3
{
	TH1=0xFF;   	    
	TL1=0xA4;		   
	Counter++;
	Counter%=100;
	if (Counter<Compare)
	{
		Motor=1;
	}
	else
	{
		Motor=0;
	}
}

 

 然后在主程序中应用红外模块和马达模块

main.c

#include <REGX52.H>

#include "Nixie.h"
#include "Motor.h"
#include "Timer1.h"
#include "IR.h"


unsigned char Command,Speed;

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

		}
		Nixie(1,Speed);
	}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1993728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt编程技巧小知识点(2)GPIB缓存区数据读取

文章目录 Qt编程技巧小知识点&#xff08;2&#xff09;GPIB缓存区数据读取小结 Qt编程技巧小知识点&#xff08;2&#xff09;GPIB缓存区数据读取 大端小端的问题&#xff0c;其主要表现如下例子&#xff1a; 例如&#xff1a;输入为QByteArray str "#14M\xB6q\xC1\n&qu…

ImageNet_2014数据集下载与解压

前言 最近在配OpenLongTailRecognition-OLTR代码用的ImageNet_2014&#xff0c;因为数据集较大的原因&#xff0c;导致下载和数据集配置一直被耽误&#xff0c;进度很满&#xff0c;故此记录&#xff0c;以背不时只用。 进入imageNet主页 注: 需要注册账号&#xff0c;教育邮箱…

【论文阅读】MobileNetV4 - Universal Models for the Mobile Ecosystem

文章目录 摘要一、介绍二、相关工作三、与硬件无关的帕累托效率四、通用倒置瓶颈五、移动MQA六、MNv4模型的设计6.1 为增强的体系结构改进NAS6.2 MNv4模型的优化 7. 结果7.1 ImageNet分类7.2 COCO目标检测 8. 强化蒸馏配方9. 结论 MobileNetV4 - 移动生态系统的通用模型 摘要 …

linux系统编程:(4)

1.系统时间的获取函数 1. time函数 功能: 获得1970年到现在的秒数 参数: t:存放秒数的空间首地址 返回值: 成功返回1970年到现在的秒数 失败返回-1 2.localtime 函数 功能: 将一个秒数转化成日历时间 参数: timep:保存秒数空间的地址 返回值: 成功…

Node.js异步编程

【图书介绍】《Node.jsMongoDBVue.js全栈开发实战》-CSDN博客 《Node.jsMongoDBVue.js全栈开发实战&#xff08;Web前端技术丛书&#xff09;》(邹琼俊)【摘要 书评 试读】- 京东图书 (jd.com) 本节主要介绍Node.js异步编程的相关内容。内容包括 同步API、异步API、同步API与…

拿捏!远程观影之详细操作教程

碎碎念 相信不少小伙伴是有收藏影片的&#xff0c;时不时会取出来进行观看。大多时候&#xff0c;我们都是在局域网中观影&#xff0c;局域网中是直连&#xff0c;所以可以一直流畅进行观影&#xff0c;但是有不少朋友是有远程观影需求的&#xff0c;那么怎么实现能随时在手机…

squidpy学习总结

下载安装 首先不要使用pip install squidpy[interactive] 安装&#xff0c;因为我在base环境里python版本是python3.11.5, 导致安装narapi包的时候出现问题&#xff0c;所以我选择的办法是 conda create -n sp_env python3.9.12 注意这个有个问题&#xff0c;我的mac为啥建立不…

【git】git与​TortoiseGit​下载教程

下载地址&#xff1a;https://git-scm.com/ 下载TortoiseGit 官网链接&#xff1a;https://tortoisegit.org/ 拉去代码错误&#xff1a; 找到在本地安装的 git 服务的根目录 -> Git -> usr -> bin 目录下选中 ssh.exe &#xff0c;再点击打开即可&#xff0c;如下图&a…

在Ubuntu上基于NDK(r21)交叉编译FFmpeg for Android

各软件版本号&#xff1a;VMware为17 Pro、FFmpeg版本号为4.3.8、NDK版本号为r21e、Ubuntu版本号为20.04 1.下载FFmpeg4.3.8并解压 2.下载NDK&#xff08;r21e&#xff09;并解压 https://dl.google.com/android/repository/android-ndk-r21e-linux-x86_64.zip 3.在ffmpeg-4.…

FastReport数据区横向排列展示

FastReport数据区横向排列展示 步骤1&#xff1a;设置数据区的Columns Editor属性 1、Count&#xff1a;2表示数据区里的控件将最多显示两列 2、AcrossThenDown&#xff1a;数据区里的控件将会被从做到右依次循环遍历 3、Width&#xff1a;9.25&#xff0c;因为我只设置了两列…

mmdebstrap:创建 Debian 系统 chroot 环境的利器 ️

文章目录 mmdebstrap 的一般性参数说明 &#x1f4dc;mmdebstrap 的常见用法示例 &#x1f308;使用 mmdebstrap 的注意事项 ⚠️ &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f388;欢迎踏入我的博客世界&#xff0c;能与您在此邂逅&#xff0c;真是缘分使然&am…

我的创新大赛经验分享:如何打磨优化项目

我的创新大赛经验分享&#xff1a;如何打磨优化项目 前言1. 强化创新性与独特性2. 深度市场调研与用户需求洞察3. 优化商业模式与财务规划4. 提升团队表现与协作效率5. 完善展示材料与演示技巧6. 模拟答辩与专家评审7. 关注细节与排除潜在问题结语 前言 在创新的浪潮中&#xf…

Vue前端服务加密后端服务解密--AES算法实现

在实际项目中考虑到用户数据的安全性&#xff0c;在用户登录时&#xff0c;前端需要对用户密码加密&#xff08;防止用户密码泄露&#xff09;&#xff0c;服务端收到登录请求时先对密码进行解密&#xff0c;然后再进行用户验证登操作。本文 AES ECB 模式来实现前端机密后端解密…

PLSQL导入导出ORACLE数据提示失败问题修改PLSQL配置

oracle中plsql导入提示无法导入问题 1.首先看下是否环境变量已经配置(具体配置看下面环境变量配置) 2.plsql数据导入中tools-->Preferences中配置如下框中的内容 3.设置 tnsnames.ora文件中看下是否设置有问题 4.PLSQL乱码问题 NLS_LANG SIMPLIFIED CHINESE_CHINA.ZHS16…

C语言作业难题

计算 1 1/(2 * 3) 1/(3 * 4) ... 1/(n * (n 1)) ?直到最后一相值小于0.00001为至。 参考代码&#xff1a; #include <stdio.h> int main() { // 定义一个变量用来存储累加结果 double sum 1;// 将第一个运算数直接赋值给sum,后期程序无需在处理 double n 2; //…

如何快速对接Android平台GB28181接入模块(SmartGBD)

好多开发者希望我们不是从代码级&#xff0c;而是从流程方面&#xff0c;大概介绍下Android端GB28181设备接入段模块。本文以SmartGBD的Camera2Demo为例&#xff0c;大概聊下相关的集成流程。 大牛直播SDK推出的Android平台GB28181接入SDK&#xff08;SmartGBD&#xff09;&am…

git commit提示node不是内部或外部命令,也不是可运行的程序 或批处理文件。

使用git commit 提交项目时提示"node" 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件。 但是node早已安装了&#xff0c;node -v也能正常显示版本号&#xff0c;我检查了环境变量等配置&#xff0c;都是正常的 E:\work\2024\project12\DEMO>gi…

慧灵——引领智能机器人行业新潮流

随着人工智能和机器人技术的迅猛发展&#xff0c;智能机器人行业正迎来前所未有的增长潜力和创新机遇。慧灵科技作为行业内的佼佼者&#xff0c;以其创新技术和卓越性能&#xff0c;正在引领智能机器人行业的新潮流。 智能机器人行业是一个充满活力和潜力的领域。随着全球人口老…

花指令基础

花指令基础 偶尔更新。。。 默认会一点cpp和汇编。 文章目录 花指令基础1. 简介2. 常见类型1. jxjnx2. calladd [esp]ret 3. 等价解析1. push pop2. jmp call retn3. enter leave4. and MoeCTF 2022 chicken_soup参考 1. 简介 花指令可以误导反汇编&#xff0c;但不影响程序…

基于SpringBoot+Vue的物流管理系统(带1w+文档)

基于SpringBootVue的物流管理系统(带1w文档) 基于SpringBootVue的物流管理系统(带1w文档) 本课题研究和开发物流管理系统管理系统&#xff0c;让安装在计算机上的该系统变成管理人员的小帮手&#xff0c;提高物流管理系统信息处理速度&#xff0c;规范物流管理系统信息处理流程…