如何用单片机51.或者52,采集格力空调红外码值?

问题来源:

请看下列链接:

格力空调红外编码解析

在了解前。需知道啥是红外?了解基本原理等。

好了,直接上我的代码;仅供参考,如不能正常接收空调红外数值,勿喷!

main.c

#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
#include <stdio.h>
typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit IRIN=P3^2;

u8 IrValue1[6];
u8 IrValue2[6];
u8 Time;

//add
unsigned char Sec;
u8 thirty_five_data_flag=0;
bit flag_Ir;                         //红外接收完成标志位

//延时函数,i=1时,大约延时10us
void delay(u16 i)
{
	while(i--);	
}

void delay7us(void)   //误差 0us @12.0 Mhz
{
    unsigned char a;
    for(a=1;a>0;a--);
}
void delay100us(void)   //误差 0us @12.0 Mhz
{
    unsigned char a,b;
    for(b=19;b>0;b--)
        for(a=1;a>0;a--);
}

void delay8ms(void)   //误差 0us @12.0 Mhz
{
    unsigned char a,b;
    for(b=205;b>0;b--)
        for(a=18;a>0;a--);
}

//add
void DelayMS(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
void delay20ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=215;b>0;b--)
        for(a=45;a>0;a--);
}

/**
  * @brief  串口初始化,4800bps@12.000MHz
  * @param  无
  * @retval 无
  */
void UART_Init()
{
	SCON=0x40;
	PCON |= 0x80;
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xF3;		//设定定时初值
	TH1 = 0xF3;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}

/**
  * @brief  串口发送一个字节数据
  * @param  Byte 要发送的一个字节数据
  * @retval 无
  */
void UART_SendByte(unsigned char Byte)
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

// void UsartInit()
// {
// 	SCON=0X50;			//设置为工作方式1
// 	TMOD|=0X20;			//设置计数器工作方式2
// 	PCON|=0X80;			//波特率加倍
// 	TH1=0XF3;			//计数器初始值设置,注意波特率是4800的
// 	TL1=0XF3;
// //	ES=1;				//打开接收中断
// //	EA=1;				//打开总中断
// 	TR1=1;				//打开计数器
// }

void IrInit()
{
	IT0=1;//下降沿触发
	EX0=1;//打开中断0允许
	EA=1;	//打开总中断
	IRIN=1;//初始化端口
	flag_Ir = 0;                         //初始化接收完成标志位 add
}

int main()
{		
	int i= 0;
	int j= 0;	
	UART_Init();			//串口初始化
	IrInit();
	while(1)
	{
		if(Sec < 6){
			UART_SendByte(Sec);	//串口发送一个字节
			Sec++;				//Sec自增
			DelayMS(1000);		//延时1秒
		}
		
		if(flag_Ir){
			flag_Ir = 0;
			UART_SendByte(IrValue1[i]);
			UART_SendByte(IrValue1[i++]);
			UART_SendByte(IrValue1[i++]);
			UART_SendByte(IrValue1[i++]);
			UART_SendByte(IrValue1[i++]);
			UART_SendByte(IrValue2[j]);
			UART_SendByte(IrValue2[j++]);
			UART_SendByte(IrValue2[j++]);
			UART_SendByte(IrValue2[j++]);

			Sec = 0;
			i = 0;
			j = 0;
		}
	}
	return 0;
}

void ReadIr() interrupt 0
{
	u8 j,k;
	u16 err;
	EA = 0;//add
	Time = 0;					 
	//delay(700);	//延时7ms,为判断9ms低电平起始码做准备
	delay8ms();//延时8ms,为判断9ms低电平起始码做准备
	if(IRIN==0)	//确认是否真的接收到正确的信号
	{
		//err=1000;//1000*10us=10ms,超过说明接收到错误的信号
		err=500;//500*10us=5ms,超过说明接收到错误的信号
		/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
		侯,程序死在这里*/	
		while((IRIN==0)&&(err>0))	//等待前面9ms的低电平过去  		
		{
			//delay(1);
			delay100us();
			err--;
		} 
		if(IRIN==1)	//如果正确等到9ms低电平
		{
			err=500;
			while((IRIN==1)&&(err>0))	//等待4.5ms的起始高电平过去
			{
				//delay(1);
				delay100us();
				err--;
			}

			//35位数据码
			for(k=0;k<5;k++){
				for(j=0;j<8;j++){
					if(thirty_five_data_flag == 35){
						thirty_five_data_flag = 0;
						break;
					}
					thirty_five_data_flag++;
					err = 60;
					while ((IRIN == 0) && (err > 0))
					{
						delay100us();
						err--;
					}
					err = 500;
					while ((IRIN == 1) && (err > 0))
					{
						delay100us();
						Time++;
						err--;
						if(Time > 50){
							break;
						}
					}
					IrValue1[k] >>= 1;
					if(Time >= 8)IrValue1[k] |= 0x80;
					Time = 0;
				}
			}

			//add  connect code ....test2 -----------------
			//连接码:646us低电平 + 20000us高电平;
			err = 60;
			while((IRIN==0)&&(err>0))//等待信号前面的646us低电平过去
			{
				delay100us();
				err--;
			}
			err = 1980;
			while((IRIN==1)&&(err>0)){
				err--;
			}
			//add 32 位数据
			for(k=0;k<4;k++){
				for(j=0;j<8;j++){
					err = 60;
					while ((IRIN == 0) && (err > 0))
					{
						delay100us();
						err--;
					}
					err = 500;
					while ((IRIN == 1) && (err > 0))
					{
						delay100us();
						Time++;
						err--;
						if(Time > 50){
							EA = 1;
							break;
						}
					}
					IrValue2[k] >>= 1;
					if(Time >= 8)IrValue2[k] |= 0x80;
					Time = 0;
				}
			}
		
		}

		if(IrValue1[2] = ~IrValue1[3]){
			flag_Ir =1;
		}
	}
	EA  =1;			//add
}

以上代码;波特率4800, 使用STC52单片机,测试某空调红外遥控打印红外码值 成功。

代码逻辑是:接到红外码值后,打印5秒1.2.3.4.5,然后关闭打印  ,循坏

参考链接:

【智能电表】格力空调遥控器红外协议icon-default.png?t=M276https://blog.youkuaiyun.com/qq1518572311/article/details/8074750838KHz,NEC红外模拟发送和接收程序icon-default.png?t=M276https://www.1024sou.com/article/218998.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Teleger

你的支持是我前进的方向

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值