• 芯片制造中的阻挡层沉积技术介绍
  • 接地搭接电缆布局屏蔽!!!
  • 北美液冷生态解码:超微spuermicro,24年营
  • SK海力士全球首发HBM4-16层堆叠、2.0TB/s
  • 2纳米Nanosheet技术及其以后的选择性层减薄

利用STM8单片机定时器tiM1的PWM输入捕获模式测量红外遥控码

[复制链接]
查看663 | 回复4 | 2021-2-18 12:28:42 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1.红外遥控
码格式为NEC红外编码。

2.
红外接收信号输入接PC1(TIM1输入通道1)。

3.
采用外部
晶振
16M。

4.
采用IAR FOR STM8开发环境。

5.
程序代码如下:

//--------------------------------------------------------------------

#i nclude <io
stm8s
105s4.h>

#define uchar              unsigned char

#define uint                unsigned int

uchar IrRecStep = 0;                             //接收步骤

uchar IrIndex = 0;                                //接收位数

uchar IrRecFlag = 0;                             //接收完标志

uchar IrRecBuff[4];                               //接收缓冲区

uchar IrRecAddr1;                                //红外地址码

uchar IrRecA
ddr2
;

uchar IrRecData1;                                //红外数据码

uchar IrRecData2;

uint IrCycle = 0;                                  //红外周期

uint IrHigh = 0;                                   //占空比

const uchar IrCode[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

//--------引导码低电平范围------------------

#define IrHeadLow_Max       2300            //2300*4 = 9200us

#define IrHeadLow_Min        2100            //2100*4 = 8400us

//--------引导码高电平范围------------------

#define IrHeadHigh_Max      1250            //1250*4 = 5000us

#define IrHeadHigh_Min       1050            //1050*4 = 4200us

//--------数据0的周期范围-------------------

#define IrData00_Max         300             //300*4 = 1200us

#define IrData00_Min          260             //260*4 = 1040us

//--------数据1的周期范围-------------------

#define IrData10_Max         580             //580*4 = 2320us

#define IrData10_Min          540             //540*4 = 2160us

//--------数据0的占空比(高电平)范围---------

#define IrData0_Max          160             //160*4 = 640us

#define IrData0_Min           120             //120*4 = 480us

//--------数据1的占空比(高电平)范围---------

#define IrData1_Max          440             //440*4 = 1760us

#define IrData1_Min           400             //400*4 = 1600us

//----------------------------------------------------------

#define REMOTE_CLK_DIV       63              //63+1=64----16Mh/64=4us

#define REMOTE_ICF_FILTER   0x30

//延时程序

void Delay_ms( uint ms )

{

  uint i,j;

  for( j=0; j   {

    for( i=0; i<1000; i++ )

    {;}

  }

}

//红外接收端口初始化

void Ir_Init(void)

{

  PC_DDR_DDR1 = 0;       //PC1为输入

  PC_CR1_C11 = 1;

  PC_CR2_C21 = 0;

}

//使用TIM1的PWM输入捕获

void Ir_PWM_Init(void)

{

  TIM1_PSCRH = 0;

  TIM1_PSCRL = REMOTE_CLK_DIV;

  TIM1_CCER1 &= 0xee;//禁止输入捕获1,2

  TIM1_CCMR1 = (REMOTE_ICF_FILTER + 0x01);// ch1到ti1fp1

  TIM1_CCER1 &= 0xec;//ch1 上升沿触发

  TIM1_CCMR2 = (REMOTE_ICF_FILTER + 0x02);// ch2选择 ti1fp2上

  TIM1_CCER1 = 0x20;//ch1 下降沿触发 ic2

  TIM1_SMCR = 0x54;//选源触发源和触发方式 复位

  TIM1_CCER1 = 0x11;//使能输入捕获1,2

  TIM1_CR1 = 0x05;

}

//红外接收程序

void Ir_Receive(void)

{

  switch(IrRecStep)

  {

  case 0:

          IrIndex = 0;

          if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1))

          {

            IrHigh = (uint)(TIM1_CCR2H);

            IrHigh = (IrHigh << 8) + TIM1_CCR2L;  //IrHigh占空比

            IrCycle = (uint)(TIM1_CCR1H);

            IrCycle = (IrCycle << 8) + TIM1_CCR1L;  //IrCycle周期

            //是否在引导码低电平范围内

            if (((IrCycle - IrHigh) < IrHeadLow_Max)&&((IrCycle - IrHigh) > IrHeadLow_Min))

            {

              IrRecStep = 1;

              TIM1_SR1_CC1IF = 0;

              TIM1_SR1_CC2IF = 0;

              TIM1_SR2_CC1OF = 0;

              TIM1_SR2_CC2OF = 0;

              TIM1_SR1_UIF = 0;

              

              IrRecBuff[0] = 0;

              IrRecBuff[1] = 0;

              IrRecBuff[2] = 0;

              IrRecBuff[3] = 0;

            }

          }

          break;

  case 1:

          if ((TIM1_SR2_CC1OF==1) (TIM1_SR2_CC2OF==1) (TIM1_SR1_UIF==1))

          {

            IrRecStep = 0;

          }

          else

          {

            if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1))

            {

              IrHigh = (uint)(TIM1_CCR2H);

              IrHigh = (IrHigh << 8) + TIM1_CCR2L;

              IrCycle = (uint)(TIM1_CCR1H);

              IrCycle = (IrCycle << 8) + TIM1_CCR1L;

              //是否在引导码高电平范围内

              if ((IrHigh < IrHeadHigh_Max)&&(IrHigh > IrHeadHigh_Min))

              {

                IrRecStep = 2;

              }

            }

          }

          break;

  case 2:

          if ((TIM1_SR2_CC1OF==1) (TIM1_SR2_CC2OF==1) (TIM1_SR1_UIF==1))

          {

            IrRecStep = 0;

          }

          else

          {

            if ((TIM1_SR1_CC1IF == 1)&&(TIM1_SR1_CC2IF == 1))

            {

              IrHigh = (uint)(TIM1_CCR2H);

              IrHigh = (IrHigh << 8) + TIM1_CCR2L;

              IrCycle = (uint)(TIM1_CCR1H);

              IrCycle = (IrCycle << 8) + TIM1_CCR1L;

              //周期是否在数据0范围内

              if ((IrCycle > IrData00_Min)&&(IrCycle < IrData00_Max))

              {

                //高电平是否在数据0范围内

                if ((IrHigh > IrData0_Min)&&(IrHigh < IrData0_Max))

                {

                  IrIndex++;

                }

                else

                {

                  IrRecStep = 0;

                }

              }

              //周期是否在数据1范围内

              else if ((IrCycle > IrData10_Min)&&(IrCycle < IrData10_Max))

              {

                //高电平是否在数据1范围内

                if ((IrHigh > IrData1_Min)&&(IrHigh < IrData1_Max))

                {

                  IrRecBuff[IrIndex >> 3] = IrCode[IrIndex & 0x07];

                  IrIndex++;

                }

                else

                {

                  IrRecStep = 0;

                }

              }

              else

              {

                IrRecStep = 0;

              }

              if(IrIndex >= 32)

              {

                IrRecStep = 0;

                IrRecFlag = 1;

              }

            }

          }

          break;

  }

}

      

//
时钟
初始化

void CLK_Init(void)

{

  CLK_ECKR=0x03;//外部时钟寄存器 外部时钟准备就绪,外部时钟开

  CLK_SWCR=0x02;//切换控制寄存器 使能切换机制

  CLK_SWR=0xB4;//主时钟切换寄存器 选择HSE为主时钟源*/

  while (!(CLK_SWCR & 0x08));  

  CLK_CSSR=0x01;//时钟安全系统寄存器   

}


//初始化

void Devices_Init(void)

{

  Delay_ms(200);

  CLK_Init();

  Ir_Init();

  Ir_PWM_Init();

}

//主程序

void main( void )

{

  Devices_Init();

  while(1)

  {

    Ir_Receive();

    if(IrRecFlag == 1)

    {

      IrRecAddr1 = IrRecBuff[0];

      IrRecAddr2 = IrRecBuff[1];

      IrRecData1 = IrRecBuff[2];

      IrRecData2 = IrRecBuff[3];

      IrRecFlag = 0;

    }

  }

}
回复

使用道具 举报

a6682100 | 2021-2-18 22:30:42 | 显示全部楼层
回复

使用道具 举报

地沟油 | 2021-2-18 22:42:02 | 显示全部楼层
回复

使用道具 举报

wangy2000 | 2021-2-19 07:01:11 | 显示全部楼层
回复

使用道具 举报

lqsgg | 2021-2-20 08:06:42 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则