STM8S MCU infrared receiver decoding program with 1602 display

Publisher:YuexiangLatest update time:2021-11-25 Source: eefocusKeywords:STM8S Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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

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"  

}


Keywords:STM8S Reference address:STM8S MCU infrared receiver decoding program with 1602 display

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

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号