单片机
返回首页

STM8S单片机红外接收解码程序 带1602显示

2021-11-25 来源:eefocus

这几天在网上找了很多关于红外接收解码的程序,但都不是很理想。一般都是用延时来作为0和1的数据,或者注释不是很详细的,所以自己鼓捣了一个。
本程序是采用外部中断加定时器1来实现红外解码,STM8S单片机ABCD口都可作为外部中断,使用的遥控器为市面上大多数的。
需要的朋友们可以作为参考。

制作出来的实物图如下:

效果图

效果图

单片机源程序如下:

/***************可识别用户码 解码成功后显示在1602并LED闪烁一次*****************/


#include 'iostm8s208mb.h'//主控芯片的头文件


#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; //存储高低电平的宽度

u8 Counter_Time_H,Counter_Time_L;


u8 a[4]; //存放码值 分别为用户码 用户反码 数据码 数据反码


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;//配置PC为仅下降沿触发


  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; //允许更新中断

  

  TIM1_PSCRH=0x00;    //16Mhz/16=1us,16分频

  TIM1_PSCRL=0x0f;  

  

//  TIM1_CNTRH=0x00;

//  TIM1_CNTRL=0x00;

  

  TIM1_ARRH=0xff;     //自动装载最大值

  TIM1_ARRL=0xff;

}


void Clock_Init(void)

{

  CLK_CKDIVR=0x00; //16M                  

}


void LED_ACT(void)                //延时时间太大会影响灵敏度

{

  LED=0;

  delay_ms(10);

  LED=1;

  delay_ms(10);

}


u8 DeCode(void)

{

   u8  i,j;

   u8 temp;    //暂存变量

   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);   //先判断是否为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);  //再判断是否为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;                                      //太大或太小舍去                         

        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)  //将二进制码转换为BCD码

{


   u8 temp; //暂存

   temp=data;

   data&=0xf0;

   data>>=4;                    

   data&=0x0f;                  

   if(data<=0x09)

   {                 

     Write_Data(0x30+data);    //显示0-9        

   }

   else

   {

     data=data-0x09;

     Write_Data(0x40+data);    //显示A-F

   }

   data=temp;

   data&=0x0f;

   if(data<=0x09)

   {

     Write_Data(0x30+data);            

   }

   else

   {

     data=data-0x09;

     Write_Data(0x40+data);

   }

   Write_Data(0x48);          //显示“H”

}


void Disp_1(void) //显示第二行:码值

{  

    Write_Com(0x80+0x40);

    two_2_bcd(a[0]);

   

    Write_Data(0x20); //空格

    two_2_bcd(a[1]);

   

    Write_Data(0x20); //空格

    two_2_bcd(a[2]);

   

    Write_Data(0x20); //空格

    two_2_bcd(a[3]);

}


void Disp_2(void) //显示第一行:固定字符

{

  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)) //判别用户码及反码

//  {

    LED_ACT();

//  }

}


void main(void)

{

  asm('sim');//MAIN程序的优先级配置为3级(关总中断)

  

  GPIO_Init();

  Clock_Init();

  TIM1_Init();

  LCD_Init();

//  delay_ms(10);

  

  Write_Com(0x01); //清屏

  

  Disp_2();

  

  asm('rim');//MAIN程序的优先级由3级降低至0级(开总中断)

  

  while(1);//死循环

}


#pragma vector=0x07

__interrupt void EXTI_PORTC_IRQHandler(void)

{

  PC_CR2_C21=0;//禁止PC0端口外部中断

  

  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))  //引导码9000us+-500  4500us+-500

  {

    if(DeCode()==1)

    {     

      Disp_1();

      CHECK_User();

    }

  }

  

  PC_CR2_C21=1;//使能PC0端口外部中断

}


#pragma vector=0x0D

__interrupt void TIM1_UPD_OVF_TRG_BRK_IRQHandler(void)

{

  TIM1_SR1&=0xfe;//清除溢出中断标志位'UIF'  

}


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章