Infrared receiver based on 51 single chip microcomputer

There are many communication principles for infrared receiving. The two commonly used methods are pulse width modulation (PWM) and pulse time modulation (PPM). Recently, the editor is trying to write an infrared receiving program based on pulse time modulation of 51 single-chip microcomputer. Some experience, share with you.

Principle analysis The
usual infrared remote control modulates the binary pulse code on a 38KHz carrier, buffers and amplifies it and sends it to the infrared light-emitting diode, which is converted into an infrared signal and emitted.
Because there are many forms of binary pulse code, to develop infrared receiving equipment, we must know the code carrier mode and carrier frequency of the infrared remote control before we can select the integrated infrared receiver and make a decoding scheme.
Below is the physical and schematic diagram of the infrared receiver I used

Insert picture description here

Insert picture description here
As you can see from the schematic diagram, the integrated infrared receiver I used has three pins, namely VCC, GND and data pins (used to transmit data).

Data format

Now that we know that it uses a data pin to transmit data, how is the data transmitted? What is the data format that is transmitted once?

Insert picture description here
Here, you can clearly see that the data consists of five pieces of data.

First, it will give a start code composed of a low level of 9ms and a high level of 4.5ms, telling us that we are going to transmit data next, and then start to transmit a 32-bit binary data code.

Since it has only one data pin, we have to use this data pin to determine whether the data it transmits is binary '0' or '1'.

Insert picture description here
It can be seen here that regardless of the data transmission '0' or '1', it will first transmit 0.56ms, which is a low level of 560us, which is used to determine the end of the previous data and the beginning of the next data. As for the data transmitted, it is Use the next high level time to judge.

The high level time of 565um is the data '0', and 1690um is the data '1'. Due to the influence of environmental factors in the actual data transmission, we need to take an intermediate value to judge. If the intermediate value is exceeded, the data is "1", and vice versa is the data "0".

Code

The theory has been talked for so long, it is probably boring, let's start analyzing the code.
Important: The code format must be standardized!

void main(void)
{
    
    
//我们使用的是51单片机,所以可以使用定时器来计时。
//对于延时函数,确实很方便,但是小编强烈不推荐使用延时函数,能用定时器解决的尽量不使用延时函数。
//延时函数时间不准确,至于为什么不使用延时函数,小编之后会单独写一篇来解释。
	TMOD = 0x01;//这儿打开定时器1,用来计时。
	TR0 = 0;	//关闭允许定时器1计时,当我们需要定时器1计时的时候再打开。
	IT0 = 1;
	EX0 = 1;	//这两句是51单片机的外部中断1允许,并且下降沿触发,因为红外数据最开始是9ms低电平,所以可以使用外部中断(不使用中断也行)。
	EA = 1;		//打开总中断
	while (1)
	{
    
    
		//while(1)循环中的代码后面会单独列出。
	}
}

The above is the configuration that our program needs to open.
Next is the external interrupt program

bit InFrared_Way = 0;			//在程序的开头我定义了一个一字节的变量,至于作用,接下来会讲。

void Int_0(void) interrupt 0	//外部中断程序
{
    
    
//最开始我是直接在外部中断里面写红外解码程序,但是我发现无论如何都无法进入中断程序(可能是我代码的问题)。
//然后我又想到我的老师跟我说过外部中断程序越简洁越好,我就改成了现在这样。
	InFrared_Way  = 1;			//让变量置1,从而在主程序里判断接受到红外信号。
}

Below is the code in the main function while(1)

	if (InFrared_Way == 1)	//判断是否接收到红外信号,若是能接收到信号,则进入函数。
	{
    
    
		EX0 = 0;			//关闭外部中断,防止干扰。
		TR0 = 1;			//允许定时器1计时。
		InFrared_Init();	//这是我写的红外接收函数,下面会提到,这儿不做过多解释。
		TR0 = 1;			//关闭允许定时器1计时。
		EX0 = 1;			//打开外部中断。
		InFrared_Way = 0;	//清零InFrared_Way ,标志着已经结束红外接收。
	}

Only the infrared receiver function is left

sbit INIR = P3^2;				//51单片机的引脚定义,我的51板子上数据引脚连接的是P3^2引脚。
unsigned char Data[4] = {
    
    0};	//定义四组8位的数据,刚好储存红外信号的32位数据。

void InFrared_Init(void)		//这个就是上面提到的红外接收函数。
{
    
    
	unsigned char i, j;			//因为定义了4个数据,每个数据8个位,所以这儿用i表示是哪个数据,j表示数据哪个位。

	TH0 = 0;
	TL0 = 0;					//将定时器1的时间清0,方便计时。
	while (INIR == 0 && TH0 <= 35);	//等待9ms低电平过去。
	if (INIR == 1)				//判断是否为高电平。
	{
    
    
		while (INIR == 1 && TH0 <= 55);	//等待4.5ms高电平过去。
//开始接收数据。
		for (i = 0; i < 4; i++)
		{
    
    
			for (j = 0; j < 8; j++)	//接收4组8位数据。
			{
    
    
				TH0 = 0;
				TL0 = 0;					//将定时器1的时间清0,方便计时。
				while (INIR == 0 && TH0 <= 3);	//等待560us低电平过去。
				while (INIR == 1);	//判断高电平时间。
				Data[i] >>= 1;	//数据左移一位,使接收位默认为0,因为数据是由低位开始接收。
				if (TH0 >= 7)	//判断是否超过中间值,超过就是数据1。
				{
    
    
					Data[i] |= 0x80;	//数据写1,默认为0,所以只需要有写1的操作。
				}
			}
		}
	}
}

So far, all the functions are shared!

Of course, I don't want to copy a piece of code, I thoughtfully put the above code synthesised below!

#include <STC12C5A60S2>		//这个根据自己的51单片机芯片来修改。

sbit INIR = P3^2;			//这个根据自己定义引脚。
bit InFrared_Way = 0;
unsigned char Data[4] = {
    
    0};

void InFrared_Init(void);

void main(void)
{
    
    
	TMOD = 0x01;
	TR0 = 0;
	IT0 = 1;
	EX0 = 1;
	EA = 1;
	while (1)
	{
    
    
		if (InFrared_Way == 1)
		{
    
    
			EX0 = 0;
			TR0 = 1;
			InFrared_Init();
			TR0 = 1;
			EX0 = 1;
			InFrared_Way = 0;
		}
	}
}

void Int_0(void) interrupt 0
{
    
    
	InFrared_Way  = 1;
}

void InFrared_Init(void)
{
    
    
	unsigned char i, j;
	
	TH0 = 0;
	TL0 = 0;
	while (INIR == 0 && TH0 <= 35);
	if (INIR == 1)
	{
    
    
		while (INIR == 1 && TH0 <= 55);
		for (i = 0; i < 4; i++)
		{
    
    
			for (j = 0; j < 8; j++)
			{
    
    
				TH0 = 0;
				TL0 = 0;
				while (INIR == 0 && TH0 <= 3);
				while (INIR == 1);
				Data[i] >>= 1;
				if (TH0 >= 7)
				{
    
    
					Data[i] |= 0x80;
				}
			}
		}
	}
}

Thought it was over? of course not

The editor’s code does not process 4 sets of data because everyone uses different displays. The editor uses 0.96 inch OLED to process 4 sets of data. Some people may use digital tubes to display. Since infrared is only discussed here, other things are not introduced.

(The following only represents my personal opinion. If someone is willing to guide you
, I am grateful!) For these four sets of data, the third set of 10 data from 0 to 9 on the remote control I used at the beginning is connected in sequence. The.

E.g:

If the data code of 0 is 0x10, then the data code of 1 is 0x11.

However, after I changed a remote control, the data codes of 0-9 are not connected together. Therefore, at present, I think that I cannot judge the data codes of 1-9 by just looking at the data code of 0. Seek truth from facts to verify each one.

thank you all! Like and follow the blogger, hee hee

Guess you like

Origin blog.csdn.net/weixin_53624282/article/details/114003211