1. Brief Introduction
Infrared remote control is a wireless, non-contact control technology with strong anti-interference ability, reliable information transmission, low power consumption and low cost.
The encoding methods for infrared remote control that are currently widely used are: NEC protocol for PWM (pulse width modulation) and RC-5 protocol for Philips PPM (pulse position modulation).
1.1 NEC Protocol Definition
The bit definition of NEC code: One pulse corresponds to a continuous carrier of 560us. It takes 2.25ms (560us pulse + 1680us low level) to transmit a logic 1, and 1.125ms (560us pulse + 560us low level) to transmit a logic 0. The remote control receiver is at a low level when it receives a pulse, and at a high level when there is no pulse. In this way, the signal we receive at the receiving head is: logic 1 should be 560us low + 1680us high, and logic 0 should be 560us low + 560us high.
Transmitter logic:
Remote control receiving head logic:
1.2 NEC Protocol Features
(1) 8-bit address and 8-bit instruction length;
(2) Address and command are transmitted twice (to ensure reliability);
(3) PWM pulse position modulation, using the duty cycle of the transmitted infrared carrier to represent "0" and "1";
(4) The carrier frequency is 38Khz;
(5) The bit time is 1.125ms or 2.25ms;
1.3 Data format of NEC remote control commands
The reverse code is used to increase the reliability of transmission. The continuous code specified by the NEC code (composed of 9ms low level + 2.5m high level + 0.56ms low level + 97.94ms high level) will send a repeated code, i.e. a continuous code, if the key is not released after a frame of data is sent.
2. Software Implementation
Above we have a basic understanding of the NEC format of infrared code sending and receiving, and we can complete the corresponding program according to the communication protocol.
Program logic:
2.1 Initialization
void Remote_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //Pull-down input
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_1);
TIM_TimeBaseStructure.TIM_Period = 10000; //Set the automatic reload value, 10ms overflow
TIM_TimeBaseStructure.TIM_Prescaler = (72-1); //Prescaler, 1MHz counting frequency, 1us plus one
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //Clock division
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //Upward counting mode
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; //IC2 is mapped to TI5
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //Rising edge capture
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //No frequency division
TIM_ICInitStructure.TIM_ICFilter = 0x03; //IC4F = 0011, input filter 8 timer clock cycle filtering
TIM_ICInit(TIM5,&TIM_ICInitStructure); //Initialize the timer input capture channel
TIM_Cmd(TIM5,ENABLE); //Enable timer 5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;//TIM5中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //Preemption priority 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //From priority 3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE); //Enable update interrupt, allow CC2IE to capture interrupt
}
2.2 Interrupt capture
u8 RmtSta=0;
u16 Dval;
u32 RmtRec=0;
u8 RmtCnt=0;
void TIM5_IRQHandler(void)
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)!= RESET)
{
if(RmtSta&0x80) //Data received flag
{
RmtSta &= ~0x10; //Cancel rising edge capture mark
if((RmtSta&0x0F)==0x00)
RmtSta |= 1<<6;
if((RmtSta&0x0F)<14)
RmtSta++;
else
{
RmtSta &= ~(1<<7); // Clear the boot flag
RmtSta &= 0xF0; // Clear the counter
}
}
}
if(TIM_GetITStatus(TIM5,TIM_IT_CC2)!=RESET)
{
if(RDATA) // rising edge has been captured
{
TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC1P=1, set to falling edge capture
TIM_SetCounter(TIM5,0); //Clear the timer value
RmtSta |= 0x10; //Mark rising edge has been captured
}
else
{
Dval = TIM_GetCapture2(TIM5); //Read the value of CCR1
TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Rising); //Set to rising edge capture
if(RmtSta&0x10)
{
if(RmtSta&0x80) //Receive the boot code
{
if(Dval>300&&Dval<800)//high level is 560us
{
RmtRec <<= 1;
RmtRec |= 0; //Received 0 code
}
else if(Dval>1400&&Dval<1800)//High level is 1680us
{
RmtRec <<= 1;
RmtRec |= 1; //Receive 1 code
}
else if(Dval>2200&&Dval<2600)//Continuous code judgment
{
RmtCnt++;
RmtSta &= 0xF0; // Clear the counter
}
}
else if(Dval>4200&&Dval<4700)
{
RmtSta |= 1<<7; //Record the received boot code
RmtCnt = 0;
}
}
RmtSta &= ~(1<<4);
}
}
TIM_ClearFlag(TIM5,TIM_IT_Update|TIM_IT_CC2);
}
2.3 Remote Control Key Value Scanning
u8 Remote_Scan(void)
{
u8 sta=0;
u8 t1,t2;
if(RmtSta&(1<<6))//Get the information of a key
{
t1 = RmtRec>>24; //Address code
t2 = (RmtRec>>16) & 0xFF; //Address inverse code
if((t1==(u8)~t2)&&t1==REMOTE_ID)//Check remote control identification code and remote control receiving address
{
t1 = RmtRec >> 8; //Control code
t2 = RmtRec; //control inverse code
if(t1==(u8)~t2)
sta = t1;
}
if((sta==0)||((RmtSta&0x80)==0))//Receive error or key not pressed
{
RmtSta &= ~(1<<6); // Clear the valid flag of receiving key
RmtCnt = 0;
}
}
return sta;
}
Previous article:stm32 button cycle lighting
Next article:STM32 study notes: standby wake-up
- Popular Resources
- Popular amplifiers
- 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)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
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
- 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?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- #define IS_GPIO_ALL_PERIPH(PERIPH) What does it mean?
- MicroPython Hands-on (31) - Easy IoT
- Programming example: CPU card ESAM process key internal authentication
- BGA81 socket or adapter board available
- BQ24610 Intelligent Li-ion Battery Charging System
- Application of X-NUCLEO-IKS01A3 sensor based on STM32F401RE development board
- Research and Design of SDTVHDTV Conversion Based on FPGA
- esp32 makes an open source handheld game console
- Some questions about DC-DC2596
- To show your companionship, you will get twice the result. Tektronix’s universal lucky bags are being delivered. There are seven lucky bags for you to choose from!