OpenEdv-开源电子网

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

测频

[复制链接]

3

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-5-6
在线时间
0 小时
发表于 2013-5-28 22:16:02 | 显示全部楼层 |阅读模式

 
利用定时器1的计数器模式测量频率,为什么只能记到65535hz呢,再大些就会从头开始,已经写好了溢出中断函数,但是仿真发现根本进不去中断,可不可以帮我看一下哪里的问题啊,十分感谢!
#include "stm32f10x_lib.h"
#include"1602.h"


/*********************变量声明***********************************/
ErrorStatus HSEStartUpStatus;
unsigned char FLAG=0;
unsigned char cnt=0;
unsigned char table[8]={'0','0','0','0','0','0','0','\0'};
unsigned char yichu;
/********************函数声明*************************************/
void RCC_Configuration(void);    
void GPIO_Configuration(void); 
void NVIC_Configuration(void);  
void TIM2_Configuration(void);  
void TIM1ERT_Configuration(void);
void displayF(unsigned long x); //显示计数频率
/************************************************************************************************/
 int main(void)
{
    RCC_Configuration();    //时钟配置

 GPIO_Configuration();      //管脚配置

 NVIC_Configuration();   //中断配置

  TIM2_Configuration();      //定时器2配置 产生一秒时基

 TIM1ERT_Configuration();   //配置定时器1为外部触发模式

    L1602_init();

 L1602_string(1,1,"f:        Hz");


    while (1)
    {
  
 
      if ( FLAG==1)
   {
         cnt++;
   FLAG=0;
           if (cnt>=10)
       {
            cnt=0;
      displayF(TIM_GetCounter(TIM1)+yichu*65535);
      yichu=0;
      TIM_SetCounter(TIM1, 0);
      
  
       }
    
       }
  }  


}
/***************************************************时钟设置*****************************************************************/
void RCC_Configuration(void)
{
 
  RCC_DeInit(); 

  RCC_HSEConfig(RCC_HSE_ON);  

  HSEStartUpStatus = RCC_WaitForHSEStartUp(); 

  if(HSEStartUpStatus ==SUCCESS)  
  {
 
    RCC_HCLKConfig(RCC_SYSCLK_Div1);     //72M
 
    RCC_PCLK2Config(RCC_HCLK_Div1);        //72M

    RCC_PCLK1Config(RCC_HCLK_Div4);     //18M

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  
 
    FLASH_SetLatency(FLASH_Latency_2);           
  
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);   //72M

    RCC_PLLCmd(ENABLE); 

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);   
 
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);   

    while(RCC_GetSYSCLKSource() != 0x08);   
  }

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE);  //72M
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);     //用APB1时钟做TIM2的计数时钟  即HCLK1      18*2
}
/*******************************************管脚配置***********************************************************************************/
void GPIO_Configuration(void)     
{
   GPIO_InitTypeDef GPIO_InitStructure;

  /*******************************外部时钟输入A12*********************************************/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;    //T1,其ETR输入引脚为PA12  作为外部时钟输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
 /**************************LCD管脚配置************************/
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13;    //RCLK   SRCLK   SER
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);     //数据口   用LS595串行转并行

 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;   //RS   RW 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;          //E
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推免输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  
 
}
/***************************************************定时器2设置****************************************************************/
void TIM2_Configuration(void)
 {
   TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;


   TIM_TimeBaseStructure.TIM_Period = 12000;                    //预装值
   TIM_TimeBaseStructure.TIM_Prescaler =2;                     //将时钟分频   这里等于18*2/(2+1=12M 
   TIM_TimeBaseStructure.TIM_ClockDivision = 0;          //分割时钟 这里未分割时钟
   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数模式 向上计数
   TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  //根据结构体指针初始化外设TIM2


   TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  //开中断
   TIM_Cmd(TIM2, ENABLE);       //使能TIM2  
}

/************************************定时器1配置**************************************************************/
 void TIM1ERT_Configuration(void)
 {
     TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;

     TIM_DeInit(TIM1);
 /***********************************时间基配置********************************/
 TIM_TimeBaseStructure.TIM_Period = 0xFFFF;      //预装值
 TIM_TimeBaseStructure.TIM_Prescaler = 0x00;    //预分频 这里是 0x00+1  即原本频率
 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;   //设定其为向上计数模式
 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // Time base configuration

 TIM_ETRClockMode2Config(TIM1, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);    //外部时钟模式2设置
       //(选择的外设,关闭预分频,上升沿或高电平有效,外部触发滤波器为无滤波器)
    TIM_SetCounter(TIM1, 0);   // 初始化Timer的计数器初始值为0;
 TIM_ClearFlag(TIM1,TIM_FLAG_Update);       

 TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);

 TIM_Cmd(TIM1, ENABLE);    //  启动Timer1
}

/*****************************************************优先级设置*****************************************************/
 void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure; 
  
#ifdef  VECT_TAB_RAM        //定义中断向量表程序储存器中
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
#endif
   /************************配置TIM2位全局中断******************************/
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //先占优先级2位,从优先级2位

   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;  
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //优先级设置 0为高优先级
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);  
  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //先占优先级2位,从优先级2位

   NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQChannel;  
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //优先级设置 0为高优先级
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);   


}

/**********************************************TIM2中断事件***************************************************************/
void TIM2_IRQHandler (void)
{
   static u16 tim;
   if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)//判断是否为定时器2溢出中断
   {
     tim++;
//  if(TIM_GetCounter(TIM1)>=65533)
//  {
//   yichu++;
//  }
     if (tim>=100)
 {
  FLAG=1;
  tim=0;
 }     

  }
   TIM_ClearFlag(TIM2, TIM_FLAG_Update);      //清中断标记
   TIM_ClearITPendingBit(TIM2, TIM_IT_Update);    //清除TIM2的待处理位
}

 void TIM1_IRQHandler (void)
{
   if(TIM_GetITStatus(TIM1,TIM_IT_Update)!=RESET)//判断是否为定时器1溢出中断
   {
     yichu++;
 }     
 TIM_ClearFlag(TIM1, TIM_FLAG_Update);
 TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
  }

 

 


/************************************************************************************************/
void displayF(unsigned long x)
{
   if(x==0)
   {
      L1602_string(1,3,"0000000");
   }
   else
   {
     table[0]=x/1000000+'0';
     table[1]=(x/100000)%10+'0';
     table[2]=(x/10000)%10+'0';
     table[3]=(x/1000)%10+'0';
  table[4]=(x/100)%10+'0';
  table[5]=(x/10)%10+'0';
     table[6]=x%10+'0';
    
   }
   L1602_string(1,3,table);
  
}

 

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-5-29 00:10:52 | 显示全部楼层
stm32的定时器就是16位的,所以最大就是65536了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-5-6
在线时间
0 小时
 楼主| 发表于 2013-5-29 01:40:03 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
不是在到65535后会产生溢出中断吗?我记录一下,那么是不是可以测的多一些呢,为什么进不去时钟1的溢出中断呢?
回复 支持 反对

使用道具 举报

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
发表于 2013-5-29 08:12:08 | 显示全部楼层
楼主,可以上传个工程吗,我也想学习一下测频,以前一直不知道怎么实现,谢谢了
回复 支持 反对

使用道具 举报

57

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
446
金钱
446
注册时间
2013-2-20
在线时间
1 小时
发表于 2013-5-29 09:39:52 | 显示全部楼层
虽然最大是65536,但是你可以利用测脉宽一样的原理,采用计数溢出+1的原理,那么总计数次数就等于65536*溢出数+当前计数值...我用430测过频,测周法和测频法都用过...至少可以1M以上,具体的我记不清了,误差也还行....
创新超越梦想,拼搏创造奇迹....
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-5-29 10:14:31 | 显示全部楼层
回复【3楼】生生:
---------------------------------
可以,4楼给出了答案.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

3

主题

5

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2013-5-6
在线时间
0 小时
 楼主| 发表于 2013-5-29 10:36:04 | 显示全部楼层
回复【5楼】废墟崛起之厦:
---------------------------------
我是这么设计的,在定时器1的计数溢出时产生中断然后加1记录下来,但是总是不成功,我软件仿真了一下,发现溢出中断没有进去,是不是我的定时器配置有什么问题,有没有时间帮我看一下程序,出现了什么问题,十分感谢!
回复 支持 反对

使用道具 举报

57

主题

195

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
446
金钱
446
注册时间
2013-2-20
在线时间
1 小时
发表于 2013-5-29 13:25:06 | 显示全部楼层
430可以直接用外部脉冲来当做定时器的输入时钟,也就是时钟计数,32好像也可以,这样的话就可以去掉用另一个定时器来做输入捕捉了,直接用定时器计数..而且误差更小....
创新超越梦想,拼搏创造奇迹....
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-19 05:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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