[讨论] 使用MSP430f149单片机和TI的DAC5571产生正弦波

门主老k   2014-1-12 16:01 楼主
我使用149单片机和DAC5571合成正弦波,使用查表法合成,但是发现输出频率一般都最多只有几百HZ,而且取点不敢取100以上的点,不然频率小的可怜。取40个点CCR0=50000时输出4HZ,CCR0=5000时输出40HZ,CCR0=500时输出400HZ,CCR0=50时变成了119HZ。不知道怎么回事,我想输出一个30KHZ的正弦波。到底是哪里出了问题,各位大神求教。

回复评论 (3)

#include
#include "IIC.h"
#include "IIC.c"

uint flag=0;
uint tosin[256]={0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5

,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5

,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd

,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda

,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99

,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51

,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16

,0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00

,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15

,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e

,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80 };
uchar sin64[64]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
uchar sin40[40]={ 0x7F,0x93,0xA6,0xB9,0xCA,0xD9,0xE6,0xF1,0xF8,0xFD,0xFE,0xFD,0xF8,0xF1,0xE6,0xD9
,0xCA,0xB9,0xA6,0x93,0x7F,0x6B,0x58,0x45,0x34,0x25,0x18,0x0D,0x06,0x01,0x00,0x01
,0x06,0x0D,0x18,0x25,0x34,0x45,0x58,0x6B};
uchar sin20[20]={ 0x7F,0xA6,0xCA,0xE6,0xF8,0xFE,0xF8,0xE6,0xCA,0xA6,0x7F,0x58,0x34,0x18,0x06,0x00
,0x06,0x18,0x34,0x58};
uchar sin60[61]={0x7F,0x8C,0x9A,0xA6,0xB3,0xBF,0xCA,0xD4,0xDE,0xE6,0xED,0xF3,0xF8,0xFC,0xFE,0xFE
,0xFE,0xFC,0xF8,0xF3,0xED,0xE6,0xDE,0xD4,0xCA,0xBF,0xB3,0xA6,0x9A,0x8C,0x7F,0x72
,0x64,0x58,0x4B,0x3F,0x34,0x2A,0x20,0x18,0x11,0x0B,0x06,0x02,0x00,0x00,0x00,0x02
,0x06,0x0B,0x11,0x18,0x20,0x2A,0x34,0x3F,0x4B,0x58,0x64,0x72,0x7F};
uchar sin80[80]={ 0x7F,0x89,0x93,0x9D,0xA6,0xB0,0xB9,0xC2,0xCA,0xD2,0xD9,0xE0,0xE6,0xEC,0xF1,0xF5
,0xF8,0xFB,0xFD,0xFE,0xFE,0xFE,0xFD,0xFB,0xF8,0xF5,0xF1,0xEC,0xE6,0xE0,0xD9,0xD2
,0xCA,0xC2,0xB9,0xB0,0xA6,0x9D,0x93,0x89,0x7F,0x75,0x6B,0x61,0x58,0x4E,0x45,0x3C
,0x34,0x2C,0x25,0x1E,0x18,0x12,0x0D,0x09,0x06,0x03,0x01,0x00,0x00,0x00,0x01,0x03
,0x06,0x09,0x0D,0x12,0x18,0x1E,0x25,0x2C,0x34,0x3C,0x45,0x4E,0x58,0x61,0x6B,0x75};
uchar sin50[50]={ 0x7F,0x8F,0x9F,0xAE,0xBC,0xCA,0xD6,0xE1,0xEB,0xF2,0xF8,0xFC,0xFE,0xFE,0xFC,0xF8
,0xF2,0xEB,0xE1,0xD6,0xCA,0xBC,0xAE,0x9F,0x8F,0x7F,0x6F,0x5F,0x50,0x42,0x34,0x28
,0x1D,0x13,0x0C,0x06,0x02,0x00,0x00,0x02,0x06,0x0C,0x13,0x1D,0x28,0x34,0x42,0x50
,0x5F,0x6F};
uchar Write_DAC(uchar wdata);
void Clock_Init();
void TimerA_Init();
/*******************************************
函数名称:Write_DAC
功    能:向DAC中写入输出电压数据
参    数:无
返回值  :写入结果:1--成功,0--失败
********************************************/
uchar Write_DAC(uchar wdata)
{
    start();
    write1byte(0x98);                     //DAC的设备地址
    if(check())   write1byte(wdata>>4);   //写控制模式和电压数据的高四位
    else          return 0;
    if(check())   write1byte(wdata<<4);   //写电压数据的低四位
    else          return 0;
    if(check())          stop();
    else          return 0;
    return 1;
}
//*************************************************************************
//       系统时钟初始化
//*************************************************************************
void Clock_Init()
{
  uchar i;
  BCSCTL1&=~XT2OFF;                 //打开XT振荡器
  BCSCTL2|=SELM1+SELS;              //MCLK为8MHZ,SMCLK为8MHZ
  do{
    IFG1&=~OFIFG;                   //清除震荡标志
    for(i=0;i<100;i++)
       _NOP();                      //延时等待
  }
  while((IFG1&OFIFG)!=0);           //如果标志为1,则继续循环等待
  IFG1&=~OFIFG;
}

void TimerA_Init()
{
  TACTL=TASSEL_2+MC_1+TACLR;
  CCTL0=CCIE;
  CCR0=500;                 //30KHZ  CCR0约为133
}

/****************主函数****************/
void main(void)
{   
     /*下面六行程序关闭所有的IO口*/
    P1DIR = 0XFF;P1OUT = 0XFF;
    P2DIR = 0XFF;P2OUT = 0xff;
    P3DIR = 0XFF;P3OUT = 0XFF;
    P4DIR = 0XFF;P4OUT = 0xff;
    P5DIR = 0XFF;P5OUT = 0xff;
    P6DIR = 0XFF;P6OUT = 0XFF;
  
     WDTCTL = WDTPW + WDTHOLD;    //停止看门狗
     Clock_Init();
     Set_IO();
     TimerA_Init();
     _EINT();                   //设置IIC使用的IO方向
         
     while(1)
     {
      
       if(0       {
         Write_DAC(sin50[flag]);   
      }
     }   
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A(void)
{
  
//  CCR0+=1;
  flag++;
  if(flag==50)
  {
    flag=0;
  }   
}
点赞  2014-1-12 16:04
程序就是上面的程序,我查了网上的很多程序,感觉差不了多少,不知道为什么就是不能实现功能
点赞  2014-1-12 16:05
149 本来就跑的不是很快。你又要求采样精度和频率。他自然跑不到。换个主频高一点的单片机。或者用DDS也可以。用的人挺多的,上KHz挺容易的,输出的波形还稳定。
点赞  2014-1-13 19:57
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复