I have found many infrared receiving and decoding programs on the Internet these days, but none of them are very ideal. Generally, they use delay as data of 0 and 1, or the comments are not very detailed, so I made one myself.
This program uses external interrupt plus timer 1 to realize infrared decoding. The ABCD ports of STM8S microcontroller can be used as external interrupts, and the remote controllers used are most of those on the market.
Friends in need can use it as a reference.
The actual picture produced is as follows:
Rendering
The microcontroller source program is as follows:
/***************The user code can be identified and decoded successfully, and then displayed at 1602 and the LED flashes once*****************/
#include "iostm8s208mb.h" //header file of the main control chip
#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
#define LED PI_ODR_ODR3
#define IR_IN PC_IDR_IDR1
#define LCD_EN PF_ODR_ODR4
#define LCD_RS PF_ODR_ODR0
#define LCD_DATA PB_ODR
//#define BUSY PB_ODR_ODR7
u16 LowTime, HighTime; //Store the width of high and low levels
u8 Counter_Time_H,Counter_Time_L;
u8 a[4]; //Store the code values as user code, user inverse code, data code, and data inverse code
u8 tab[ ]= {"1602IR-CODE TEST"};
void delay_us(u16 n)
{
n<<=2;
while(--n);
}
void delay_ms(u16 t)
{
while(t--)
{
delay_us(1000);
}
}
void GPIO_Init(void)
{
EXTI_CR1|=0x20; //Configure PC to trigger only on falling edge
PI_DDR_DDR3=1; //LED
PI_CR1_C13=1;
PI_CR2_C23=1;
LED=1;
PC_DDR_DDR1=0;//IR_IN
PC_CR1_C11=1;
PC_CR2_C21=1;
PF_DDR_DDR4=1;//EN
PF_CR1_C14=1;
PF_CR2_C24=1;
PF_DDR_DDR0=1;//RS
PF_CR1_C10=1;
PF_CR2_C20=1;
PB_DDR=0xff;//DATA
PB_CR1=0xff;
PB_CR2=0xff;
}
void Write_Com(u8 com)
{
LCD_RS=0;
LCD_DATA=com;
delay_ms(5);
LCD_EN=1;
delay_ms(5);
LCD_EN=0;
}
void Write_Data(u8 data)
{
LCD_RS=1;
LCD_DATA=data;
delay_ms(5);
LCD_EN=1;
delay_ms(5);
LCD_EN=0;
}
void LCD_Init(void)
{
LCD_EN=0;
Write_Com(0x38);
Write_Com(0x0c);
Write_Com(0x06);
Write_Com(0x01);
}
void TIM1_Init(void)
{
TIM1_CR1=0x00; //close timer1
TIM1_IER = 0x01; //Enable update interrupt
TIM1_PSCRH=0x00; //16Mhz/16=1us, 16 division
TIM1_PSCRL=0x0f;
//TIM1_CNTRH=0x00;
//TIM1_CNTRL=0x00;
TIM1_ARRH=0xff; //Automatically load the maximum value
TIM1_ARRL=0xff;
}
void Clock_Init(void)
{
CLK_CKDIVR=0x00; //16M
}
void LED_ACT(void) // Too long a delay will affect sensitivity
{
LED = 0;
delay_ms(10);
LED=1;
delay_ms(10);
}
u8 DeCode(void)
{
u8 i,j;
u8 temp; //temporary variable
for(i=0;i<4;i++) //
{
for(j=0;j<8;j++) //
{
temp=temp>>1; //
TIM1_CNTRH=0;
TIM1_CNTRL=0;
TIM1_CR1|=0x01;
while(IR_IN==0); //First determine whether it is 0
TIM1_CR1=0x00;
Counter_Time_H=TIM1_CNTRH;
Counter_Time_L=TIM1_CNTRL;
LowTime=Counter_Time_H*256+Counter_Time_L; //
TIM1_CNTRH=0;
TIM1_CNTRL=0;
TIM1_CR1|=0x01;
while(IR_IN==1); //Judge whether it is 1
TIM1_CR1=0x00;
Counter_Time_H=TIM1_CNTRH;
Counter_Time_L=TIM1_CNTRL;
HighTime=Counter_Time_H*256+Counter_Time_L;
if((LowTime<420)||(LowTime>690))
return 0; //Too big or too small to be discarded
if((HighTime>460)&&(HighTime<660))
temp=temp&0x7f; //"0" 560us+-100
if((HighTime>1480)&&(HighTime<1880))
temp=temp|0x80; //"1" 1680us+-500
}
a[i]=temp;
}
// if(a[2]==~a[3])
return 1;
}
void two_2_bcd(u8 data) //Convert binary code to BCD code
{
u8 temp; //temporary storage
temp=data;
data&=0xf0;
data>>=4;
data&=0x0f;
if(data<=0x09)
{
Write_Data(0x30+data); //Display 0-9
}
else
{
data=data-0x09;
Write_Data(0x40+data); //Display AF
}
data=temp;
data&=0x0f;
if(data<=0x09)
{
Write_Data(0x30+data);
}
else
{
data=data-0x09;
Write_Data(0x40+data);
}
Write_Data(0x48); //Display "H"
}
void Disp_1(void) //Display the second line: code value
{
Write_Com(0x80+0x40);
two_2_bcd(a[0]);
Write_Data(0x20); //Space
two_2_bcd(a[1]);
Write_Data(0x20); //Space
two_2_bcd(a[2]);
Write_Data(0x20); //Space
two_2_bcd(a[3]);
}
void Disp_2(void) //Display the first line: fixed characters
{
u8 num; //
Write_Com(0x80);
for(num=0;num<16;num++)
{
Write_Data(tab[num]);
delay_ms(5);
}
}
void CHECK_User(void)
{
// if((a[0]==0x00)&&(a[1]==0xff)) // Determine user code and inverse code
// {
LED_ACT();
// }
}
void main(void)
{
asm("sim"); //The priority of the MAIN program is configured as level 3 (turn off the total interrupt)
GPIO_Init();
Clock_Init();
TIM1_Init();
LCD_Init();
//delay_ms(10);
Write_Com(0x01); //Clear screen
Disp_2();
asm("rim"); //The priority of the MAIN program is reduced from level 3 to level 0 (turn on the total interrupt)
while(1); // infinite loop
}
#pragma vector=0x07
__interrupt void EXTI_PORTC_IRQHandler(void)
{
PC_CR2_C21=0; //Disable PC0 port external interrupt
TIM1_CNTRH=0;
TIM1_CNTRL=0;
TIM1_CR1=0x01; //open timer1
while(IR_IN==0);
TIM1_CR1=0x00; //
Counter_Time_H=TIM1_CNTRH;
Counter_Time_L=TIM1_CNTRL;
LowTime=Counter_Time_H*256+Counter_Time_L;
TIM1_CNTRH=0; //
TIM1_CNTRL=0; //
TIM1_CR1=0x01; //
while(IR_IN==1); //
TIM1_CR1=0x00; //
Counter_Time_H=TIM1_CNTRH;
Counter_Time_L=TIM1_CNTRL;
HighTime=Counter_Time_H*256+Counter_Time_L;
if((LowTime>8500)&&(LowTime<9500)&&(HighTime>4000)&&(HighTime<5000)) //Boot code 9000us+-500 4500us+-500
{
if(DeCode()==1)
{
Disp_1();
CHECK_User();
}
}
PC_CR2_C21=1; //Enable PC0 port external interrupt
}
#pragma vector=0x0D
__interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)
{
TIM1_SR1&=0xfe; //Clear overflow interrupt flag "UIF"
}
Previous article:The STM8 microcontroller of the car screen drives the 128x16 dot matrix screen to output Chinese characters
Next article:stm8s105k4 microcontroller PWM wave configuration
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- 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
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- [Xianji HPM6750 Review 5] LittlevGL transplantation using SPI display
- How to measure BLE power consumption
- TI Embedded Live Month - Registration starts now to support efficient, intelligent and low-power system design~
- Four input modes of MCU
- How to replace TMS320C6416TGLZ7 chip
- I would like to ask how to connect the ground on the PCB board of the monitoring equipment and the board ground?
- Overvoltage, overcurrent and overtemperature detection circuit
- Recruitment: Assistant Optical Engineer, Assistant Electronic Engineer, Assistant CAE Engineer, Assistant Structural Engineer
- PCB checklist summary
- Multi-core DSP products in the SoC era