OpenEdv-开源电子网

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

STM32F407用两个定时器双通道测双频率,测量不正确

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-11-8
在线时间
5 小时
发表于 2019-1-6 20:10:46 | 显示全部楼层 |阅读模式
7金钱
本帖最后由 六道轮回 于 2019-1-6 20:12 编辑

这里用两个定时器的两个通道测频率。当分别一个一个测的时候没有问题,误差之内,但是两个一起测时,比如一个输入10000Hz,另一个4000Hz,但是显示两个值却为1000,目前判断为两个中断互相干扰,或者可能中断太频繁,初步使用交替中断,,但还是有问题,所以小白特来求助,希望给位伸出援手,非常感谢!
以下是主程序和中断服务函数。
主程序:
int main(void)
{
u8 key;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168);  //初始化延时函数
uart_init(115200);//初始化串口波特率为115200
KEY_Init();
LCD_Init();
LED_Init();
   LCD_display_char24(30,260,BLACK,BACK_COLOR,"按键0:-------");
   LCD_display_char24(30,290,BLACK,BACK_COLOR,"按键1:频率检测");  
  TIM5_CH1_Cap_Init(0XFFFFFFFF,2-1); //84M/2=42Mhz的计数频率计数到FFFFFFFF
TIM3_Int_Init(20000-1,21000-1); //设定定时器3的溢出时间为5S
TIM2_CH3_Cap_Init(0XFFFFFFFF,2-1);
TIM4_Int_Init(20000-1,21000-1);//设定定时器4的溢出时间为5S
while(1)
   {
    key=KEY_Scan(0);
     if(key)
    {         
      switch(key)
      {      
         case KEY2_PRES:
              while(1)
         { LCD_display_char24(90,90,BLUE,BACK_COLOR,"PA0");
          LCD_display_char24(90,150,BLUE,BACK_COLOR,"PA2");
          printf("F:%5.1f HZ\r\n",Freq_value1);
          printf("T:%5.1f HZ\r\n",(Freq_value2/2));
          Show_flag1=0;
           delay_ms(500);
          if(Show_flag1==1)
                    {
          //show_frequency1((Freq_value2/2));
          LCD_display_char24(50,180,RED,BACK_COLOR,"%5.1f Hz    ",(Freq_value2/2));
          TIM_Cmd(TIM2,DISABLE );
          TIM_Cmd(TIM5,ENABLE );
          TIM_SetCounter(TIM3,0);
                    }
          Show_flag=0;
           delay_ms(500);
          if(Show_flag==1)
                    {
          show_frequency(Freq_value1);
          TIM_Cmd(TIM5,DISABLE );
          TIM_Cmd(TIM2,ENABLE );
          TIM_SetCounter(TIM4,0);
                    }
中断服务程序:

//定时器5中断服务程序  
void TIM5_IRQHandler(void)
{
if(mtjishu&0x80000000)//如果第31位为1,表示2s时间已到
{
  mtread2=TIM_GetCounter(TIM3);
  shijian=mtread1+mtread2;
  shijian*=250;
  Freq_value1=(float)(t1+1)*1000000/shijian;
  mtjishu=0;
  TIM_SetCounter(TIM3,0);
  Show_flag=1;      
}
else
{
  mtread1=TIM_GetCounter(TIM3);
  mtjishu++;
  if(mtread1>=8000)//是否计数到2s
   {
     t1=mtjishu&0X7FFFFFFF;
   mtjishu|=0x80000000;
   TIM_SetCounter(TIM3,0);
    }
}  
  TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);
}

void TIM3_IRQHandler(void)
{  
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
  LED1=!LED1;//DS1翻转
}

TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}
void TIM2_IRQHandler(void)
{
if(mtjishu1&0x80000000)//如果第31位为1,表示2s时间已到
{
  mtread22=TIM_GetCounter(TIM4);
  shijian1=mtread21+mtread22;
  shijian1*=250;
  Freq_value2=(float)(t2+1)*1000000/shijian1;
  mtjishu1=0;
  TIM_SetCounter(TIM4,0);
  Show_flag1=1;      
}
else
{
  mtread21=TIM_GetCounter(TIM4);
  mtjishu1++;
  if(mtread21>=8000)//是否计数到2s
   {
     t2=mtjishu1&0X7FFFFFFF;
   mtjishu1|=0x80000000;
   TIM_SetCounter(TIM4,0);
    }
}  
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC3|TIM_IT_Update);
}


void TIM4_IRQHandler(void)
{  
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //溢出中断
{
  LED0=!LED0;//DS0翻转
}

TIM_ClearITPendingBit(TIM4,TIM_IT_Update);  //清除中断标志位
}


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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-1-7 01:45:02 | 显示全部楼层
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2018-11-8
在线时间
5 小时
 楼主| 发表于 2019-1-7 09:06:07 | 显示全部楼层
可有人指点一下:
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-10 15:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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