历史上的今天
返回首页

历史上的今天

今天是:2025年07月24日(星期四)

正在发生

2018年07月24日 | STM8 测量脉宽——红外例程

2018-07-24 来源:eefocus

实例说明:
1、本实例是利用STM8单片机定时器TIM1的PWM输入捕获模式测量红外遥控码。 2、红外遥控码格式为NEC红外编码。
3、红外接收信号输入接PC1(TIM1输入通道1)。
4、采用外部晶振16M。
5、采用IAR FOR STM8开发环境。
6、程序代码如下:
//--------------------------------------------------------------------
#i nclude  
#define uchar              unsigned char
#define uint                unsigned int 
uchar IrRecStep = 0;                             //接收步骤
uchar IrIndex = 0;                                //接收位数
uchar IrRecFlag = 0;                             //接收完标志
uchar IrRecBuff[4];                               //接收缓冲区
uchar IrRecAddr1;                                //红外地址码
uchar IrRecAddr2;
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;
    }
  }

推荐阅读

史海拾趣

虹冠电子(Champion)公司的发展小趣事

虹冠电子自成立以来,一直将技术创新作为公司发展的核心动力。早期,虹冠电子就投入大量资源研发AC-DC模拟电源IC,成功推出了一系列高效能、低能耗的产品,迅速在市场上建立了良好的口碑。随着技术的不断迭代,虹冠电子在电源管理技术方面取得了显著优势,尤其在电竞电源供应器领域,凭借卓越的性能和稳定性,赢得了众多专业用户和消费者的认可。

Cooper Industries公司的发展小趣事

在电工产品领域,Cooper Industries同样取得了显著的成就。2000年,公司收购了Eagle电气,并将其与已有的接线装置产品系列合并,组建成了一个名为“库柏电工”的新事业部。这一举措不仅丰富了公司的产品线,也使其在电工产品领域的技术实力得到了进一步提升。库柏电工提供了超过10000个高质量装置的产品组合,广泛应用于工业、商业和住宅领域,满足了不同客户的需求。同时,公司还不断投入研发,推出更加先进、高效的电工产品,为行业的发展做出了积极贡献。

DESOUTTER公司的发展小趣事

随着全球经济的不断发展,Desoutter公司开始实施国际化战略,积极开拓国际市场。公司通过与全球知名企业的合作,如大众集团、捷豹路虎集团等,成功进入了欧洲、北美等地区的市场。同时,Desoutter公司还在全球范围内建立了多个生产基地和研发中心,以更好地满足不同地区客户的需求。

GSI Technology公司的发展小趣事

从财务表现来看,GSI Technology在过去几年中取得了不俗的成绩。尽管在某些季度受到宏观经济环境和市场需求波动的影响,但公司整体营收和净利润均保持了稳定增长。特别是在2023年Q3财报中,尽管营收略低于市场预期,但公司依然展现出了强劲的发展潜力和市场竞争力。展望未来,GSI Technology将继续秉承创新、务实、高效的发展理念,不断推出更多高性能、高品质的存储器产品,为全球电子行业的发展贡献自己的力量。

Burr-Brown公司的发展小趣事

Burr-Brown在音频领域取得了显著的成就。1957年,公司推出的Model 130成为世界上第一个固态运算放大器(op amp),这一技术在现代高级音频系统中仍占据核心地位。1982年,公司发布的16位单片数模转换器(DAC)更是彻底改变了音乐的播放和发行方式,使得音乐可以以高保真度进行复制,并方便地随身携带。Burr-Brown的技术成为优质音频的代名词,赢得了广泛的行业认可。

ConnectBlue公司的发展小趣事

2014年5月19日,ConnectBlue公司被全球领先的定位与无线通信技术公司u-blox收购。这一收购为ConnectBlue公司带来了新的发展机遇和更广阔的市场空间。在u-blox的支持下,ConnectBlue公司得以进一步加大研发投入,拓展产品线,提升产品品质和服务水平。同时,公司还借助u-blox的全球销售网络和品牌影响力,进一步开拓国际市场,实现了新的跨越式发展。

问答坊 | AI 解惑

【EEWORLD】救火车和你一起学ARM系列活动全部地址链接

恭喜救火车已经注册公司,全称是秦皇岛千目电子有限公司。 【EEWORLD】救火车和你一起学ARM系列活动之一(发起活动和组建工作环境) 【EEWORLD】救火车和你一起学ARM系列活动之二(最小系统电路和建立第一个软件工程)  【EEWORLD】救火车和 ...…

查看全部问答>

[转帖]探讨正确安装防盗报警探测器的方法

防盗报警探测器的安装过程是一个需费心又费时的过程,并不是按着说明书将其安装固定到建筑物体上,稍稍目测下探测方位以及适度调试下角度就算可以了。 管线的敷设         在过往的工程实践中,大家会发现部分防盗 ...…

查看全部问答>

2440ce5的bsp移植到ce6的SMFLASH问题

ce5下bsp是好的,移植到ce6下,eboot已经搞好,烧录nk后,打印如下消息: Error Reporting Memory Reserved, dump size = 00020000 Setting up softlog at 0x83edc000 for 0x800 entries Booting Windows CE version 6.00 for (ARM) &pTOC = 81 ...…

查看全部问答>

关于触摸屏的问题

我正在搞qt,现在点击触摸屏时出现一个问题:就是我点一个地方,触摸屏的鼠标响应的地方不是我点的那一点,而是与触摸屏对角线平行的另一点,而我点在触摸屏的对角线上的任何一点,就基本准确,请问是不是触摸屏的X,Y轴搞错了??我在驱动里要改哪 ...…

查看全部问答>

请大家推荐几本Wince 6.0开发的好书

如题,就是那种讲的比较深入的书。我这里有《Windows CE实用开发技术》是针对Wince5.0的书籍。谢谢各位高手了…

查看全部问答>

arm7 变量值在cpu做状态切换时 更改了 请教高手!!!原因是什么?

arm7  变量值在cpu做状态切换时  更改了  请教高手!!!原因是什么?…

查看全部问答>

前辈们请给点指点!谢谢

我现在只是一个大一新生,对机器人特别感兴趣,但对这个领域了解甚少.想知道作为初学者应该从哪些基础方面着手.对了我学的专业是信息安全,也不知道有哪些专业课对此爱好有用. …

查看全部问答>

基于Kinetis的简单webserver(四)

网络控制界面 网络的控制没有问题了,下一步开始把SLCD的其它功能函数移植进去,字符的显示,滚动效果等等。 …

查看全部问答>

DSP开发板上的I/O口是coms电平,还是ttl电平,怎么去判断的?

DSP开发板上的I/O口是coms电平,还是ttl电平,怎么去判断?请教。。。…

查看全部问答>

2012 TI C2000, MSP430 & M3 大奖赛论文,源代码及PCB光盘大小1.8G下载地址

LM3S8962视频教程 f5529视频教程 msp430launchpad教程 上传了很久,大家给力点哟~ 下载地址 https://download.eeworld.com.cn/detail/qinkaiabc/8416…

查看全部问答>