牛卧堂MCU技术交流

标题: 如何产生频率连续可调的方波? [打印本页]

作者: leefine    时间: 2015-4-18 10:07
标题: 如何产生频率连续可调的方波?
如何产生频率连续可调的方波?

作者: Angus    时间: 2015-4-26 10:45
本帖最后由 Angus 于 2015-4-26 10:46 编辑

1>,可用 PWM 产生,CNR是周期,每次写完周期后,再把占空比CMR的值写成周期CNR的值的一半
2>,可用Timer产生,把Timer醒成反转模式,Timer的寄存器 CMPR就是半周期值。

作者: leefine    时间: 2015-5-23 15:20
可有具体参看资料或者例子?谢谢!
作者: leefine    时间: 2015-5-23 15:22
我是想搞一个频率值介于1Hz-10000Hz连续可调的?
作者: leefine    时间: 2015-5-23 15:45
我使用环境是Keil MDK5.0
作者: leefine    时间: 2015-5-23 16:31
查看量不少,回复太少。
作者: Angus    时间: 2015-5-23 17:37
方法一, 用定时器toggle模式. 只要调整Timer寄存器CMPR值,就调整了频率.
方法二, 用PWM, 调整频率时,要同时调整周期寄存器CNR和占空比寄存器CMR

作者: eeyrw    时间: 2015-5-23 21:26
其实可以考虑下DDS合成算法,用单个方波做波表。
作者: leefine    时间: 2015-5-26 20:28
eeyrw,是否可以提供详细点的资料,谢谢。
作者: eeyrw    时间: 2015-5-27 13:50
本帖最后由 eeyrw 于 2015-5-27 13:54 编辑
  1. // 凑合看看吧,这个好象是可以同时合成多个波叠加的。。
复制代码
  1. #include "sineTable.h"
  2. #include "dds.h"

  3. #define DDS_FRAME_SIZE 2000
  4. #define DDS_UNITS_NUM 16

  5. STEREO_SAMPLE ddsFrameSample0[DDS_FRAME_SIZE];
  6. STEREO_SAMPLE ddsFrameSample1[DDS_FRAME_SIZE];


  7. DDS_CFG ddsCfg[DDS_UNITS_NUM];


  8. void DdsInitCfg(DDS_CFG* ddsCfg)
  9. {
  10.         ddsCfg->cst1=0xFFFFFFFF/ddsCfg->sampleRate;
  11. }
  12. void DdsChangeFreq(uint32_t freq,uint32_t chn)
  13. {

  14.         ddsCfg[chn].desireFreq=freq;


  15. }
  16. void DdsInit(void)
  17. {
  18.         uint32_t i;
  19.         for(i=0; i<DDS_UNITS_NUM; i++)
  20.         {
  21.                 ddsCfg[i].desireFreq=0;
  22.                 ddsCfg[i].phaseAccReg=0;
  23.                 ddsCfg[i].sampleRate=44100;

  24.                 DdsInitCfg(&ddsCfg[i]);
  25.         }

  26.         SoundBufferAssign((uint32_t)ddsFrameSample0,DDS_FRAME_SIZE*4,(uint32_t)ddsFrameSample1,DDS_FRAME_SIZE*4);
  27. }

  28. void PhaseAccRegUpdate(DDS_CFG* ddsCfg)
  29. {
  30.         ddsCfg->phaseAccReg=ddsCfg->desireFreq*ddsCfg->cst1+ddsCfg->phaseAccReg;
  31. }

  32. void DdsPeriodRoutine(void)
  33. {
  34.         uint32_t i,j;

  35.         uint32_t* rawBufPtr;

  36.         int16_t* samplePtr;

  37.         int32_t res;

  38.         uint32_t waveTableIdx=0;
  39.         int32_t waveValue;
  40.         res=SoundOpenFreeBuffer(&rawBufPtr);

  41.         if(res!=-1)
  42.         {
  43.                 samplePtr=(int16_t*)rawBufPtr;

  44.                 waveValue=0;


  45.                 for(i=0; i<DDS_FRAME_SIZE; i++)
  46.                 {
  47.                         for(j=0; j<DDS_UNITS_NUM; j++)
  48.                         {
  49.                                 PhaseAccRegUpdate(&ddsCfg[j]);

  50.                                 waveTableIdx=(ddsCfg[j].phaseAccReg>>18)&0x3FFF;
  51.                                 waveValue+=sineTbl[waveTableIdx];

  52.                         }
  53.                         waveValue/=DDS_UNITS_NUM;

  54.                         *samplePtr=waveValue;
  55.                         samplePtr++;
  56.                         *samplePtr=waveValue;
  57.                         samplePtr++;

  58.                 }
  59.                 res=SoundCloseBuffer(&rawBufPtr);
  60.         }


  61. }
复制代码




作者: chenwenbin    时间: 2015-6-2 10:55
用PWM就可以實現了




欢迎光临 牛卧堂MCU技术交流 (http://www.nuvoton-mcu.com/) Powered by Discuz! X3.2