普中51单片机学习笔记-红外遥控

红外线简介

人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、 蓝、紫。其中红光的波长范围为 0.62~0.76μm;紫光的波长范围为 0.38~0.46μm。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线。红外线遥控就是利用波长为 0.76~1.5μm 之间的近红外线来传送控制信号的。

红外遥控的原理

红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。

1.1 工作原理

  • 红外遥控器发送38kHz的调制信号

  • 接收头(如HS0038)接收并解调信号

  • 单片机通过外部中断检测信号时序

  • 根据脉冲宽度解码数据

1.2 NEC协议(最常用)

  • 引导码:9ms高电平 + 4.5ms低电平

  • 数据格式:8位地址码 + 8位地址反码 + 8位命令码 + 8位命令反码

  • 数据表示:

    • 逻辑0:560us高电平 + 560us低电平

    • 逻辑1:560us高电平 + 1690us低电平

  • 重复码:9ms高电平 + 2.25ms低电平

硬件电路

示例代码

main.c

复制代码
/**************************************************************************************
实验名称:红外遥控实验
接线说明:	
实验现象:下载程序后,数码管上显示数码管上显示红外解码遥控器键值
注意事项:红外接收头凸起处要与PCB板接口凸起丝印处对应																				  
***************************************************************************************/

#include "public.h"
#include "smg.h"
#include "ired.h"


/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	u8 ired_buf[3];

	ired_init();//红外初始化

	while(1)
	{				
		ired_buf[0]=gsmg_code[gired_data[2]/16];//将控制码高4位转换为数码管段码
		ired_buf[1]=gsmg_code[gired_data[2]%16];//将控制码低4位转换为数码管段码
		ired_buf[2]=0X76;//显示H的段码
		smg_display(ired_buf,6);	
	}		
}

smg.h

复制代码
#ifndef _smg_H
#define _smg_H

#include "public.h"


#define SMG_A_DP_PORT	P0	//使用宏定义数码管段码口

//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

extern u8 gsmg_code[17];

void smg_display(u8 dat[],u8 pos);

#endif

smg.c

复制代码
#include "smg.h"

//共阴极数码管显示0~F的段码数据
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
				0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

/*******************************************************************************
* 函 数 名       : smg_display
* 函数功能		 : 动态数码管显示
* 输    入       : dat:要显示的数据
				   pos:从左开始第几个位置开始显示,范围1-8
* 输    出    	 : 无
*******************************************************************************/
void smg_display(u8 dat[],u8 pos)
{
	u8 i=0;
	u8 pos_temp=pos-1;

	for(i=pos_temp;i<8;i++)
	{
	   	switch(i)//位选
		{
			case 0: LSC=1;LSB=1;LSA=1;break;
			case 1: LSC=1;LSB=1;LSA=0;break;
			case 2: LSC=1;LSB=0;LSA=1;break;
			case 3: LSC=1;LSB=0;LSA=0;break;
			case 4: LSC=0;LSB=1;LSA=1;break;
			case 5: LSC=0;LSB=1;LSA=0;break;
			case 6: LSC=0;LSB=0;LSA=1;break;
			case 7: LSC=0;LSB=0;LSA=0;break;
		}
		SMG_A_DP_PORT=dat[i-pos_temp];//传送段选数据
		delay_10us(100);//延时一段时间,等待显示稳定
		SMG_A_DP_PORT=0x00;//消音
	}
}

ired.h

复制代码
#ifndef _ired_H
#define _ired_H

#include "public.h"

//管脚定义
sbit IRED=P3^2;

//声明变量
extern u8 gired_data[4];


//函数声明
void ired_init(void);

#endif

ired.c

复制代码
#include "ired.h"

u8 gired_data[4];//存储4个字节接收码(地址码+地址反码+控制码+控制反码)

/*******************************************************************************
* 函 数 名         : ired_init
* 函数功能		   : 红外端口初始化函数,外部中断0配置 
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void ired_init(void)
{
	IT0=1;	//下降沿触发
	EX0=1;	//打开中断0允许
	EA=1;	//打开总中断
	IRED=1;	//初始化端口
}

void ired() interrupt 0	//外部中断0服务函数
{
	u8 ired_high_time=0;
	u16 time_cnt=0;
	u8 i=0,j=0;

	if(IRED==0)
	{
		time_cnt=1000;
		while((!IRED)&&(time_cnt))//等待引导信号9ms低电平结束,若超过10ms强制退出
		{
			delay_10us(1);//延时约10us
			time_cnt--;
			if(time_cnt==0)return;		
		}
		if(IRED)//引导信号9ms低电平已过,进入4.5ms高电平
		{
			time_cnt=500;
			while(IRED&&time_cnt)//等待引导信号4.5ms高电平结束,若超过5ms强制退出
			{
				delay_10us(1);
				time_cnt--;
				if(time_cnt==0)return;	
			}
			for(i=0;i<4;i++)//循环4次,读取4个字节数据
			{
				for(j=0;j<8;j++)//循环8次读取每位数据即一个字节
				{
					time_cnt=600;
					while((IRED==0)&&time_cnt)//等待数据1或0前面的0.56ms结束,若超过6ms强制退出
					{
						delay_10us(1);
						time_cnt--;
						if(time_cnt==0)return;	
					}
					time_cnt=20;
					while(IRED)//等待数据1或0后面的高电平结束,若超过2ms强制退出
					{
						delay_10us(10);//约0.1ms
						ired_high_time++;
						if(ired_high_time>20)return;	
					}
					gired_data[i]>>=1;//先读取的为低位,然后是高位
					if(ired_high_time>=8)//如果高电平时间大于0.8ms,数据则为1,否则为0
						gired_data[i]|=0x80;
					ired_high_time=0;//重新清零,等待下一次计算时间
				}
			}
		}
		if(gired_data[2]!=~gired_data[3])//校验控制码与反码,错误则返回
		{
			for(i=0;i<4;i++)
				gired_data[i]=0;
			return;	
		}
	}		
}

public.h

复制代码
#ifndef _public_H
#define _public_H

#include "reg52.h"

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;

void delay_10us(u16 ten_us);
void delay_ms(u16 ms);

#endif

public.c

复制代码
#include "public.h"

/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能		 : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出    	 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}

/*******************************************************************************
* 函 数 名       : delay_ms
* 函数功能		 : ms延时函数,ms=1时,大约延时1ms
* 输    入       : ms:ms延时时间
* 输    出    	 : 无
*******************************************************************************/
void delay_ms(u16 ms)
{
	u16 i,j;
	for(i=ms;i>0;i--)
		for(j=110;j>0;j--);
}

完结,撒花~~~

相关推荐
行业探路者4 分钟前
二维码标签是什么?主要有线上生成二维码和文件生成二维码功能吗?
学习·音视频·语音识别·二维码·设备巡检
逑之12 分钟前
C语言笔记5:函数
java·c语言·笔记
li星野16 分钟前
OpenCV4X学习—核心模块Core
人工智能·opencv·学习
@zulnger25 分钟前
python 学习笔记(多线程和多进程)
笔记·python·学习
gravity_w35 分钟前
Hugging Face使用指南
人工智能·经验分享·笔记·深度学习·语言模型·nlp
凉、介37 分钟前
SylixOS 中的 Unix Socket
服务器·c语言·笔记·学习·嵌入式·sylixos
好奇龙猫37 分钟前
【人工智能学习-AI-MIT公开课第 19. 架构:GPS、SOAR、包容架构】
人工智能·学习·架构
中屹指纹浏览器42 分钟前
2026指纹浏览器底层技术揭秘:Hook内核与特征校验机制的实现
经验分享·笔记
特立独行的猫a1 小时前
告别碎片化笔记:基于n8n-mcp的AI写作助手实战
人工智能·笔记·ai写作·n8n·n8n-mcp
saoys1 小时前
Opencv 学习笔记:绘制动态随机直线(附实时展示)
笔记·opencv·学习