OpenEdv-开源电子网

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

STM32测频问题

[复制链接]

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
发表于 2013-7-12 10:37:42 | 显示全部楼层 |阅读模式

RT。小弟想做个测频的程序,参照了别人的,但是输出始终是0。请原子哥帮忙看下是什么问题。感谢!!

#include "timer.h"
#define TIMx  TIM4
#define x     4 
extern u32 Cnt;

void NVIC_Configuration(void)
{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

}
void TIMx_EXTERN_CLK_INIT(void)
{
 //初始化定时器时钟
 RCC->APB1RSTR |= 1 << (x-2);
 RCC->APB1RSTR &= ~(1<<(x-2));
 
 RCC->APB1ENR |= 1 << (x-2);
 //*********************

 TIMx_PIN_INIT();

 TIMx->CCMR1 |= 1 << 8;    //第8位置1 CC2S[1:0] == 01
 //无滤波器
 TIMx->CCER |= 0 << 5;    //极性为高电平计数
 TIMx->SMCR |= 1 << 0 | 1 << 1 | 1 << 2;   //选择外部时钟模式1
 TIMx->SMCR |= 1 << 6 | 1 << 5;       //选择T2作为触发源
 TIMx->DIER |= 1 << 0;   //中断使能
 TIMx->CR1 |= 1 << 0;    //开始计数
}

void TIMx_PIN_INIT(void)
{
 RCC->APB2ENR |= 1 << 3;

 GPIOB->CRL &= 0x0fffffff;
 GPIOB->CRL |= 0x80000000; //配置引脚为输入
 Bout(7) = 0; 
}

void CLOSE_CNT(void)
{
 TIMx->CR1 &= ~(1<<0);
}
            
void TIM4_IRQHandler(void)
{
 if (TIM4->SR & (1 << 0))
 {
  Cnt++;
  TIM4->SR &= ~(1 << 0);
 }
}

/*****MAIN******/

  u32 tt=0;
 delay_init();       //延时函数初始化
 NVIC_Configuration();
 TIMx_EXTERN_CLK_INIT();
 while(1)
 {
  delay_ms(10);
  tt++; 
  if(tt==100)
  {
   TIM4->CR1 |= 1 << 0;
   CLOSE_CNT();
   fre = Cnt*65535+TIM4->CNT;
   LCD_ShowNum(98,150,fre,8,16);  //显示电压值的小数
   Cnt=0;
   TIM4->CNT=0;
   tt=0;
  }
 }

坚持到底就是胜利!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-12 14:04:18 | 显示全部楼层
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-12 15:20:39 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
我用函数信号发生器给的VPP 3V的方波,接上去之后示波器测的是VPP 2.4V。2.4应该也属于是高电平范围啊??程序有木有什么问题???方波我接的PB7
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-12 15:22:49 | 显示全部楼层
我把程序贴出来了,麻烦帮忙看下,谢啦!!!

DAC - 副本.rar

2.97 MB, 下载次数: 88

坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-12 19:15:22 | 显示全部楼层
你的信号没有现负压吧?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-12 19:35:23 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
没有。。是不是NVIC没配置的原因?感觉NVIC这东西不是很懂
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-12 19:54:35 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
刚刚查了下,中断可以进去,但是fre的值始终是0。到底是什么问题啊。。。都快崩溃了
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 11:37:31 | 显示全部楼层
fre是什么?
为什么要不是0?
这么容易崩溃么?你这代码写了几天?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 11:39:37 | 显示全部楼层
我表示看不懂你的测量频率的实现原理是什么....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 11:50:20 | 显示全部楼层
回复【9楼】正点原子:
---------------------------------
没写多久。。fre是最后的频率,原理是打算用定时器捕获边沿来测得频率。信号发生器输出40mv-3.2V  10KHZ的方波,接到PB7上
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 11:58:53 | 显示全部楼层
没写多久就崩溃了啊,很容易崩溃嘛,呵呵.程序猿这么容易崩溃,可是不行的哦...
既然是测频率,我给你指条明路:采用定时器的外部计数模式.妥妥的.
具体我还在论坛发过源码,就看你找资料的能力怎么样了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 16:54:07 | 显示全部楼层
回复【11楼】正点原子:
---------------------------------
改了一个。
开机正常,但是把PA0接上信号之后就死机了。主函数的LED不闪,但是TIM3中断里的LED在闪,这个是什么原因啊??
定时器配置
extern u16    COUNT;
extern u32    FRE;
NVIC_InitTypeDef NVIC_InitStructure;

//TIM2,外部计数模式 
void TIM2_Excnt_Init(u16 arr,u16 psc) 
{  

RCC->APB1ENR|=1<<0;    //TIM2 时钟使能  
RCC->APB2ENR|=1<<2;     //使能PORTA时钟   

GPIOA->CRL&=0XFFFFFFF0; //PA0 清除之前设置   
GPIOA->CRL|=0X00000008; //PA0 输入    
GPIOA->ODR|=0<<0;  //PA0 下拉 

TIM2->ARR=arr;    //设定计数器自动重装值    
TIM2->SC=psc;    //预分频器  

TIM2->CCMR1|=1<<0;  //CC1S=01  选择输入端 IC1映射到TI1上 
TIM2->CCMR1|=0<<4;   //IC1F=0000 配置输入滤波器 不滤波 

TIM2->CCER|=0<<1;   //CC1P=0 上升沿计数 
TIM2->SMCR|=5<<4;    //触发选择:滤波后的定时器输入1(TI1FP1) 
TIM2->SMCR|=7<<0;    //外部时钟模式1 
TIM2->DIER|=1<<0;   //允许更新中断    
TIM2->DIER|=1<<6;   //允许触发中断
TIM2->CR1|=1<<0;       //启动计数器,CEN=1 

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

}

////计数溢出中断服务程序  
void TIM2_IRQHandler(void)
{                  
 TIMx->CR1 &= ~(1<<0);  //禁止                
 if(TIM2->SR&0X0001)//溢出中断 UIF,位0:更新中断标志位置位
 {
  COUNT++;
 }     
 TIM2->SR&=~(1<<0);//清除中断标志位
 TIMx->CR1 |= (1<<0);  //使能
      
}
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

//定时器TIM3初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


TIM_Cmd(TIM3, ENABLE);  //使能TIMx  
}
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志
FRE = COUNT*65535;
FRE = FRE + TIM2->CNT;  
COUNT = 0; 
LED1=!LED1;
}


主函数
TIM3_Int_Init(9999,7199);//10Khz的计数频率,计数到5000为500ms  
TIM2_Excnt_Init(0XFFFF,0); //外部计数,最大值0xffff   
while(1)
{
t++;
key=KEY_Scan(0);   
if(key==1)
{  
if(dacval<4000)dacval+=200;
 DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
}else if(key==3)
{
if(dacval>200)dacval-=200;
else dacval=0;
DAC_SetChannel1Data(DAC_Align_12b_R, dacval);//设置DAC值
}  
if(t==10||key==1||key==3)  //WKUP/KEY1按下了,或者定时时间到了
{   

adcx=DAC_GetDataOutputValue(DAC_Channel_1);//读取前面设置DAC的值
LCD_ShowxNum(124,70,adcx,4,16,0);      //显示DAC寄存器值
temp=(float)adcx*(3.3/4096); //得到DAC电压值
adcx=temp;
  LCD_ShowxNum(124,90,temp,1,16,0);      //显示电压值整数部分
  temp-=adcx;
temp*=1000;
LCD_ShowxNum(140,90,temp,3,16,0X80);  //显示电压值的小数部分
  adcx=Get_Adc_Average(ADC_Channel_1,10); //得到ADC转换值   
temp=(float)adcx*(3.3/4096); //得到ADC电压值
adcx=temp;
  LCD_ShowxNum(124,110,temp,1,16,0);      //显示电压值整数部分
  temp-=adcx;
temp*=1000;
LCD_ShowxNum(140,110,temp,3,16,0X80);  //显示电压值的小数部分
adcx=Get_Adc_Average(ADC_Channel_2,10); //得到ADC转换值   
temp=(float)adcx*(3.3/4096); //得到ADC电压值
adcx=temp;
  LCD_ShowxNum(124,130,temp,1,16,0);      //显示电压值整数部分
  temp-=adcx;
temp*=1000;
LCD_ShowxNum(140,130,temp,3,16,0X80);  //显示电压值的小数
LED0=!LED0;
t=0;
}
delay_ms(10);
LCD_ShowNum(98,150,FRE,8,16);
LCD_ShowNum(98,170,COUNT,8,16);
}
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 16:54:37 | 显示全部楼层
回复【11楼】正点原子:
---------------------------------
PA0接了按键,初始化了,但是没用
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 19:11:27 | 显示全部楼层
拿仿真器跟踪下吧
你那个DAC,是在没必要现在就加进去.测量频率都还没整好呢,发扬各个击破的革命传统,应该讲代码弄到最精简,然后就一个个测试.
俗话说多一个葫芦多一个鬼,还没开始就带着这么多鬼在旁边....
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 19:12:23 | 显示全部楼层
学东西和做事都是要掌握方法的, 所谓事倍功半和事半功倍, 就看你怎么去做了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 19:27:12 | 显示全部楼层
回复【15楼】正点原子:
---------------------------------
嗯。。直接用的DAC例程,想加个测频。
现在能测低频了,调试下来发现是TIM5的中断进不去。中断进不去溢出次数没法算,所以目前能测的最大就65K。
void TIM5_Excnt_Init(u16 arr,u16 psc) 
{  

RCC->APB1ENR|=1<<3;    //TIM5 时钟使能  
RCC->APB2ENR|=1<<2;     //使能PORTA时钟   

GPIOA->CRL&=0XFFFFFFF0; //PA0 清除之前设置   
GPIOA->CRL|=0X00000008; //PA0 输入    
GPIOA->ODR|=0<<0; //PA0 下拉 

TIM5->ARR=arr;   //设定计数器自动重装值    
TIM5->SC=psc;   //预分频器  

TIM5->CCMR1|=1<<0; //CC1S=01  选择输入端 IC1映射到TI1上 
TIM5->CCMR1|=0<<4;  //IC1F=0000 配置输入滤波器 不滤波 

TIM5->CCER|=0<<1;  //CC1P=0 上升沿计数 
TIM5->SMCR|=5<<4;    //触发选择:滤波后的定时器输入1(TI1FP1) 
TIM5->SMCR|=7<<0;    //外部时钟模式1 
TIM5->CR1|=1<<0;       //启动计数器,CEN=1 
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  //TIM5中断 
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级0级 
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级 
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 
NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器



////计数溢出中断服务程序  
void TIM5_IRQHandler(void)

TIM_Cmd(TIM5, DISABLE);
if(TIM5->SR&0X0001)//溢出中断 UIF,位0:更新中断标志位置位
{
                         COUNT++;
}      
TIM5->SR&=~(1<<0);//清除中断标志位
        TIM_Cmd(TIM5, ENABLE);  
}

COUNT值一直为0。
TIM5的arr为FFFF,psc为0。频率超过65K应该会溢出进入中断的啊,奇怪了。。。
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 19:29:36 | 显示全部楼层
回复【16楼】VictorScarlet:
---------------------------------
早就提醒你了,用外部计数的方法,测量频率是最好的.
用中断,每个上升沿/下降沿都要中断,STM32也忙不过来啊...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 19:42:43 | 显示全部楼层
回复【17楼】正点原子:
---------------------------------
这次这个是外部计数,就是把TIM5->CNT的值给FRE。TIM3定时1秒读取一次TIM5的CNT。但是如果信号频率超过FFFF了。溢出次数只能在TIM5的中断里累加啊。。。。问题就是TIM5中断进不去
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 21:02:17 | 显示全部楼层
回复【18楼】VictorScarlet:
---------------------------------
溢出的时候就设计一个中断啊.溢出中断,中断里面统计下就可以了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 21:23:38 | 显示全部楼层
回复【19楼】正点原子:
---------------------------------
void TIM5_IRQHandler(void)

tt++;
tt%=0xffffffff;
LCD_ShowNum(98,270,tt,8,16);
// TIM_Cmd(TIM5, DISABLE);
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
{
COUNT++;
}    
TIM_ClearITPendingBit(TIM5, TIM_IT_Update  );  //清除TIMx更新中断标志
// TIM_Cmd(TIM5, ENABLE);  
}

中断函数写的是这个。COUNT值一直是0。 tt直接不显示。
之前只做过定时中断,外部计数没做过。。。是不是中断有什么条件?
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-7-13 21:56:23 | 显示全部楼层
看看有没有进入中断吧.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

20

主题

79

帖子

0

精华

初级会员

Rank: 2

积分
193
金钱
193
注册时间
2013-6-2
在线时间
2 小时
 楼主| 发表于 2013-7-13 21:58:23 | 显示全部楼层
回复【21楼】正点原子:
---------------------------------
之前没有进中断,现在可以了
原来是NVIC要写在TIM5->CR1|=1<<0;
之前是最后才配置的NVIC。
测频范围能超过65K了。感谢原子哥!!!!
坚持到底就是胜利!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-18 03:56

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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