51单片机嵌入式开发:12、STC89C52RC 红外解码数码管显示


在这里插入图片描述

1 概述

HX1838是一种常见的红外接收模块,用于接收和解码红外遥控器发送的红外信号。
HX1838具有以下特点和功能:
灵敏度高:HX1838采用高灵敏度的红外接收头,能够接收到较远距离的红外信号。
宽频带:HX1838支持38kHz的红外调制频率,适用于常见的红外遥控器。
内置解码电路:HX1838模块内部集成了红外信号解码电路,能够将接收到的红外信号解码为数字信号,方便后续处理。
简单接口:HX1838模块通常通过3个引脚进行连接,包括供电正极(VCC)、地(GND)和输出信号(OUT),接口简单、易于使用。
应用广泛:HX1838模块常用于各种红外遥控应用,如家电控制、智能家居、遥控车辆等。
使用HX1838模块时,通常需要将其与微控制器或其他数字电路连接,以接收和处理解码后的红外信号。根据具体的应用需求,可以使用相应的编程语言和库来处理和应用接收到的红外信号。

在这里插入图片描述

2 HX1838原理

2.1 原理概述

HX1838模块的工作原理如下:
接收红外信号:当红外遥控器发送信号时,HX1838模块中的红外光电二极管会接收到红外光信号。红外光电二极管是一种特殊的二极管,具有对红外光敏感的特性。
转换为电信号:接收到的红外光信号会被红外光电二极管转换为相应的电信号。这个电信号的特征是频率为38kHz的调制波形,即红外遥控器发送信号时会对红外光进行38kHz的调制。
解码电路处理:HX1838模块内部集成了解码电路,用于将接收到的调制信号进行解码。解码电路会对接收到的信号进行滤波、整形和解码处理,将红外信号转换为数字信号。
输出解码数据:解码后的数字信号将以特定的格式输出,通常是通过模块上的输出引脚(如OUT引脚)输出。输出的数字信号可以表示红外遥控器发送的按键码或其他相关信息。
红外遥控器采用了NEC编码规则:

2.2 原理概述

红外信号NEC 载波频率为 38Khz
    引导码:9ms 高电平 + 4.5ms 低电平
    1 码 :0.56 ms 高电平 + 0.56 ms 低电平
    0 码 : 0.56ms 高电平 + 1.68 ms 低电平
    结束码 :0.56ms 高电平
数据帧格式:引导码 + 地址 + 地址反码 + 键值 + 键值反码 + 结束码
重复帧格式:9ms 高电平 + 2.25ms低电平 + 结束位 + 结束码
高位在前,即首先收到的是高位的数据

2.3 HX1838解码时序
NEC协议的格式,首先来看NEC协议的典型脉冲链:主要分为:
引导码----用户码(区分不同遥控器)----用户码反码----键码(键值)----键码反码

在这里插入图片描述

具体形式:

在这里插入图片描述

注意:由于在HX1838芯片解码时,输出管脚接受到的编码是红外线的编码的反码。

在这里插入图片描述

而具体的引导码形式和逻辑位的形式如下图所示:

在这里插入图片描述

按照上图,进行代码编写!

3 HX1838代码实现

3.1 工程整理

因为工程中需要使用定时器计时解码波形信号时间长短,所以我们添加定时器的c/h文件,同时工程需要用数码管显示接受到的按键数值,所以,添加ledtube的c/h文件,工程框架如下。

在这里插入图片描述

3.2 工程代码

//main.c文件

#include "includes.h"



/******************************************************************/
/*                    微秒延时函数  //10us                         */
/******************************************************************/
void delay_us(unsigned int us)//delay us
{
	while(us--)
	{
	}
}

/******************************************************************/
/*                    微秒延时函数                                */
/******************************************************************/
void delay_ms(unsigned int Ms)//delay us
{
	while(Ms--)
	{
		delay_us(100);
	}
}

/*------------------------------------------------
                    延时子程序
------------------------------------------------*/
void delay(unsigned int cnt) 
{
 while(--cnt);
}




/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
	sys_timer_init();
	
	delay(10);
	delay_ms(10);
	
	
	sys_ledtube_on2();
	
	sys_ledtube_on1();
	
	while (1)
	{
//		sys_keynum_ledon(9);
		sys_tx1838_test();
	}
}

//includes.h文件

#ifndef __INCLUDES_H__
#define __INCLUDES_H__

//#include<reg52.h> 

#include<intrins.h> //汇编指令_nop_
#include<stdio.h> 	//标准输入输出

//_nop_(); 产生一条NOP指令
//作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。
//NOP指令为单周期指令,可由晶振频率算出延时时间。

//8051 为每个机器周期 12 时钟
//对于12M晶振,延时1uS。
//11.0592M晶振,延时1.0851uS。

//对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。


//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "STC89C5xRC_RDP.h"

//应用层头文件
//#include "c51_gpio.h"
#include "c51_ledtube.h"
//#include "c51_key.h"
#include "c51_timer.h"
//#include "c51_exit.h"
//#include "c51_lcd1602.h"
//#include "c51_iic.h"
#include "c51_tx1838.h"


extern void delay(unsigned int cnt);
extern void delay_us(unsigned int us);//delay us;
extern void delay_ms(unsigned int Ms);//delay Ms;


#endif

//c51_tx1838.c文件

#include "includes.h"


unsigned char tx1838_cnt = 0;
unsigned char tx1838_id = 0;
unsigned char tx1838_data = 0;


void sys_tx1838_test(void)
{
	unsigned int time = 0;
	while(!NEC);		//等待低电平结束
	TH0 = 0;
	TL0 = 0;
	while(NEC);			//等待数据位计时
	time =(TH0<<8)+TL0; //取得脉冲宽度
	
	tx1838_cnt ++ ;
	if(time>168 && time<800) //接收到数据位为0的时间长度
	{

	}
	else 
	{
		if(time>1100 && time<1800) //接收到数据位为1的时间长度
		{
			if(tx1838_cnt > 8)
			{
				tx1838_id |= (1<<(tx1838_cnt-9));//取识别遥控器类型
			}
			if(tx1838_cnt > 24)//取出最后一字节 
			{
				tx1838_data |= (1<<(tx1838_cnt-25));
			}
		}
		else //重新解码 //接收到引导码或者结束码,或者接收到的是重复码,本章节不进行演示
		{
			
			tx1838_cnt = 0;		//接收位数量清0
			tx1838_id = 0;
			tx1838_data = 0;
		}
	}
	
	if(tx1838_cnt==32)
	{
		switch(tx1838_data)//判断数码值
		{
			case 255:sys_keynum_ledon(0);break;//0 显示相应的按键值
			case 254:sys_keynum_ledon(1);break;//1
			case 253:sys_keynum_ledon(2);break;//2
			case 252:sys_keynum_ledon(3);break;//3
			case 251:sys_keynum_ledon(4);break;//4
			case 250:sys_keynum_ledon(5);break;//5
			case 249:sys_keynum_ledon(6);break;//6
			case 248:sys_keynum_ledon(7);break;//7
			case 247:sys_keynum_ledon(8);break;//8
			case 246:sys_keynum_ledon(0);break;//9 显示相应的按键值

		}
	}
			
}

//c51_tx1838.h文件

#ifndef __C51_TX1838_H__
#define __C51_TX1838_H__


#define  NEC 	P32 //红外线接收头  

extern unsigned char tx1838_cnt;
extern unsigned char tx1838_id;
extern unsigned char tx1838_data;


extern void sys_tx1838_test(void);

#endif

//c51_timer.c文件

#include "includes.h"


void sys_timer_init(void)
{
	sys_timer0_init();
	sys_timer1_init();
	sys_timer2_init();
	sys_wdog_init();
	clr_wdg();
}


/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer0_init(void)
{
	TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     
	TH0=0x00;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
	TL0=0x00;
	//EA=1;            //总中断打开 等最后一个中断打开
	//ET0=1;           //定时器中断打开
	TR0=1;           //定时器开关打开
}

/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer1_init(void)
{
	TMOD |= 0x20;	  //使用模式2,	     
	TH1=0x05;	      //给定初值,这里使用定时器最大值从5开始计数一直到255溢出
	TL1=0x00;
	//EA=1;            //总中断打开
	//ET1=1;           //定时器中断打开
	
	//TR1=1;           //定时器开关打开
}


/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer2_init(void)
{
	RCAP2H = 0/256;//
	RCAP2L = 0/256;
	//ET2=1;                     //打开定时器中断
	//EA=1;                      //打开总中断
  
	//TR2=1;                     //打开定时器开关
}




void sys_wdog_init(void)
{ 
	//WDT_CONTR = 0x35;
}

void clr_wdg(void)
{
	//WDT_CONTR = 0x35;
}


/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
	TH0=0x00;		  //重新赋值
	TL0=0x00;

	//sys_led_test1(); //流水灯操作
}


/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer1_isr(void) interrupt 3
{

	//sys_led_test1(); //流水灯操作
	
}	




/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer2_isr(void) interrupt 5//定时器2中断
{
    TF2=0;
    //sys_led_test1(); //流水灯操作
}

//c51_timer.h文件

#ifndef __C51_TIMER_H__
#define __C51_TIMER_H__




extern void sys_timer_init(void);
extern void sys_timer0_init(void);
extern void Timer0_isr(void);
extern void sys_timer1_init(void);
extern void Timer1_isr(void);
extern void sys_timer2_init(void);
extern void Timer2_isr(void);

extern void sys_wdog_init(void);
extern void clr_wdg(void);

#endif

//c51_ledtube.c文件

#include "includes.h"

// 显示段码值01234567,可对应原理图查看显示不同图形对应的引脚高点电平配置状态
unsigned char const EL[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,\
		                  	 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F



/********************************************************
函数名称:sys_ledtube_on1
函数功能:点亮一个数码管全为亮起来
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_ledtube_on1(void)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=0xFF;//取显示数据,段码
	P2=0;  	//取位码
}

/********************************************************
函数名称:sys_ledtube_on2
函数功能:显示一组数据
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
static unsigned char ledtube_cnt = 0;
void sys_ledtube_on2(void)
{
	ledtube_cnt++;
	if(ledtube_cnt>7)
	{
		ledtube_cnt = 0;
	}
	P0 = 0x00;				//防止切换数码管瞬间有虚影出现
	P2 = 0x00;
	P0 = EL[ledtube_cnt];	//取显示数据,段码
	P2 = ledtube_cnt;  		//取位码
	
	//根据人眼适应虚影缓冲时间为50ms左右
	//我们调整delay在500以下可以看到明显的看起来是一串数据一起显示
	delay(100); 			
}


/********************************************************
函数名称:sys_keynum_ledon
函数功能:显示按键数值
入口参数:按键数值
出口参数:
修    改:
内    容:
********************************************************/
void sys_keynum_ledon(unsigned char num)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=EL[num];//取显示数据,段码
	P2=0;  	//取位码
}

//c51_ledtube.h文件

#ifndef __C51_LEDTUBE_H__
#define __C51_LEDTUBE_H__


extern unsigned char const EL[];

extern void sys_ledtube_on1(void);
extern void sys_ledtube_on2(void);

extern void sys_keynum_ledon(unsigned char num);


#endif

3.3 演示

我们使用手机遥控器按键0~9进行演示,在数码管上可以显示出对应的数字。

在这里插入图片描述
在这里插入图片描述

4 HX1838总结

通过HX1838模块,用户可以轻松实现红外遥控信号的接收和解码功能。它的高灵敏度和宽频带支持使其适用于多种红外遥控器,并能够接收来自较远距离的红外信号。内置的解码电路简化了红外信号的处理过程,使用户能够更便捷地获取解码后的数字信号。HX1838模块的简单接口使其易于集成到各种电子项目中,并且在家庭自动化、智能控制等领域具有广泛的应用。

  • 36
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 35
    评论
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值