OpenEdv-开源电子网

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

mini开发板测量外部两路信号的相位差

[复制链接]

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
发表于 2014-4-29 10:23:37 | 显示全部楼层 |阅读模式

论坛搜索了一下关于相位差测量的方法,有几个疑问咨询一下大家,看到大部分人都是说把信号整成方波,通过测量两列方波的时间差算出周期,既然这样,那我是不是需要一个定时器同时捕获两路信号,计算两路信号的时间差啊?

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

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2015-10-8
在线时间
0 小时
发表于 2016-4-11 20:32:57 | 显示全部楼层
是两路信号输入的问题,用两台函数信号发生器输出的信号测的话是不行的,你用单片机输出两路频率相同的方波是可以测出来的
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-4-29 14:38:19 | 显示全部楼层
既然是2路信号,必定是要2个IO去采集,用同一个定时器,捕获两路信号,是可以的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
 楼主| 发表于 2014-5-28 21:53:06 | 显示全部楼层
原子哥,能不能帮我看一下怎么编写求两路方波信号的时间差啊?我看了看定时器捕获的相关知识,也在论坛上搜了一下,在中断里边不知道如何下手编写,或者告诉我思路也行。下边的程序我设置好了两路IO口,PA6和PA7,我想在测量频率的同时也能够测量相位差。
void Cap_Init(u16 arr,u16 psc)
{    
//此部分需手动修改IO口设置
   RCC->APB1ENR|=1<<1;         //TIM3 时钟使能
   RCC->APB2ENR|=1<<2;         //使能PORTA时钟      
   GPIOA->CRL&=0XF0FFFFFF;     //PA6 清除之前设置  
   GPIOA->CRL|=0X08000000;     //PA6 输入   
   GPIOA->ODR|=0<<6;           //PA6 下拉    

GPIOA->CRL&=0X0FFFFFFF;//PA7
GPIOA->CRL|=0X80000000;//  A7 输入 
GPIOA->ODR|=0<<7;//PA7下拉
  
   TIM3->ARR=arr;              //设定计数器自动重装值  自动装置寄存器 65536
   TIM3->SC=psc;              //预分频器  预分频器 71

   TIM3->CCMR1|=1<<0;          //CC1S=01     选择输入端 IC1映射到TI1上
   TIM3->CCMR1|=0<<4;         //IC1F=0000 配置输入滤波器 不滤波
   TIM3->CCMR1|=0<<2;         //IC1PS=00    配置输入分频,不分频
   TIM3->CCER|=0<<1;           //CC1P=0       上升沿捕获 高电平有效
   TIM3->CCER|=1<<0;           //CC1E=1      允许捕获计数器的值到捕获寄存器中

   TIM3->CCMR1|=1<<8;          //CC2S=01     选择输入端 IC2映射到TI2上
   TIM3->CCMR1|=0<<12;         //IC2F=0000 配置输入滤波器 不滤波
   TIM3->CCMR1|=0<<10;         //IC2PS=00    配置输入分频,不分频
   TIM3->CCER|=0<<5;           //CC2P=0       上升沿捕获 高电平有效
   TIM3->CCER|=1<<4;           //CC2E=1      允许捕获计数器的值到捕获寄存器中

   TIM3->DIER|=1<<1;                //当有高电平出现时产生捕获 产生中断 执行 TIM3_IRQChannel 
   TIM3->DIER|=1<<2; 
   TIM3->DIER|=1<<0;                //允许更新中断 产生中断请求    
 
   TIM3->CR1|=0x01;                  //使能计数器     
   MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2   //设置中断 定时器3中断   
}

void TIM3_IRQHandler(void)
{
u32 temp=0;
temp=TIM3->SR;//状态寄存器值赋值给temp
if((temp&0X02))   //计数器值已被捕获(拷贝)至TIM3-CCR1
{
   TIM3->SR=~(1<<1);//清零
 if(CaptureNumber[0]==0)  //判断捕获数是否为零
  {
    IC1ReadValue1[0]=TIM3->CCR1; //如果捕获数为0,将捕获寄存器的值赋给IC1ReadValue1
CaptureNumber[0]=1;//成功标志捕获了一次
 if(Flag_cap==0)
  {
      TIM3->CCER|=1<<1;//捕获发生在IC1的下降沿
Flag_cap=1; //捕获标志=1
      }
 else
 if(Flag_cap==1)
 {
        TIM3->CCER&=~(1<<1);//捕获发生在IC1的上升沿
Flag_cap=0; 
       }  
    }
 else
  if(CaptureNumber[0]==1)
  {
    IC1ReadValue2[0]=TIM3->CCR1; //如果捕获数为1,将捕获寄存器的值赋给IC1ReadValue2
 if(IC1ReadValue2[0]>IC1ReadValue1[0])
 {
      Capture[0]=(IC1ReadValue2[0]-IC1ReadValue1[0]);
     }
 else
 {
      Capture[0]=((0XFFFF-IC1ReadValue1[0])+IC1ReadValue2[0]);
     }
Getnum[0]=Capture[0];
CaptureNumber[0]=0;
 if(Flag_cap==0)  //如果没有捕获 则为低电平时间
 {
      table[0]=Getnum[0];
TIM3->CCER=~(1<<1);
     }
 else
if(Flag_cap==1) //如果成功捕获 则为高电平时间
{
      table[1]=Getnum[0];
TIM3->CCER|=(1<<1);
      }
    }    
 }
 TIM3->SR=0; 
}
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-5-28 23:12:47 | 显示全部楼层
测量相位,你只需要能测量出两路信号的上升沿/下降沿的时间差就可以了啊.
结合频率,就可以算出相位差了.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
 楼主| 发表于 2014-5-31 13:53:00 | 显示全部楼层



原子哥,你帮我看一下我的相位差测量代码吧?我开启了两路IO,TIM3的CH1和CH2,也即PA6和PA7,我在中断里把频率也都测量出来了。问题是这样的,我打算在通道1的第一次捕获发生的时候(假设上图的A点)将TIM3->CCR1的时赋给IC1ReadValue1[0],在第2通道的第一次捕获发生的时候(假设上图的B点)将TIM3->CCR2的时赋给IC1ReadValue1[1],求IC1ReadValue1[1]-IC1ReadValue1[0]的值不就是两路信号的时间差吗,然后除以周期,乘以360度就是相位了,我按照这个思想编了一下代码结果不对的,请原子哥指导一下吧。看一下我的思路对不对,好吧?我决心把这个相位差测量出来,然后把代码分享一下,我基础比较差的。
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h" 
#include "key.h"
#include "exti.h"
#include "wdg.h"
#include "timer.h"
#include "lcd.h"   
#include "rtc.h"
#include "wkup.h"
int main(void)
{
  Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口1初始化   
LED_Init();
  Cap_Init(65535,71);

POINT_COLOR=RED;//设置字体为红色 

while(1)
{  
printf("F:%dHZ\r\n",(u32)1000000/Getnum[0]); //频率1
    delay_ms(500);
printf("F1:%dHZ\r\n",(u32)1000000/Getnum[1]); //频率2
    delay_ms(500);
printf("xiangweicha:%d\r\n",(u32)(IC1ReadValue1[1]-IC1ReadValue1[0])/Getnum[0]*360);//相位差
    delay_ms(500);
   }
}

#include "timer.h"
#include "led.h"
//////////////////////////////////////////////////////////////////////////////////  
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//Mini STM32开发板
//通用定时器 驱动代码   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2010/12/03
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 正点原子 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////  

extern u32 speed_run_time;
u16  TIM3CH1_CAPTURE_STA=0; //输入捕获状态    
u32 TIM3CH1_CAPTURE_VAL; //输入捕获值
u16 tsr; 
u16 TimeValue;
u16 CaptureNumber[5];
u16 Getnum[4];
u16 IC1ReadValue1[5],IC1ReadValue2[5];
u32 Capture[5];
u8 Flag_cap;
u8 Flag_cap1;
u16 table[4];


//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void Timerx_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1;//TIM3时钟使能    
  TIM3->ARR=arr;  //设定计数器自动重装值//刚好1ms    
TIM3->SC=psc;  //预分频器7200,得到10Khz的计数时钟
//这两个东东要同时设置才可以使用中断
TIM3->DIER|=1<<0;   //允许更新中断
TIM3->DIER|=1<<6;   //允许触发中断
     
TIM3->CR1|=0x01;    //使能定时器3
  MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2  
}

void Cap_Init(u16 arr,u16 psc)
{  
//此部分需手动修改IO口设置
   RCC->APB1ENR|=1<<1;         //TIM3 时钟使能
   RCC->APB2ENR|=1<<2;         //使能PORTA时钟      
   GPIOA->CRL&=0XF0FFFFFF;     //PA6 清除之前设置  
   GPIOA->CRL|=0X08000000;     //PA6 输入   
   GPIOA->ODR|=0<<6;           //PA6 下拉    

GPIOA->CRL&=0X0FFFFFFF;//PA7
GPIOA->CRL|=0X80000000;// PA7 输入 
GPIOA->ODR|=0<<7;//PA7下拉
  
   TIM3->ARR=arr;              //设定计数器自动重装值  自动装置寄存器 65536
   TIM3->SC=psc;              //预分频器  预分频器 71
 
TIM3->SR|=1<0;

   TIM3->CCMR1|=1<<0;          //CC1S=01     选择输入端 IC1映射到TI1上
   TIM3->CCMR1|=0<<4;         //IC1F=0000 配置输入滤波器 不滤波
   TIM3->CCMR1|=0<<2;         //IC1PS=00    配置输入分频,不分频
   TIM3->CCER|=0<<1;           //CC1P=0       上升沿捕获 高电平有效 
   TIM3->CCER|=1<<0;           //CC1E=1      允许捕获计数器的值到捕获寄存器中 捕获使能

   TIM3->CCMR1|=1<<8;          //CC2S=01     选择输入端 IC2映射到TI2上
   TIM3->CCMR1|=0<<12;         //IC2F=0000 配置输入滤波器 不滤波
   TIM3->CCMR1|=0<<10;         //IC2PS=00    配置输入分频,不分频
   TIM3->CCER|=0<<5;           //CC2P=0       上升沿捕获 高电平有效
   TIM3->CCER|=1<<4;           //CC2E=1      允许捕获计数器的值到捕获寄存器中

TIM3->DIER&=~(1<<1);
   TIM3->DIER|=1<<1;                //当有高电平出现时产生捕获 产生中断 执行 TIM3_IRQChannel 
TIM3->DIER&=~(1<<2);  
   TIM3->DIER|=1<<2; 
   
TIM3->DIER|=1<<0;                //允许更新中断 产生中断请求    
 
   TIM3->CR1|=0x01;                  //使能计数器  
 
   MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2 //设置中断 定时器3中断  
}

void TIM3_IRQHandler(void)
{
u32 temp=0;
temp=TIM3->SR;//状态寄存器值赋值给temp
if((temp&0X02))   //计数器值已被捕获(拷贝)至TIM3-CCR1
{
   TIM3->SR=~(1<<1);//清零
if(CaptureNumber[0]==0)  //第一次捕获
 {
    IC1ReadValue1[0]=TIM3->CCR1; //保留捕获值
CaptureNumber[0]=1;//设置成功捕获了一次  
    }
else
 if(CaptureNumber[0]==1)  //第2次捕获
 {
    IC1ReadValue2[0]=TIM3->CCR1; //保留捕获值
if(IC1ReadValue2[0]>IC1ReadValue1[0])
{
      Capture[0]=(IC1ReadValue2[0]-IC1ReadValue1[0]);
     }
else
{
      Capture[0]=((0XFFFF-IC1ReadValue1[0])+IC1ReadValue2[0]);
     }
Getnum[0]=Capture[0];
CaptureNumber[0]=0;
 
    }   
  }

 /*捕获/比较2*/
else 
if((temp&0X04))   //计数器值已被捕获(拷贝)至TIM3-CCR2

TIM3->SR=~(1<<2);//清零
     if(CaptureNumber[1]==0)  //第一次捕获
 {
     IC1ReadValue1[1]=TIM3->CCR2; //保留捕获值
CaptureNumber[1]=1;//设置成功捕获了一次  
    }
else
if(CaptureNumber[1]==1)  //第2次捕获
 {
     IC1ReadValue2[1]=TIM3->CCR2; //保留捕获值
if(IC1ReadValue2[1]>IC1ReadValue1[1])
{
      Capture[1]=(IC1ReadValue2[1]-IC1ReadValue1[1]);
     }
else
{
      Capture[1]=((0XFFFF-IC1ReadValue1[1])+IC1ReadValue2[1]);
     }
Getnum[1]=Capture[1];
CaptureNumber[1]=0;
    }   
}
 TIM3->SR=0; 
}































回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-5-31 22:48:44 | 显示全部楼层
回复【5楼】lixulongren:
---------------------------------
你第二次捕获的时候:
 if(CaptureNumber[0]==1)  //第2次捕获
 {
    IC1ReadValue2[0]=TIM3->CCR1; //保留捕获值

怎么还是读取CCR1的值?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
 楼主| 发表于 2014-6-1 10:31:56 | 显示全部楼层
回复【6楼】正点原子:
---------------------------这个还是通道1,PA6的捕获啊,PA7的捕获在后边呢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-1 13:01:47 | 显示全部楼层
回复【7楼】lixulongren:
---------------------------------
你不是测时间差么?
怎么要同一个波捕获2次?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
 楼主| 发表于 2014-6-1 13:48:03 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
同一个波捕获两次不就得到这个波的周期了吗!程序有两路,第一路是这样的:判断是不是第一次捕获,如果是,则将TIM3->CCR1的值赋给IC1ReadValue1[0],如果是第二次捕获,则将TIM3->CCR1的值赋给IC1ReadValue2[0],IC1ReadValue2[0]减去IC1ReadValue1[0]不就得到信号1的周期了;第二路同样是这样的:判断是不是第一次捕获,如果是,则将TIM3->CCR2的值赋给IC1ReadValue1[1],如果是第二次捕获,则将TIM3->CCR2的值赋给IC1ReadValue2[1]。按照这样的思路的话,那么第一路信号的第一次值与第二路信号的第一次捕获值之差不就是两路信号的时间差了吗?也即:IC1ReadValue1[1]-IC1ReadValue1[0]
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-1 15:32:43 | 显示全部楼层
回复【9楼】lixulongren:
---------------------------------
这样可以,不过要考虑溢出情况。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

29

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
228
金钱
228
注册时间
2013-5-4
在线时间
0 小时
 楼主| 发表于 2014-6-1 16:30:14 | 显示全部楼层
我就是按照这个思路走的,可就是测量不出来相位差,IC1ReadValue1[1]-IC1ReadValue1[0]的值经常跳动,我除以周期乘以360的话相位差都上千了,这肯定不对啊,原子哥认真帮我看一下吧
回复 支持 反对

使用道具 举报

16

主题

85

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
331
金钱
331
注册时间
2013-12-18
在线时间
64 小时
发表于 2014-6-19 21:57:47 | 显示全部楼层
测量两路方波的相位差

UCGUI_bisai.zip

22.38 MB, 下载次数: 12770

回复 支持 反对

使用道具 举报

1

主题

215

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2013-9-23
在线时间
4 小时
发表于 2015-1-19 19:59:12 | 显示全部楼层
回复【11楼】lixulongren:
---------------------------------
楼主搞定没,是什么问题呢?可以共享一下吗?
回复 支持 反对

使用道具 举报

1

主题

215

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2013-9-23
在线时间
4 小时
发表于 2015-1-19 21:24:25 | 显示全部楼层
回复【12楼】yysforever:
---------------------------------
请问大神你这测两路方波相位差的思路是怎样的?
回复 支持 反对

使用道具 举报

38

主题

121

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
340
金钱
340
注册时间
2013-12-7
在线时间
15 小时
发表于 2015-4-17 11:18:56 | 显示全部楼层
楼主解决了吗,我在做F107的地感线圈测试,要用到两路频率差,
每天都是新开始
回复 支持 反对

使用道具 举报

10

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2015-5-19
在线时间
10 小时
发表于 2015-7-15 12:14:10 | 显示全部楼层
回复【12楼】yysforever:
---------------------------------
你的原理是什么,你只是测了两路脉冲宽度啊
回复 支持 反对

使用道具 举报

2

主题

10

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2015-10-29
在线时间
16 小时
发表于 2015-12-3 17:10:49 | 显示全部楼层

我也用一个定时器两个通道试过,进入了一个if不得等一次中断结束了才出来么,就是测下一组的第一个上升沿时已经过去1个周期多了,我觉得这个计数值的变化比较难弄,还在摸索中,楼主你弄出来了么?

都快而立之年,还是要写代码...
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2021-3-11
在线时间
15 小时
发表于 2021-4-11 21:13:34 | 显示全部楼层
PPPPPPP/P/P/P

回复 支持 反对

使用道具 举报

7

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2021-3-14
在线时间
20 小时
发表于 2021-12-9 16:11:18 | 显示全部楼层
lixulongren 发表于 2014-5-31 13:53
原子哥,你帮我看一下我的相位差测量代码吧?我开启了两路IO,TIM3的CH1和CH2,也即PA6和PA7,我在中断 ...

兄弟这种方法测出来误差怎么样?能否发下工程
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 22:27

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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