一直都是在论坛上求助,求助,是时候也该共享点资源了,虽然我也是新手,刚接触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范围内波动 (测试时用的遥控器没有内置晶振,有的话会可能会更好些)
  |