OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13040|回复: 10

发一个刚测试通过的程序希望对刚学习stm32的朋友及有需要的能有帮助,stm32定时器输入捕获解红外遥控器载波频率,误差在0.2K以内

[复制链接]

9

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2012-9-17
在线时间
2 小时
发表于 2012-11-22 17:28:53 | 显示全部楼层 |阅读模式
一直都是在论坛上求助,求助,是时候也该共享点资源了,虽然我也是新手,刚接触STM32不足一个月,下面这程序我已仿真调试通过,测头码还是很精确的,有在做遥控器芯片的同行看到这个应该会很有用。
可能有朋友不知道什么是引导码,所以发个图解释下,遥控器发的码都由下图中(9+4.5ms)的引导码加客户码+客户码反码+数据码及数据码反码组成,我要测的就是引导码的频率,也称为载波频率。


实际接收时是反的,如下图

程序如下:

/**
  ******************************************************************************
  * @file    测红外载波程序
  * @author  S.H
  * @version V1.0
  * @date    11.2012
  * @brief  
  ******************************************************************************/
#include "stm32f10x.h"
#include "stm32f10x_conf.h"
#include "sys.h"
#include "delay.h"
#define IR PAin(1)

typedef int  bool;
#define false 0
#define ture 1
u32 ICValue[3];
u32 FinalValue;
float Frequency;
u8 ik=0;
bool gFlag;
void GPIO_Config()
{
  GPIO_InitTypeDef GPIO_InitStructure;   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;  //上拉输入
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);   //选择PA1所在的GPIO管脚用作外部中断线路EXIT1
}

void TIM2_Config()
{
  TIM_DeInit(TIM2); 
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure ;        
  TIM_TimeBaseInitStructure.TIM_Prescaler = 0;                  //分频
  TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
  TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF;                     //计数65535
  TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;                 //时钟分割
  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
  TIM_PrescalerConfig(TIM2, 0x0048, TIM_PSCReloadMode_Immediate);        //72分频  1us计数周期
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);
  TIM_ITConfig( TIM2, TIM_IT_Update, DISABLE );
  TIM_ClearFlag(TIM2, TIM_FLAG_Update);

  TIM_ICInitTypeDef TIM_ICInitStructure;
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;             //选择通道2
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;// 捕获下降沿
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //捕获在捕获输入上每探测到一个边沿执行一次
  TIM_ICInitStructure.TIM_ICFilter = 0x0;                      //输入比较滤波器
  TIM_ICInit(TIM2, &TIM_ICInitStructure);
  TIM_ITConfig( TIM2, TIM_IT_CC2, DISABLE );
  TIM_ClearFlag( TIM2, TIM_FLAG_CC2 );

  TIM_ITConfig(TIM2, TIM_IT_CC2 ,ENABLE);
  TIM_Cmd(TIM2, ENABLE);
}

void TIM2_IRQHandler()
{
  if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
  {
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    ICValue[ik]=TIM_GetCapture2(TIM2);
    ik++;
    if(ik>1)
    {
      ik=0;
      gFlag=1;
      TIM_ITConfig(TIM2, TIM_IT_CC2 ,DISABLE);
//      TIM_Cmd(TIM2, DISABLE);
    }
  }
  if(ICValue[1]<ICValue[0])
  {
    FinalValue=(0xFFFF-ICValue[0])+ICValue[1];
  }
  else
  {
    FinalValue=ICValue[1]-ICValue[0];  //引导码长度
  }
  Frequency=51200000/FinalValue;
}

void NVIC_Config()
{
  NVIC_InitTypeDef NVIC_InitStucture;
  NVIC_InitStucture.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStucture.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStucture.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStucture.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStucture);
}
//配置72M系统时钟
void RCC_Config()
{
  ErrorStatus HSEStartUpStatus;                       
  RCC_DeInit();
  RCC_HSEConfig(RCC_HSE_ON);                           //启用外部时钟HSE
  HSEStartUpStatus = RCC_WaitForHSEStartUp();          //等待外部晶振起振
  if(HSEStartUpStatus == SUCCESS)                     
  {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  //预指取缓存使能
    FLASH_SetLatency(FLASH_Latency_2);                     //设置代码延时值,延时2周期
    RCC_HCLKConfig(RCC_SYSCLK_Div1);                       //设置AHB时钟
    RCC_PCLK2Config(RCC_HCLK_Div1);
    RCC_PCLK1Config(RCC_HCLK_Div1);
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while (RCC_GetSYSCLKSource() != 0x08);            //使用PLL作为系统时钟
    {
    }
  }
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE ); 
}

int main()
{
  RCC_Config();
  NVIC_Config();
  TIM2_Config();
  GPIO_Config();
  delay_init(72);
  while(1)
  {
    if(gFlag)
    {
      gFlag=0;
      delay_ms(120);
      while(IR){};
      TIM_ITConfig(TIM2, TIM_IT_CC2 ,ENABLE);
    }
  }
}
JTAG仿真结果:


基准频率为37.9 实测在0.2K范围内波动 (测试时用的遥控器没有内置晶振,有的话会可能会更好些)

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

9

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2012-9-17
在线时间
2 小时
 楼主| 发表于 2012-11-22 17:31:25 | 显示全部楼层
 欢迎转载,传播以及用于各种用途
回复 支持 反对

使用道具 举报

24

主题

89

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2012-8-29
在线时间
3 小时
发表于 2012-12-29 12:00:07 | 显示全部楼层
学习后 STM32发送实验成功了吗?谢谢!
我白天是个程序员,晚上就是个有抱负的演员。住在天朝的魔都,有条同名的狗......
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2012-12-29 13:25:45 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

0

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2012-2-4
在线时间
9 小时
发表于 2013-1-21 16:19:48 | 显示全部楼层
如果楼主可以把工程直接上传更省事,不要怪我懒啊,呵呵
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-2-19
在线时间
0 小时
发表于 2014-2-22 13:05:49 | 显示全部楼层
楼主我有个疑问  Frequency=51200000/FinalValue;这个51200000是什么?
还有一体化接收头是看不到载波的,你的原理我没看明白?
参加过电子设计大赛,玩过单片机,搞过DSP,fpga也接触过,可惜学的不精,在此就是来好好研究的,请多多关照
回复 支持 反对

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-2-19
在线时间
0 小时
发表于 2014-2-22 13:07:33 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
原子哥,能麻烦你稍微提点一下这个吗。
我有个疑问  Frequency=51200000/FinalValue;这个51200000是什么? 
还有一体化接收头是看不到载波的,你的原理我没看明白?
参加过电子设计大赛,玩过单片机,搞过DSP,fpga也接触过,可惜学的不精,在此就是来好好研究的,请多多关照
回复 支持 反对

使用道具 举报

4

主题

84

帖子

0

精华

初级会员

Rank: 2

积分
155
金钱
155
注册时间
2013-10-17
在线时间
9 小时
发表于 2014-7-8 10:58:07 | 显示全部楼层
mark,标记
回复 支持 反对

使用道具 举报

7

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
98
金钱
98
注册时间
2012-9-25
在线时间
3 小时
发表于 2014-11-5 09:08:07 | 显示全部楼层
你好,楼主,请问这个程序stm32能否正确的识别红外编码(我的红外接收头是不滤除38KHz载波)??、谢谢
回复 支持 反对

使用道具 举报

10

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2014-5-11
在线时间
10 小时
发表于 2014-11-26 00:24:46 | 显示全部楼层
mark,最近刚好在做红外,到时候可以试试用这个识别频率
回复 支持 反对

使用道具 举报

1

主题

13

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2023-3-25
在线时间
5 小时
发表于 2023-3-25 14:45:44 | 显示全部楼层
Frequency=51200000/FinalValue; 51.2M哪里出来的?如何理解?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 13:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表