当前位置: 首页 > news >正文

51单片机嵌入式开发:14、STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示

  • STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示
  • 1 概述
  • 2 硬件电路
    • 2.1 遥控器
    • 2.2 红外接收器电路
    • 2.3 STC89C52单片机电路
    • 2.4 数码管显示电路
    • 2.5 串口打印电路
    • 2.6 LED显示电路
  • 3 工程代码实现
    • 3.1 红外接收程序
    • 3.2 定时器程序
    • 3.3 数码管显示程序
    • 3.4 外部中断程序
    • 3.5 串口打印程序
    • 3.6 演示效果
  • 4 设计总结


STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示

HX1838红外解码NEC+数码管+串口打印+LED显示

在这里插入图片描述

1 概述

对于C51单片机的设计思路,你可以使用类似的步骤来实现红外解码、数码管显示和LED显示的功能。下面是一个简单的设计思路:

在这里插入图片描述

(1) 连接HX1838红外解码器、数码管和LED到C51单片机。将HX1838的信号引脚连接到C51单片机的外部中断引脚(例如INT0),数码管的CLK引脚连接到C51单片机的某个IO口引脚,数码管的DIO引脚连接到C51单片机的另一个IO口引脚,LED连接到C51单片机的某个IO口引脚。
(2) 在C51的程序中,定义并初始化所需的IO口和外部中断。
(3) 编写中断服务函数来处理红外解码。当外部中断触发时,读取HX1838接收到的红外信号,并进行解码。
(4) 根据解码结果,使用适当的算法将解码结果转换为数码管的显示数据。
(5) 将数码管的显示数据发送到数码管的CLK和DIO引脚上,以控制数码管显示解码结果。
(6) 根据解码结果的状态,设置LED的引脚状态,以控制LED的显示。
(7) 通过循环等待的方式,持续接收和处理红外信号,并更新数码管和LED的显示。

2 硬件电路

2.1 遥控器

外部遥控器的编码见下图:

在这里插入图片描述

2.2 红外接收器电路

红外接收器电路见下图:

在这里插入图片描述

2.3 STC89C52单片机电路

单片机接口电路见下图:

在这里插入图片描述

2.4 数码管显示电路

数码管显示电路接口电路见下图,在数码管0和1进行显示16进制的红外线接收码:
在之前的章节,有相关数码管数显实现的方法,大家可以翻一翻。

在这里插入图片描述

2.5 串口打印电路

串口打印电路接口电路见下图(其实用下载电路也能实现串口的通讯):

在这里插入图片描述

在这里插入图片描述

2.6 LED显示电路

LED显示电路电路见下图:
根据不同的接收数据码,在8个LED灯进行显示,当对应位置为1时,led不亮。

在这里插入图片描述

3 工程代码实现

工程、主程序及includes.h如下:

在这里插入图片描述

//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();sys_exit_init();sys_uart_init();//	sys_ledtube_on2();
//	
//	sys_ledtube_on1();delay(10);//首先定义处于什么状态,//tx1838_type = 1;printf("Hello world~~");while (1){
//		sys_tx1838_test();if(tx1838_flag){tx1838_flag = 0;hx1838_transform(tx1838_value);}sys_keynum_ledon(tx1838_value>>4,0);delay_ms(10);sys_keynum_ledon(tx1838_value&0xF,1);delay_ms(10);}
}

//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"
#include "c51_uart.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

3.1 红外接收程序

实现红外nec解码和根据码位不同,在printf打印不同的字符串。
//c51_tx1838.c文件

#include "includes.h"unsigned char tx1838_cnt = 0;
unsigned char tx1838_type = 0;
unsigned char tx1838_flag = 0;
unsigned char tx1838_repeat_flag = 0;unsigned char tx1838_value = 0;
unsigned char tx1838_data[4] = {0};
unsigned int  tx1838_time = 0;//void sys_tx1838_test(void)
//{
//	unsigned int time = 0;
//	if(!NEC)
//	{
//		while(!NEC);		//等待低电平结束
//		TH0 = 0;
//		TL0 = 0;
//		delay_us(1);
//		if(tx1838_type==4)
//		{
//			tx1838_type =1;
//		}
//		else
//		{
//			while(NEC)			//等待数据位计时
//			{
//				if(TH0>30)
//				{
//					tx1838_type =1;
//					break;
//				}
//			}
//		}
//		time =(TH0<<8)+TL0; //取得脉冲宽度
//	
//		switch(tx1838_type)
//		{
//			case 1:
//			{
//				if(time>3000 && time<7000) //接收到数据
//				{
//					tx1838_type = 2;
//					
//					tx1838_cnt = 0;		//接收位数量清0
//					tx1838_data[0] = 0;
//					tx1838_data[1] = 0;
//					tx1838_data[2] = 0;
//					tx1838_data[3] = 0;
//				}
//				else if(time>2000 && time<3000)//接收到重复码
//				{
//					tx1838_type = 3;
//				}
//				else
//				{
//					tx1838_type = 1;
//				}
//				break;
//			}
//			case 2:
//			{
//				tx1838_cnt ++ ;
//				if(time>168 && time<800) //接收到数据位为0的时间长度
//				{//				}
//				else 
//				{
//					if(time>1100 && time<1800) //接收到数据位为1的时间长度
//					{
//						if(tx1838_cnt<=8)
//						{
//							tx1838_data[0] |= (1<<(tx1838_cnt-1));
//						}
//						else if(tx1838_cnt<=16)
//						{
//							tx1838_data[1] |= (1<<(tx1838_cnt-9));
//						}
//						else if(tx1838_cnt<=24)
//						{
//							tx1838_data[2] |= (1<<(tx1838_cnt-17));
//						}
//						else if(tx1838_cnt<=32)
//						{
//							tx1838_data[3] |= (1<<(tx1838_cnt-25));
//						}
//						else
//						{
//							tx1838_type = 1;
//							
//							tx1838_cnt = 0;		//接收位数量清0
//							tx1838_data[0] = 0;
//							tx1838_data[1] = 0;
//							tx1838_data[2] = 0;
//							tx1838_data[3] = 0;
//						}
//					}
//					else //重新解码 //接收到引导码或者结束码,或者接收到的是重复码,本章节不进行演示
//					{
//						tx1838_type = 1;
//						
//						tx1838_cnt = 0;		//接收位数量清0
//						tx1838_data[0] = 0;
//						tx1838_data[1] = 0;
//						tx1838_data[2] = 0;
//						tx1838_data[3] = 0;
//					}
//				}
//				
//				if(tx1838_cnt>=32)
//				{
//					tx1838_type = 4;
//					
//					switch(tx1838_data[3])//判断数码值
//					{
//						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(9);break;//9 显示相应的按键值//					}
//				}
//				break;
//			}
//			case 3: //重复码
//			{
//				tx1838_type = 1;
//				sys_keynum_ledon(11);
//				break;
//			}
//			case 4: //结束码
//			{
//				tx1838_type = 1;
//				
//				tx1838_cnt = 0;		//接收位数量清0
//				
//				break;
//			}
//			case 5:
//			{
//				break;
//			}
//			default:
//				tx1838_type = 1;
//				break;
//		}
//			
//	}
//}void sys_nec_test(void)
{if(tx1838_type==0)				//状态0,空闲状态{timer0_set(0);				//定时计数器清0timer0_run(1);				//定时器启动tx1838_type=1;				//置状态为1}else if(tx1838_type==1)			//状态1,等待Start信号或Repeat信号{tx1838_time=timer0_get();	//获取上一次中断到此次中断的时间timer0_set(0);				//定时计数器清0//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)if(tx1838_time>12442-500 && tx1838_time<12442+500){tx1838_type=2;			//置状态为2}//如果计时为11.25ms,则接收到了repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)else if(tx1838_time>10368-500 && tx1838_time<10368+500){tx1838_repeat_flag=1;	//置收到连发帧标志位为1timer0_run(0);		//定时器停止tx1838_type=0;		//置状态为0}else					//接收出错{tx1838_type=1;			//置状态为1}}else if(tx1838_type==2)		//状态2,接收数据{tx1838_time=timer0_get();	//获取上一次中断到此次中断的时间timer0_set(0);	//定时计数器清0//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)if(tx1838_time>1032-500 && tx1838_time<1032+500){tx1838_data[tx1838_cnt/8]&=~(0x01<<(tx1838_cnt%8));	//数据对应位清0tx1838_cnt++;			//数据位置指针自增}//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)else if(tx1838_time>2074-500 && tx1838_time<2074+500){tx1838_data[tx1838_cnt/8]|=(0x01<<(tx1838_cnt%8));	//数据对应位置1tx1838_cnt++;			//数据位置指针自增}else					//接收出错{tx1838_cnt=0;			//数据位置指针清0tx1838_type=1;			//置状态为1}if(tx1838_cnt>=32)		//如果接收到了32位数据{tx1838_cnt=0;			//数据位置指针清0if((tx1838_data[0]==~tx1838_data[1]) && (tx1838_data[2]==~tx1838_data[3]))	//数据验证{//地址		:tx1838_data[0]//地址反码	:tx1838_data[1]//数据		:tx1838_data[2]//数据反码	:tx1838_data[3]tx1838_value = tx1838_data[2];P1 = tx1838_value;tx1838_flag=1;	//红外遥控获取收到数据帧标志位}timer0_run(0);		//定时器停止tx1838_type=0;			//置状态为0}}
}void hx1838_transform(unsigned char cmd)
{/*#define TX1838_CH0			0x45
#define TX1838_CH1			0x46
#define TX1838_CH2			0x47
#define TX1838_VOL1			0x44
#define TX1838_VOL2			0x40
#define TX1838_VOL3			0x43
#define TX1838_EQ1			0x07
#define TX1838_EQ2			0x15
#define TX1838_EQ3			0x09
#define TX1838_0			0x16
#define TX1838_100			0x19
#define TX1838_200			0x0D
#define TX1838_1			0x0C
#define TX1838_2			0x18
#define TX1838_3			0x5E
#define TX1838_4			0x08
#define TX1838_5			0x1C
#define TX1838_6			0x5A
#define TX1838_7			0x42
#define TX1838_8			0x52
#define TX1838_9			0x4A*/switch(cmd){case TX1838_CH0:printf("Receice cmd : TX1838 receice is TX1838_CH0 !\r\n");break;case TX1838_CH1:printf("Receice cmd : TX1838 receice is TX1838_CH1 !\r\n");break;case TX1838_CH2:printf("Receice cmd : TX1838 receice is TX1838_CH2 !\r\n");break;case TX1838_VOL1:printf("Receice cmd : TX1838 receice is TX1838_VOL1 !\r\n");break;case TX1838_VOL2:printf("Receice cmd : TX1838 receice is TX1838_VOL2 !\r\n");break;case TX1838_VOL3:printf("Receice cmd : TX1838 receice is TX1838_VOL3 !\r\n");break;case TX1838_EQ1:printf("Receice cmd : TX1838 receice is TX1838_EQ1 !\r\n");break;case TX1838_EQ2:printf("Receice cmd : TX1838 receice is TX1838_EQ2 !\r\n");break;case TX1838_EQ3:printf("Receice cmd : TX1838 receice is TX1838_EQ3 !\r\n");break;case TX1838_0:printf("Receice cmd : TX1838 receice is TX1838_0 !\r\n");break;case TX1838_100:printf("Receice cmd : TX1838 receice is TX1838_100 !\r\n");break;case TX1838_200:printf("Receice cmd : TX1838 receice is TX1838_200 !\r\n");break;case TX1838_1:printf("Receice cmd : TX1838 receice is TX1838_1 !\r\n");break;case TX1838_2:printf("Receice cmd : TX1838 receice is TX1838_2 !\r\n");break;case TX1838_3:printf("Receice cmd : TX1838 receice is TX1838_3 !\r\n");break;case TX1838_4:printf("Receice cmd : TX1838 receice is TX1838_4 !\r\n");break;case TX1838_5:printf("Receice cmd : TX1838 receice is TX1838_5 !\r\n");break;case TX1838_6:printf("Receice cmd : TX1838 receice is TX1838_6 !\r\n");break;case TX1838_7:printf("Receice cmd : TX1838 receice is TX1838_7 !\r\n");break;case TX1838_8:printf("Receice cmd : TX1838 receice is TX1838_8 !\r\n");break;case TX1838_9:printf("Receice cmd : TX1838 receice is TX1838_9 !\r\n");break;default:printf("Receice cmd : TX1838 receice err!\r\n");break;}
}

//c51_tx1838.h文件

#ifndef __C51_TX1838_H__
#define __C51_TX1838_H__#define  NEC 	P32 //红外线接收头  #define TX1838_CH0			0x45
#define TX1838_CH1			0x46
#define TX1838_CH2			0x47
#define TX1838_VOL1			0x44
#define TX1838_VOL2			0x40
#define TX1838_VOL3			0x43
#define TX1838_EQ1			0x07
#define TX1838_EQ2			0x15
#define TX1838_EQ3			0x09
#define TX1838_0			0x16
#define TX1838_100			0x19
#define TX1838_200			0x0D
#define TX1838_1			0x0C
#define TX1838_2			0x18
#define TX1838_3			0x5E
#define TX1838_4			0x08
#define TX1838_5			0x1C
#define TX1838_6			0x5A
#define TX1838_7			0x42
#define TX1838_8			0x52
#define TX1838_9			0x4Aextern unsigned char tx1838_cnt;
extern unsigned char tx1838_type;
extern unsigned char tx1838_flag;
extern unsigned char tx1838_repeat_flag;
extern unsigned char tx1838_value;
extern unsigned char tx1838_data[4];
extern unsigned int tx1838_time;//extern void sys_tx1838_test(void);
extern void sys_nec_test(void);
extern void hx1838_transform(unsigned char cmd);#endif

3.2 定时器程序

定时器主要是配合解码时时间长短判断接收数据的0和1。

//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 &= 0xF0;TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     TH0=0x00;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出TL0=0x00;//EA=1;            //总中断打开 等最后一个中断打开//ET0=1;           //定时器中断打开TF0=0;           //定时器标志清零TR0=0;           //定时器开关打开
}/*------------------------------------------------定时器初始化子程序
------------------------------------------------*/
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;                     //打开定时器开关
}/*** @brief  定时器0设置计数器值* @param  Value,要设置的计数器值,范围:0~65535* @retval 无*/
void timer0_set(unsigned int Value)
{TH0=Value/256;TL0=Value%256;
}/*** @brief  定时器0获取计数器值* @param  无* @retval 计数器值,范围:0~65535*/
unsigned int timer0_get(void)
{return ((TH0<<8)|TL0);
}/*** @brief  定时器0启动停止控制* @param  Flag 启动停止标志,1为启动,0为停止* @retval 无*/
void timer0_run(unsigned char Flag)
{TR0=Flag;
}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 timer0_set(unsigned int Value);
extern unsigned int timer0_get(void);
extern void timer0_run(unsigned char Flag);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

3.3 数码管显示程序

实现数码管显示遥控器的发送码。

//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,unsigned char pn)
{//根据原理图,将P0口全部输出高电平,P2选择0号数码管P0 = 0x00;		//防止切换数码管瞬间有虚影出现P2 = pn;  		//取位码P0 = EL[num];	//取显示数据,段码
}

//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,unsigned char pn);#endif

3.4 外部中断程序

实现在有数据过来时,下降沿触发解码程序。

//c51_exit.c文件

#include "includes.h"void sys_exit_init(void)
{IT0=1;         //边沿触发EX0=1;         //外部中断0开IE0=0;		   //中断标志清零//PX0 = 1;		 //中断优先级不配置EA = 1;//EX1=1;         //外部中断1开//IT1=0;         //电平触发//IT1=1;         //边沿触发,IT1=0表示电平触发
}/*------------------------------------------------外部中断程序
------------------------------------------------*/
void Exit0_isr(void) interrupt 0
{IE0=0;		   //中断标志清零sys_nec_test();
}/*------------------------------------------------外部中断程序
------------------------------------------------*/
void Exit1_isr(void) interrupt 2
{//在此处可以添加去抖动程序,防止按键抖动造成错误//P1=~P1;
}

//c51_exit.h文件

#ifndef __C51_EXIT_H__
#define __C51_EXIT_H__extern void sys_exit_init(void);
extern void Exit0_isr(void);
extern void Exit1_isr(void);#endif

3.5 串口打印程序

实现printf打印不同的字符串。

//c51_uart.c文件

#include "includes.h"/*-----------------------------------------------名称:串口通信内容:连接好串口或者usb转串口至电脑,下载该程序,打开电源打开串口调试程序,将波特率设置为9600,无奇偶校验晶振11.0592MHz,发送和接收使用的格式相同,如都使用字符型格式,在发送框输入 hello,I Love MCU ,在接收框中同样可以看到相同字符,说明设置和通信正确
------------------------------------------------*//******************************************************************/
void sys_uart_init(void)
{SCON  = 0x50;		        /* SCON: 模式 1, 8-bit UART, 使能接收         */TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */TH1   = 0xFD;               /* TH1:  reload value for 9600 baud @ 11.0592MHz   */TR1   = 1;                  /* TR1:  timer 1 run                          */EA    = 1;                  /*打开总中断*///ES    = 1;                  /*打开串口中断*///当使用串口协议通讯时可以使用此型号中断}void Uart_SendChar(unsigned char  dat)
{SBUF = dat; while(!TI); TI = 0; 
}char putchar(char c)//重定向
{Uart_SendChar(c);return c;}/******************************************************************/
/*                  串口中断程序                                  */
/******************************************************************/static unsigned char uart_temp = 0;          //定义临时变量 
static unsigned char uart_cnt = 0;          //定义临时变量 void UART_isr(void) interrupt 4 //串行中断服务程序
{if(RI)                        //判断是接收中断产生{RI=0;                      //标志位清零uart_temp=SBUF;                 //读入缓冲区的值if(uart_cnt==0){if(0x02 == uart_temp){uart_cnt = 1;}else{uart_cnt = 0;}}else if(uart_cnt==1){if(0x05 == uart_temp){uart_cnt = 2;}else{uart_cnt = 0;}}else if(uart_cnt==2){uart_cnt = 0;//P1=uart_temp;                   //把值输出到P1口,用于观察SBUF=uart_temp;                 //把接收到的值再发回电脑端}else{uart_cnt = 0;}}if(TI)                        //如果是发送标志位,清零{TI=0;}
} 

//c51_uart.h文件

#ifndef __C51_UART_H__
#define __C51_UART_H__extern void Uart_SendChar(unsigned char  dat);
extern char putchar(char c);//重定向extern void sys_uart_init(void);
extern void UART_isr(void);#endif

3.6 演示效果

(1)串口打印效果

在这里插入图片描述

(2)数码管显示和LED显示
数码管显示0x1C,LED显示D2D3D4灭,其他亮,所以也显示0x1C

在这里插入图片描述

4 设计总结

HX1838红外解码器结合数码管、串口和LED显示的应用场景有很多,下面是一些可能的应用场景:
(1) 远程控制器:将HX1838红外解码器与数码管、串口和LED显示结合使用,可以实现一个简单的远程控制器。用户可以使用红外遥控器发送命令,通过解码器解码后,在数码管上显示命令信息,并使用LED显示命令的状态(例如开启/关闭)。这可以用于控制家电设备、灯光等。
(2) 安防系统:将HX1838红外解码器与数码管、串口和LED显示结合使用,可以构建一个基本的安防系统。通过使用红外遥控器发送特定的指令,解码器将解码后的指令信息显示在数码管上,并相应地控制LED的状态,以指示安全状态或报警状态。
(3) 学习工具:结合数码管和LED显示,可以将HX1838红外解码器用于学习工具。例如,可以使用红外遥控器发送特定的学习指令,解码器将解码后的指令信息显示在数码管上,而LED则可以用于指示学习进度或正确与否。
(4) 玩具设计:利用HX1838红外解码器和数码管、串口和LED显示,可以设计各种互动玩具。例如,通过使用特定的红外遥控器发送不同的指令,解码器将识别并在数码管上显示相应的信息,而LED则可以用于增加互动效果或指示玩具状态。
(5) DIY项目:HX1838红外解码器与数码管、串口和LED显示的组合可以应用于各种DIY项目,例如智能家居控制、自动化系统、电子游戏等。通过自定义红外指令和相应的解码、显示和控制逻辑,可以实现各种有趣的功能和交互体验。
这些只是一些示例应用场景,实际上,HX1838红外解码器与数码管、串口和LED显示的组合可以应用于各种需要红外信号解码和相应显示控制的项目和系统中。具体的应用取决于你的创意和需求。

相关文章:

51单片机嵌入式开发:14、STC89C52RC 之HX1838红外解码NEC+数码管+串口打印+LED显示

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 STC89C52RC 之HX1838红外解码NEC数码管串口打印LED显示 STC89C52RC 之HX1838红外解码NEC数码管串口打印LED显示1 概述2 硬件电路2.1 遥控器2.2 红外接收器电路2.3 STC89C52单…...

在不同环境中,Java应用程序和MySQL等是如何与Docker进行交互和操作的?

1. 本地开发环境 在本地开发环境中&#xff0c;可以使用Docker Compose来管理和运行Java应用程序容器和MySQL容器。通常&#xff0c;会创建一个docker-compose.yml文件&#xff0c;定义需要的服务及其配置。 以下是一个示例docker-compose.yml文件: version: 3 services:app…...

《DRL》P10-P15-损失函数-优化(梯度下降和误差的反向传播)

文章目录 损失函数交叉熵损失多类别分类任务概述真实标签的独热编码交叉熵损失函数 L p 范式 \mathcal{L}_{p}\text{ 范式} Lp​ 范式均方误差平均绝对误差 优化梯度下降和误差的反向传播 简介 本文介绍了神经网络中的损失函数及其优化方法。损失函数用于衡量模型预测值与真实值…...

Spring Boot项目的404是如何发生的

问题 在日常开发中&#xff0c;假如我们访问一个Sping容器中并不存在的路径&#xff0c;通常会返回404的报错&#xff0c;具体原因是什么呢&#xff1f; 结论 错误的访问会调用两次DispatcherServlet&#xff1a;第一次调用无法找到对应路径时&#xff0c;会给Response设置一个…...

<数据集>手势识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2400张 标注数量(xml文件个数)&#xff1a;2400 标注数量(txt文件个数)&#xff1a;2400 标注类别数&#xff1a;5 标注类别名称&#xff1a;[fist, no_gesture, like, ok, palm] 序号类别名称图片数框数1fist597…...

【Vue3】选项式 API

【Vue3】选项式 API 背景简介开发环境开发步骤及源码总结 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。…...

2、如何发行自己的数字代币(truffle智能合约项目实战)

2、如何发行自己的数字代币&#xff08;truffle智能合约项目实战&#xff09; 1-Atom IDE插件安装2-truffle tutorialtoken3-tutorialtoken源码框架分析4-安装openzeppelin代币框架&#xff08;代币发布成功&#xff09; 1-Atom IDE插件安装 正式介绍基于web的智能合约开发 推…...

百日筑基第二十三天-23种设计模式-创建型总汇

百日筑基第二十三天-23种设计模式-创建型总汇 前言 设计模式可以说是对于七大设计原则的实现。 总体来说设计模式分为三大类&#xff1a; 创建型模式&#xff0c;共五种&#xff1a;单例模式、简单工厂模式、抽象工厂模式、建造者模式、原型模式。结构型模式&#xff0c;共…...

张量的基本使用

目录 1.张量的定义 2.张量的分类 3.张量的创建 3.1 根据已有数据创建张量 3.2 根据形状创建张量 3.3 创建指定类型的张量 1.张量的定义 张量&#xff08;Tensor&#xff09;是机器学习的基本构建模块&#xff0c;是以数字方式表示数据的形式。PyTorch就是将数据封装成张量…...

Oracle(14)什么是唯一键(Unique Key)?

唯一键&#xff08;Unique Key&#xff09;是数据库表中的一个或多个列&#xff0c;它们的值必须在整个表中唯一&#xff0c;但允许包含NULL值。唯一键的主要目的是确保表中每一行的数据在指定的列&#xff08;或列组合&#xff09;中是唯一的&#xff0c;以防止重复数据的出现…...

PostgreSQL的引号、数据类型转换和数据类型

一、单引号和双引号&#xff08;重要&#xff09;&#xff1a; 1、在mysql没啥区别 2、在pgsql中&#xff0c;实际字符串用单引号&#xff0c;双引号相当于mysql的,用来包含关键字&#xff1b; -- 单引号&#xff0c;表示user_name的字符串实际值 insert into t_user(user_nam…...

Mad MAD Sum-Codeforces Round 960 (Div. 2)

题目在这里 大意: MAD函数返回出现次数 ≥ 2 \geq2 ≥2的最大整数 b i b_i bi​ M A D ( a [ 1 , 2 , . . . i ] ) MAD(a[1,2,...i]) MAD(a[1,2,...i]) 每次操作把 a i a_i ai​进行上述操作&#xff0c;直到全变为0为止&#xff0c;对每次操作的数组进行求和&#xff0c;记…...

Flutter 插件之 package_info_plus

当使用Flutter开发应用时,通常需要获取应用程序的基本信息,例如包名、版本号和构建号。Flutter提供了一个名为 package_info_plus 的插件,它能方便地帮助我们获取这些信息。 1. 添加依赖 首先,需要在项目的 pubspec.yaml 文件中添加 package_info_plus 的依赖。打开 pubs…...

如何实现布隆过滤器?

1.布隆过滤器的场景 在Redis 缓存击穿&#xff08;失效&#xff09;、缓存穿透、缓存雪崩怎么解决&#xff1f;中我们说到可以使用布隆过滤器避免「缓存穿透」。 你会说我们只要记录了每个用户看过的历史记录&#xff0c;每次推荐的时候去查询数据库过滤存在的数据实现去重。 …...

运维团队如何高效监控容器化环境中的PID及其他关键指标

随着云计算和容器化技术的快速发展&#xff0c;越来越多的企业开始采用容器化技术来部署和管理应用程序。然而&#xff0c;容器化环境的复杂性和动态性给运维团队带来了前所未有的挑战。本文将从PID&#xff08;进程标识符&#xff09;监控入手&#xff0c;探讨运维团队如何高效…...

通过vue3 + TypeScript + uniapp + uni-ui 实现下拉刷新和加载更多的功能

效果图: 核心代码: <script lang="ts" setup>import { ref, reactive } from vue;import api from @/request/api.jsimport empty from @/component/empty.vueimport { onLoad,onShow, onPullDownRefresh, onReachBottom } from @dcloudio/uni-applet form …...

Pointnet++改进即插即用系列:全网首发WTConv2d大接受域的小波卷积|即插即用,提升特征提取模块性能

简介:1.该教程提供大量的首发改进的方式,降低上手难度,多种结构改进,助力寻找创新点!2.本篇文章对Pointnet++特征提取模块进行改进,加入WTConv2d,提升性能。3.专栏持续更新,紧随最新的研究内容。 目录 1.理论介绍 2.修改步骤 2.1 步骤一 2.2 步骤二 2.3 步骤三 1.理…...

4核16G服务器支持多少人?4C16G服务器性能测评

租赁4核16G服务器费用&#xff0c;目前4核16G服务器10M带宽配置70元1个月、210元3个月&#xff0c;那么能如何呢&#xff1f;配置为ECS经济型e实例4核16G、按固定带宽10Mbs、100GB ESSD Entry系统盘。 那么问题来了&#xff0c;4C16G10M带宽的云服务器可以支持多少人同时在线&…...

塔子哥的平均数-美团2023笔试(codefun2000)

题目链接 塔子哥的平均数-美团2023笔试(codefun2000) 题目内容 给定一个正整数数组a1 ,a2 ,…,an&#xff0c;求平均数正好等于k的最长连续子数组的长度 输入描述 输出描述 输出一个整数&#xff0c;表示最长满足题目条件的长度。 样例1 输入 5 2 1 3 2 4 1 输出 3 样例1解释…...

故障诊断 | 基于小波包能量谱对滚动轴承的故障诊断Matlab代码

故障诊断 | 基于小波包能量谱对滚动轴承的故障诊断Matlab代码 目录 故障诊断 | 基于小波包能量谱对滚动轴承的故障诊断Matlab代码效果一览基本介绍程序设计参考资料 效果一览 基本介绍 基于小波包能量谱对滚动轴承的故障诊断 matlab代码 数据采用的是凯斯西储大学数据 首先利用…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

rknn优化教程(二)

文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK&#xff0c;开始写第二篇的内容了。这篇博客主要能写一下&#xff1a; 如何给一些三方库按照xmake方式进行封装&#xff0c;供调用如何按…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...