问题来源:
请看下列链接:
格力空调红外编码解析
在了解前。需知道啥是红外?了解基本原理等。
好了,直接上我的代码;仅供参考,如不能正常接收空调红外数值,勿喷!
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,然后关闭打印? ,循坏
参考链接:
【智能电表】格力空调遥控器红外协议https://blog.csdn.net/qq1518572311/article/details/8074750838KHz,NEC红外模拟发送和接收程序https://www.1024sou.com/article/218998.html
|