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