The infrared ray starts to send a 13.5ms guide code, which consists of a 9ms high level and a 4.5ms low level. The guide code is followed by the system code, the system inverse code, the key code, and the key inverse code. If the key is pressed, the remote control will send a repeat code, which consists of a 9ms high level, a 2.25ms low level, and a short pulse. This program comes from the Internet, the copyright belongs to the source author, and is only for learning and communication! It cannot be used for commercial purposes. This program has been tried and can decode the codes of most remote controls!
#include "at89x52.h"
#define NULL 0x00 //Invalid data
#define RESET 0X01 //Program reset
#define REQUEST 0X02 //Request signal
#define ACK 0x03 //Acknowledgement signal. After receiving data, sending ACK signal indicates that the data is received correctly.
It is also the acknowledgement signal of the request signal
#define NACK 0x04 //Acknowledgement signal, indicating that the received data is wrong
#define BUSY 0x05 //Busy signal, indicating busy
#define FREE 0x06 //Free signal, indicating idle state
#define READ_IR 0x0b //Read infrared
#define STORE_IR 0x0c //Save data
#define READ_KEY 0x0d //Read key value
#define RECEIVE 0Xf400 //Start address of receiving buffer
#define SEND 0xfa00 //Start address of sending buffer
#define IR 0x50 // infrared receiving buffer start address
#define HEAD 0xaa // data frame header
#define TAIL 0x55 // data frame tail
#define SDA P1_7
#define SCL P1_6
unsigned char xdata *buf1; // receiving data buffer
unsigned int buf1_length; // actual length of received data
unsigned char xdata *buf2; // sending data buffer
unsigned int buf2_length; // actual length of data to be sent
bit buf1_flag; // receiving flag, 1 means receiving a data frame, 0 means not receiving a data frame or data
frame is empty
bit buf2_flag; // sending flag, 1 means need to send or not sent, 0 means no data to send or
sent
unsigned char state1,state2; // used to mark the status of receiving characters, state1 is used to indicate receiving
status, state2 is used to indicate sending status
unsigned char data *ir;
union{
unsigned char a[2];
unsigned int b;
unsigned char data *p1[2];
unsigned int data *p2[2];
unsigned char xdata *p3; //Infrared buffer pointer
unsigned int xdata *p4;
}p;
//union{ //
// unsigned char a[2]; //
// unsigned int b;
// unsigned char data *p1[2];
// unsigned int data *p2[2];
// unsigned char xdata * p3;
// unsigned int xdata *p4; //address pointer
//}q; //
union{
unsigned char a[2];
unsigned int b;
}count;
union{
unsigned char a[2];
unsigned int b;
}temp;
union{
unsigned char a[4];
unsigned int b[2];
unsigned long c;
}ir_code;
union{
unsigned char a[4];
unsigned int b[2];
unsigned long c;
unsigned char data *p1[4];
unsigned int data *p2[4];
unsigned char xdata *p3[2];
unsigned int xdata *p4[2];
}I;
unsigned char ir_key;
bit ir_flag; //Infrared receiving flag, 0 means buffer is empty, 1 means reception is successful, 2 means buffer overflow
void sub(void);
void delay(void);
void ie_0(void);
void tf_0(void);
void ie_1 (void);
void tf_1(void);
void tf_2(void);
void read_ir(void); void ir_jiema(
void); void ir_init(void); void ir_exit(void); void store_ir(void); void read_key(void ); void reset_iic(void); unsigned char read_byte_ack_iic(void); unsigned char read_byte_nack_iic(void); bit write_byte_iic(unsigned char a); void send_ack_iic(void); void send_nack_iic(void); bit receive_ack_iic(void); void start_iic (void); void stop_iic(void); void write_key_data(unsigned char a); unsigned int read_key_data(unsigned char a); void ie0(void) interrupt 0{ie_0();} void tf0(void) interrupt 1{tf_0();} void ie1 (void) interrupt 2{ie_1();} void tf1(void) interrupt 3{tf_1();tf_2();} void tf2(void) interrupt 5{ //Use the interrupt method and the query method to decode EA =0; //Disable interrupt if(TF2){ //Judge whether the interrupt is caused by overflow or level change TF2=0; //If the interrupt is caused by overflow, clear the overflow bit and reopen the interrupt to exit EA=1; goto end; } EXF2=0; //Clear the interrupt bit generated by the level change *ir=RCAP2H; //Save the captured number ir++; *ir=RCAP2L; *ir++; F0=1; TR0=1; //Start counter 0 loop: TL0=0; //Reset counter 0 to zero TH0=0; while(!EXF2){ //Query and wait for EXF2 to become 1 if(TF0) goto exit; //Check if timeout has occurred, exit if timeout }; EXF2=0; //Clear EXF2if (!TH0) //Judge if it is a long low level pulse { //Not a long low level pulse Flat pulse but short low level if(F0)count.b++; //Short pulse number plus one temp.a[0]=RCAP2H; //Store the captured number temporarily temp.a[1]=RCAP2L; goto loop; //Return and continue query } else{ //If it is a low level pulse, process it F0=0; *ir=temp.a[0]; //Record the total time of continuous short pulses ir++; *ir =temp.a[1]; ir++; *ir=RCAP2H; //Record the long level pulse time ir++; *ir=RCAP2L; ir++; if(ir>=0xda) {
goto exit; //Judge whether the buffer overflows, if overflow, exit after failure
}
goto loop; //Return and continue query
}
exit:
ir_flag=1; //Set ir_flag to 1 to indicate successful receptionend
:
;
}
void rs232(void) interrupt 4{
static unsigned char sbuf1,sbuf2,rsbuf1,rsbuf2; //sbuf1,sbuf2 are used for receiving
temporary use, rsbuf1,rsbuf2 are used to store the half byte of receiving and sending
EA=0; //Disable interruptsif
(RI){
RI=0; //Clear the receive interrupt flag
sbuf1=SBUF; //Copy the characters in the receive buffer to sbuf1
if(sbuf1==HEAD){ //Judge whether it is the beginning of the frame
state1=10; //If yes, assign state to 10
buf1=RECEIVE; //Initialize the receiving address
}
else{
switch(state1){
case 10:sbuf2=sbuf1>>4; //Shift the high nibble to the nibble
sbuf2=~sbuf2; //Invert the low nibble
if((sbuf2&0x0f)!=(sbuf1&0x0f)) //Judge whether the reception is correct
{ //Reception error, it is possible that the data frame tail is received, or it is possible that the reception error is
if(sbuf1==TAIL) //Judge whether the data frame tail is received
{ //Yes, the data frame tail is received
buf1=RECEIVE; //Initialize the received address
if(*buf1==RESET) //Judge whether it is a reset command
{
ES=0;
sbuf2=SP+1;
for(p.p1[0]=SP-0x10;p.p1[0]<=sbuf2;p.p1
[0]++)*p.p1[0]=0;
}
state1=0; //Set the receive status flag to zero and receive the next data frame
buf1_flag=1; //Set the receive flag to 1, indicating that a data frame has been received
REN=0; //Disable reception
}
else
{ //Not receiving the end of the data frame, indicating a reception error
state1=0; //Set the reception status flag to zero and receive again
buf1=RECEIVE; //Initialize the send address
*buf1=NACK; //Store the NACK signal in the receive buffer
buf1_flag=1; //Set the flag to 1 so that the main program can handle the reception error
REN=0; //Disable reception
}
}
else
{ //Receive correctlyrsbuf1
=~sbuf1; //Invert the bit to change the high nibble to the original
codersbuf1&=0xf0; //Only keep the high nibble and remove the low nibblestate1
=20; //Set the status flag to 20 and prepare to receive the low nibble
}
break;
case 20:sbuf2=sbuf1>>4; //Shift the high nibble to the right nibblesbuf2
=~sbuf2; //Invert the low nibbleif
((sbuf2&0x0f)!=(sbuf1&0x0f)) //Judge whether the reception is correct
{ //Accept errorstate1
=0; //Set the receive status flag to zero and receive againbuf1
=RECEIVE; //Initialize the received address
*buf1=NACK; //Store the NACK signal in the send
bufferbuf1_flag=1; //Set the flag to 1 so that the main program can handle the receive errorREN
=0; //Disable reception
}
else
{
sbuf1&=0x0f; //Only keep the lower nibble and remove the upper nibblersbuf1
|=sbuf1; //Merge the upper and lower nibbles
*buf1++=rsbuf1; //Save the received data to the receive buffer, and add one to the data pointer buf1_length
++; //Increase the length of the received data
state1=10; //Set state1 to 10, and prepare to receive the upper nibble of the next byte
}
break;
}
}
}
else{
TI=0; //Clear the send interrupt flag
if(buf2_length) //Judge whether the send length is zero
{ //The send length is not zeroif
(state2==0) //Judge whether to send the upper nibble
{ //Send the upper nibble
sbuf2=*buf2; //Send the byte to be sent to sbuf2
rsbuf2=~sbuf2; //Invert to make the upper nibble into the inverse code
sbuf2>>=4; //Shift the upper nibble right to the lower nibblersbuf2
&=0xf0; //Retain the high nibble and remove the low nibble
sbuf2&=0x0f; //Retain the low nibble and remove the high nibble
rsbuf2|=sbuf2; //Merge the high and low nibbles
SBUF=rsbuf2; //Send out
state2=10; //Set state2 to 10 to prepare to send the lower nibble
}
else
{ //Send the low nibble
sbuf2=*buf2; //Send the byte to be sent to sbuf2
buf2++; // pointer plus one
buf2_length--; // send data length minus one
rsbuf2=~sbuf2; // invert to make the lower half byte into the inverse code
rsbuf2<<=4; // shift the inverse code of the lower half byte to the upper half byte
rsbuf2&=0xf0; // keep the upper half byte and remove the lower half byte
sbuf2&=0x0f; // keep the lower half byte and remove the upper half byte
rsbuf2|=sbuf2; // merge the high and low half bytes
SBUF=rsbuf2; // send out
state2=0;
}
}
else
{ // if the length of the data to be sent is zero, send the tail of the data frame
if(buf2_flag){ // determine whether the tail of the data frame has been sent
SBUF=TAIL; // send the tail of the data frame
while(TI==0);
TI=0;
buf2_flag=0; // set the send flag to zero, indicating that the sending is completed
}
}
}
EA=1; // open interrupt
}
Reference address:Infrared remote control software decoding principle and program (C language)
#include "at89x52.h"
#define NULL 0x00 //Invalid data
#define RESET 0X01 //Program reset
#define REQUEST 0X02 //Request signal
#define ACK 0x03 //Acknowledgement signal. After receiving data, sending ACK signal indicates that the data is received correctly.
It is also the acknowledgement signal of the request signal
#define NACK 0x04 //Acknowledgement signal, indicating that the received data is wrong
#define BUSY 0x05 //Busy signal, indicating busy
#define FREE 0x06 //Free signal, indicating idle state
#define READ_IR 0x0b //Read infrared
#define STORE_IR 0x0c //Save data
#define READ_KEY 0x0d //Read key value
#define RECEIVE 0Xf400 //Start address of receiving buffer
#define SEND 0xfa00 //Start address of sending buffer
#define IR 0x50 // infrared receiving buffer start address
#define HEAD 0xaa // data frame header
#define TAIL 0x55 // data frame tail
#define SDA P1_7
#define SCL P1_6
unsigned char xdata *buf1; // receiving data buffer
unsigned int buf1_length; // actual length of received data
unsigned char xdata *buf2; // sending data buffer
unsigned int buf2_length; // actual length of data to be sent
bit buf1_flag; // receiving flag, 1 means receiving a data frame, 0 means not receiving a data frame or data
frame is empty
bit buf2_flag; // sending flag, 1 means need to send or not sent, 0 means no data to send or
sent
unsigned char state1,state2; // used to mark the status of receiving characters, state1 is used to indicate receiving
status, state2 is used to indicate sending status
unsigned char data *ir;
union{
unsigned char a[2];
unsigned int b;
unsigned char data *p1[2];
unsigned int data *p2[2];
unsigned char xdata *p3; //Infrared buffer pointer
unsigned int xdata *p4;
}p;
//union{ //
// unsigned char a[2]; //
// unsigned int b;
// unsigned char data *p1[2];
// unsigned int data *p2[2];
// unsigned char xdata * p3;
// unsigned int xdata *p4; //address pointer
//}q; //
union{
unsigned char a[2];
unsigned int b;
}count;
union{
unsigned char a[2];
unsigned int b;
}temp;
union{
unsigned char a[4];
unsigned int b[2];
unsigned long c;
}ir_code;
union{
unsigned char a[4];
unsigned int b[2];
unsigned long c;
unsigned char data *p1[4];
unsigned int data *p2[4];
unsigned char xdata *p3[2];
unsigned int xdata *p4[2];
}I;
unsigned char ir_key;
bit ir_flag; //Infrared receiving flag, 0 means buffer is empty, 1 means reception is successful, 2 means buffer overflow
void sub(void);
void delay(void);
void ie_0(void);
void tf_0(void);
void ie_1 (void);
void tf_1(void);
void tf_2(void);
void read_ir(void); void ir_jiema(
void); void ir_init(void); void ir_exit(void); void store_ir(void); void read_key(void ); void reset_iic(void); unsigned char read_byte_ack_iic(void); unsigned char read_byte_nack_iic(void); bit write_byte_iic(unsigned char a); void send_ack_iic(void); void send_nack_iic(void); bit receive_ack_iic(void); void start_iic (void); void stop_iic(void); void write_key_data(unsigned char a); unsigned int read_key_data(unsigned char a); void ie0(void) interrupt 0{ie_0();} void tf0(void) interrupt 1{tf_0();} void ie1 (void) interrupt 2{ie_1();} void tf1(void) interrupt 3{tf_1();tf_2();} void tf2(void) interrupt 5{ //Use the interrupt method and the query method to decode EA =0; //Disable interrupt if(TF2){ //Judge whether the interrupt is caused by overflow or level change TF2=0; //If the interrupt is caused by overflow, clear the overflow bit and reopen the interrupt to exit EA=1; goto end; } EXF2=0; //Clear the interrupt bit generated by the level change *ir=RCAP2H; //Save the captured number ir++; *ir=RCAP2L; *ir++; F0=1; TR0=1; //Start counter 0 loop: TL0=0; //Reset counter 0 to zero TH0=0; while(!EXF2){ //Query and wait for EXF2 to become 1 if(TF0) goto exit; //Check if timeout has occurred, exit if timeout }; EXF2=0; //Clear EXF2if (!TH0) //Judge if it is a long low level pulse { //Not a long low level pulse Flat pulse but short low level if(F0)count.b++; //Short pulse number plus one temp.a[0]=RCAP2H; //Store the captured number temporarily temp.a[1]=RCAP2L; goto loop; //Return and continue query } else{ //If it is a low level pulse, process it F0=0; *ir=temp.a[0]; //Record the total time of continuous short pulses ir++; *ir =temp.a[1]; ir++; *ir=RCAP2H; //Record the long level pulse time ir++; *ir=RCAP2L; ir++; if(ir>=0xda) {
goto exit; //Judge whether the buffer overflows, if overflow, exit after failure
}
goto loop; //Return and continue query
}
exit:
ir_flag=1; //Set ir_flag to 1 to indicate successful receptionend
:
;
}
void rs232(void) interrupt 4{
static unsigned char sbuf1,sbuf2,rsbuf1,rsbuf2; //sbuf1,sbuf2 are used for receiving
temporary use, rsbuf1,rsbuf2 are used to store the half byte of receiving and sending
EA=0; //Disable interruptsif
(RI){
RI=0; //Clear the receive interrupt flag
sbuf1=SBUF; //Copy the characters in the receive buffer to sbuf1
if(sbuf1==HEAD){ //Judge whether it is the beginning of the frame
state1=10; //If yes, assign state to 10
buf1=RECEIVE; //Initialize the receiving address
}
else{
switch(state1){
case 10:sbuf2=sbuf1>>4; //Shift the high nibble to the nibble
sbuf2=~sbuf2; //Invert the low nibble
if((sbuf2&0x0f)!=(sbuf1&0x0f)) //Judge whether the reception is correct
{ //Reception error, it is possible that the data frame tail is received, or it is possible that the reception error is
if(sbuf1==TAIL) //Judge whether the data frame tail is received
{ //Yes, the data frame tail is received
buf1=RECEIVE; //Initialize the received address
if(*buf1==RESET) //Judge whether it is a reset command
{
ES=0;
sbuf2=SP+1;
for(p.p1[0]=SP-0x10;p.p1[0]<=sbuf2;p.p1
[0]++)*p.p1[0]=0;
}
state1=0; //Set the receive status flag to zero and receive the next data frame
buf1_flag=1; //Set the receive flag to 1, indicating that a data frame has been received
REN=0; //Disable reception
}
else
{ //Not receiving the end of the data frame, indicating a reception error
state1=0; //Set the reception status flag to zero and receive again
buf1=RECEIVE; //Initialize the send address
*buf1=NACK; //Store the NACK signal in the receive buffer
buf1_flag=1; //Set the flag to 1 so that the main program can handle the reception error
REN=0; //Disable reception
}
}
else
{ //Receive correctlyrsbuf1
=~sbuf1; //Invert the bit to change the high nibble to the original
codersbuf1&=0xf0; //Only keep the high nibble and remove the low nibblestate1
=20; //Set the status flag to 20 and prepare to receive the low nibble
}
break;
case 20:sbuf2=sbuf1>>4; //Shift the high nibble to the right nibblesbuf2
=~sbuf2; //Invert the low nibbleif
((sbuf2&0x0f)!=(sbuf1&0x0f)) //Judge whether the reception is correct
{ //Accept errorstate1
=0; //Set the receive status flag to zero and receive againbuf1
=RECEIVE; //Initialize the received address
*buf1=NACK; //Store the NACK signal in the send
bufferbuf1_flag=1; //Set the flag to 1 so that the main program can handle the receive errorREN
=0; //Disable reception
}
else
{
sbuf1&=0x0f; //Only keep the lower nibble and remove the upper nibblersbuf1
|=sbuf1; //Merge the upper and lower nibbles
*buf1++=rsbuf1; //Save the received data to the receive buffer, and add one to the data pointer buf1_length
++; //Increase the length of the received data
state1=10; //Set state1 to 10, and prepare to receive the upper nibble of the next byte
}
break;
}
}
}
else{
TI=0; //Clear the send interrupt flag
if(buf2_length) //Judge whether the send length is zero
{ //The send length is not zeroif
(state2==0) //Judge whether to send the upper nibble
{ //Send the upper nibble
sbuf2=*buf2; //Send the byte to be sent to sbuf2
rsbuf2=~sbuf2; //Invert to make the upper nibble into the inverse code
sbuf2>>=4; //Shift the upper nibble right to the lower nibblersbuf2
&=0xf0; //Retain the high nibble and remove the low nibble
sbuf2&=0x0f; //Retain the low nibble and remove the high nibble
rsbuf2|=sbuf2; //Merge the high and low nibbles
SBUF=rsbuf2; //Send out
state2=10; //Set state2 to 10 to prepare to send the lower nibble
}
else
{ //Send the low nibble
sbuf2=*buf2; //Send the byte to be sent to sbuf2
buf2++; // pointer plus one
buf2_length--; // send data length minus one
rsbuf2=~sbuf2; // invert to make the lower half byte into the inverse code
rsbuf2<<=4; // shift the inverse code of the lower half byte to the upper half byte
rsbuf2&=0xf0; // keep the upper half byte and remove the lower half byte
sbuf2&=0x0f; // keep the lower half byte and remove the upper half byte
rsbuf2|=sbuf2; // merge the high and low half bytes
SBUF=rsbuf2; // send out
state2=0;
}
}
else
{ // if the length of the data to be sent is zero, send the tail of the data frame
if(buf2_flag){ // determine whether the tail of the data frame has been sent
SBUF=TAIL; // send the tail of the data frame
while(TI==0);
TI=0;
buf2_flag=0; // set the send flag to zero, indicating that the sending is completed
}
}
}
EA=1; // open interrupt
}
Previous article:AT89S51 and AT89C2051 microcontroller pin introduction
Next article:DS18B20 temperature measurement and display program
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
MoreDaily News
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
Guess you like
- Relationship between ACM9226 ADC sampling result and voltage value
- Controlling Hardware with Python - Automating Frequency Response Testing of Conditioning Circuits
- Dual full-function USB-C interface display solution, specific implementation application description
- What is a directional coupler? Three topologies of directional couplers
- Step 1: Preliminary research, DIY high-efficiency bidirectional DC-DC converter from scratch!
- How are the three types of RFID technologies distinguished?
- Ended-- Live [Microchip Embedded Security Solutions | Trust Your Firmware: Secure Boot Application Processors]
- How does a water leak detector work?
- pads VX.2.1 router problem
- Detailed explanation of AP and STA working modes of wireless Wifi module