OpenEdv-开源电子网

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

使用STM32F100的AD和DMA模块测量两路信号的相位差

[复制链接]

2

主题

3

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2012-3-15
在线时间
3 小时
发表于 2012-3-16 00:31:01 | 显示全部楼层 |阅读模式

请教大家一个问题,如何利用STM32自带AD和DMA模块测量两路信号的相位差。
现在我有一路基准信号,是用TIM3产生的占空比为50%的5kHz的PWM波,测量该PWM波和外围电路上一个5kHz的正弦波的相位差。
由于我采用了FFT,所以我需要对5kHz的正弦波连续采样1024个点,这里我采用了DMA的方式,DMA的缓冲区设置为1024
程序如下,前面都是配置AD和DMA的,没什么问题,关键在AD转换启动的那一刻,也就是ADC_SoftwareStartConvCmd(ADC1, ENABLE)这里
启动以后,我把那个用于产生PWM波的TIM3中的计数值TIM3->CNT放到一个变量PlusePhase中存储起来,这就是PWM在AD转换开始时的相位,应该是没有问题的吧?
接下来,我对每采集到的1024个点进行FFT(我程序FFT是没有问题的,将AD值导出后,用我MATLAB算的结果和我程序是一致的)测量相位,多次测量发现
该信号的相位和PWM波相位的相位差一直在变化,而我用示波器看,这两路同频率的信号相位差是恒定的,请问这是什么原因呢?
我怀疑是不是ADC_SoftwareStartConvCmd(ADC1, ENABLE)以后,AD采用需要经过一段间隔时间才能进行。如果这段时间是固定的,那相位差还是应该恒定不变,
难道这个间隔一直在变吗?很不解,所以请大家帮帮忙啦...
小弟先行谢过...

/***********************************************************************************************************

AD的配置
***********************************************************************************************************/
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //独立的转换模式
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;       //关闭扫描模式
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;       //开启连续转换模式
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  //ADC外部开关,关闭状态
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;      //对齐方式,ADC为12位中,右对齐方式
  ADC_InitStructure.ADC_NbrOfChannel = 1;      //开启通道数,1个
  ADC_Init(ADC1, &ADC_InitStructure);

/***********************************************************************************************************

DMA的配置
***********************************************************************************************************/
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;     //DMA对应的外设基地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValueTab;   //内存存储基地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;     //DMA的转换模式为SRC模式,由外设搬移到内存
  DMA_InitStructure.DMA_BufferSize = 1024;         //DMA缓存大小,1个
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;   //接收一次数据后,设备地址禁止后移
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    //接收一次数据后,目标内存地址后移
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;    //定义外设数据宽度为16位
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;     //DMA搬移数据尺寸,HalfWord就是为16位
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;        //转换模式,循环缓存模式。
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;     //DMA优先级高
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;        //M2M模式禁用

 

/***********************************************************************************************************

AD的校准

***********************************************************************************************************/

  ADC_Cmd(ADC1, ENABLE);          //开启ADC1  
  ADC_ResetCalibration(ADC1); 
  while(ADC_GetResetCalibrationStatus(ADC1)); 
  ADC_StartCalibration(ADC1);  
  while(ADC_GetCalibrationStatus(ADC1));

/***********************************************************************************************************

AD和DMA的初始化

***********************************************************************************************************/

  ADC_RegularChannelConfig(ADC1, Channel, 1, ADC_SampleTime_7Cycles5);
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  DMA_DeInit(DMA1_Channel1);          //开启DMA1的第一通道
  ADC_DMACmd(ADC1, ENABLE);         
 

/***********************************************************************************************************

KEY:软件触发

***********************************************************************************************************/
  ADC_SoftwareStartConvCmd(ADC1, ENABLE)


  PlusePhase = TIM3->CNT;           //方波相位


  while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));


  ADC_SoftwareStartConvCmd(ADC1, DISABLE);


  DMA_ClearFlag(DMA1_FLAG_TC1);


  return ADCConvertedValueTab;

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-3-16 09:13:46 | 显示全部楼层
你的正弦信号是不是有正负周期的?
这方面我不熟,呵呵.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

3

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2012-3-15
在线时间
3 小时
 楼主| 发表于 2012-3-16 09:50:25 | 显示全部楼层
木有额~~ 我正弦信号有一个偏置  采集是没有问题的  我用串口输出  用matlab画线还是挺漂亮的 只是不知道为什么相位不对  呵呵~~
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-3-16 12:36:08 | 显示全部楼层
你的matlab怎么画线的?
首先FFT,然后反傅里叶变换?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

1436

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2209
金钱
2209
注册时间
2010-12-16
在线时间
190 小时
发表于 2012-3-16 13:23:53 | 显示全部楼层
记得线性代数的第十多页有个卷积的式子,把输入信号和一个标准正弦信号卷积就可以得到信号与标准正弦的相位差,两个相位差的差值应该就是你的要求,这样运算量比FFT少很多。
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1436

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2209
金钱
2209
注册时间
2010-12-16
在线时间
190 小时
发表于 2012-3-16 13:26:23 | 显示全部楼层
如果需要测量的频率不确定,有个正弦迭代的式可以快速计算正弦表。

具体还要自己找,只回忆到这些,其他全送给老师了。
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-25 04:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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