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

最新更新时间:2021-11-25来源: eefocus关键字:STM8S  单片机  红外接收解码  1602显示 手机看文章 扫描二维码
随时随地手机看文章

这几天在网上找了很多关于红外接收解码的程序,但都不是很理想。一般都是用延时来作为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"  

}


关键字:STM8S  单片机  红外接收解码  1602显示 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic555610.html

上一篇:车载屏的STM8单片机驱动 128x16点阵屏输出汉字
下一篇:stm8s105k4单片机PWM波配置

推荐阅读

STM8S驱动OLED12864
这种OLED的液晶屏似乎很受电子爱好者的欢迎,原因大概是:①这种屏小巧玲珑,同样是128*64点阵的液晶屏,这种屏的体积比以前那种LCD12864小了四分之一,作为DIY手表的屏幕刚刚好。②功耗低,由于OLED是有机发光材料制作成的,没有使用背光,所以功耗比使用LED作为背光的液晶屏,功耗要低很多。所以这块液晶屏适合用于手表之类的手持设备。③可以选择的接口很多。接口和使用的液晶屏驱动芯片有关,大多数OLED12864使用的驱动芯片是SSD1306,这款驱动芯片提供给MCU的接口有5种,如下图。本文使用I2C接口来驱动OLED,主要是因为I2C占用MCU的IO少,当然用SPI接口驱动OLED的也很多。使用I2C接口时,D0脚作为I2C
发表于 2021-11-25
<font color='red'>STM8S</font>驱动OLED12864
stm8 stm8s stm8af 485接口 modbus协议代码
本人使用stm8af62a6,stm8s和stm8af大多数是互通的,只用一个库函数62a6只能使用uart3!485接口是硬件,不需要管,任何硬件接线都可以实现代码见附件,已实现通信主函数代码,主要为初始化函数,以及modbus帧接收处理函数,帧接收处理按自己的需求自行修改,本例的处理函数为接收数据再多输出一点数据单片机源程序如下:/******************************************************************mian.c文件部分******************************************************************/void
发表于 2021-11-12
STM8S学习笔记之三(STM8 SysClk)
STM8S系统时钟设置,对于单片机来说是非常重要的,不同的用处必须应用不同的时钟。。举个例子,做AVR时在高稳定的串口通讯时用的时钟一般是3.6864M,主要是这个算波特率精确。。STM8S同样重要。STM8S时钟源:●1-24MHz高速外部晶体振荡器(HSE)●最大24MHz高速外部时钟信号(HSE user-ext)●16MHz高速内部RC振荡器(HSI)●128KHz低速内部RC(LSI)各个时钟源可单独打开或关闭,从而优化功耗。对于我这么懒得人一般都是用的内部或者外部晶振。。这个芯片时钟方面很大的一个亮点就是时钟可以自由分频。在降低功耗方面,如果有特殊需求的时候还是考虑STM8L系列或者430的吧,不得不承认术业有专攻
发表于 2021-11-10
STM8S定时器工作
TIM4是一个8位通用定时器,TIM4工作时,其计数器从0开始向上计数,计数到TIM4_ARR寄存器中设置的值时,计数器从新从0开始计数,同时产生一个计数器溢出事件。程序实例void main(void){  InitLED();  InitTIM4();  asm("ris");  TIM4_CR1 |= 0X01;   while(1){}}InitTIM4();为 TIM4 初始化函数,起作用是设置 TIM4 的相关寄存器,使 TIM4 每隔一段时间产生一次溢出中断。其函数内部如下:void InitTIM4(void){  TIM4_PSCR =
发表于 2021-10-20
STM8S定时器的使用 - stm8s定时器tim4使用方法解析
  stm8s定时器TIm4概述  该定时器由的8可位自动重载的向上计数器所组成,它可以用来作为时基发生器,具有溢出中断功能。  TIM6同时钟信号控制器用于定时器同步和级联。  STM8通用定时器TIM4的主要功能  TIM4功能包括:  1、8位向上计数的自动重载计数器;  2、3位可编程的预分配器(可在运行中修改),提供1,2,4,8,16,32,64和128这8种分频比例。  3、中断产生  –在计数器更新时:计数器溢出  STM8通用定时器TIM4功能概述    (TIM4框图 )  中断  通用定时器包括2个中断源:  更新中断(溢出,计数器初始化);  触发信号输入(仅TIM6可用)  STM8S定时器的使用  环境
发表于 2021-10-20
<font color='red'>STM8S</font>定时器的使用 - <font color='red'>stm8s</font>定时器tim4使用方法解析
stm8s105k4单片机PWM波配置
//ccr = 0~499void setPWM1(unsigned short ccr){//PC1  TIM1_CCR1H = (unsigned char)(ccr>>8);  TIM1_CCR1L = (unsigned char)(ccr & 0xff);}void setPWM2(unsigned short ccr){//PC2  TIM1_CCR2H = (unsigned char)(ccr>>8);  TIM1_CCR2L = (unsigned char)(ccr & 0xff);}void setPWM3(unsigned sho
发表于 2021-11-25
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2021 EEWORLD.com.cn, Inc. All rights reserved