⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msp430-fw-dds[1].c

📁 老外用DDSAD9854和MSP430做的一个收音机的源程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
//===================================================================
//
//  MSP430F149 based direct digital conversion
//  software defined radio receiver
//
//  (C) 2005 Jan Florian Wagner OH2GHR, jwagner@cc.hut.fi
//  http://users.tkk.fi/~jwagner/electr/dc-rx/
//
//  Firmware Version 1.03
//
//  Licence: free as per GNU GPL
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//  
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  
//  For further details see the included GPL.TXT 
//  or go to http://www.gnu.org/copyleft/gpl.html  
//
//===================================================================
//
//  Contains AD9854 configuration routines for parallel mode, and
//  some auxiliary user functions.
//  
//  DDS has an external 50MHz crystal oscillator connected.
//  
//  Also contains different board operational mode functions, like
//  auto scanning, manual scanning, chirp or modulation, etc.
//  (currently only the "manual scanning" over PC, tuning wheel and
//  keyboard is implemented)
//
//  Additionally contains funcs to convert the DDS tuning word
//  into a frequency and string representation.
//
// port 4: 8 bit data and
//         5 bit address through 74hc573 latch
// port 5: 5.0 RST, 5.1 !RD, 5.2 !WR, 5.3 IOCLK,
//         5.4 ALE,
//         not yet used : 5.5 FSK/MOD, 5.6 KEYING

#include "MSP430-fw-stdincludes.h"

#define DEBUG_DDS
#define POS_STEP 4
#define NEG_STEP -4

volatile unsigned long long   dds_lo_tw;        // tuning frequency (LO main freq)
volatile unsigned long long   dds_delta;        // freq step
volatile signed int           dds_wheeldivider; // wheel divider (turns vs freq steps)

char freq_str[12+10]; // filled out by call to DDS_Tuningword2FreqStr(tw), 
                      // [0..11]=LCDformat, [12..21]=PCformat, [22]=spare

//===================================================================
//
//       DDS CONFIGURATION ROUTINES
//


//-------------------------------------------------------------------
// DDS_init ( long long )
//
// Initialize the DDS : parallel data, external update clock,
//   no keying, no inverse sinc filtering, multipliers off, 
//   single tone mode
//
void DDS_init(void) 
{
   int i=0;

   // set frequency and step size (tuning wheel)
   dds_wheeldivider = 1;
//   if(RestoreSettings()==RESP_NACK) {  // get stored settings (not working 100% yet...)
      dds_delta = DEFAULT_DELTA;       // or use default settings
      dds_lo_tw = DEFAULT_LO_TW;
//   }
   
   // msp430 port setup
   DDS_DATA_DIR = 0xFF;
   DDS_CTRL_DIR = ~DDS_CLK;  // first, all outputs except AD9854 clock (input)
   DDS_DATA_OUT = 0;
   DDS_CTRL_OUT = 0xFF;

   // assert reset for a while
   DDS_CTRL_OUT |= DDS_RST;
   for(i=32000; i>0; --i) _NOP(); // wait a bit  
   DDS_CTRL_OUT &= ~DDS_RST;

   // assign to external update clock
   // addr 0x1F bits: 7=clrAcc1 6=clrAcc2 5=Triangle
   //                 4=SrcQDac (hi=no quadrature)
   //                 3=Mode[2] 2=Mode[1] 1=Mode[0]
   //                 0=Ext/IntUpdateClk (0=ext 1=int)
   DDS_writeByte( 0x00, 0x1F );
   DDS_commit();
   for(i=32000; i>0; --i) _NOP(); // wait a bit

   DDS_CTRL_DIR = 0xFF;  // now MSP430 can steer the clock signal (output)

   // DAC setup
   // addr 0x1D bits: 7=x 6=x 5=x 4=comparator power down (pd)
   //                 3=0 2=qdac pd 1=dac pw 0=dig pd
   // 0001 0001 - user-specified digital multipliers disabled, comp disabled
   DDS_writeByte( 0x10, 0x1D );

   // clock setup
   // addr 0x1E bits: 7=x
   //                 6=PLL range (0 <200MHz, 1 200..300MHz) 5=bypass PLL
   //                 4..0=ref clock multplier
   // 010 00100 - range 1, pll on, x4 (50->200 MHz)
   // DDS_writeByte( 0x40+DDS_MULTIPLIER, 0x1E );
   DDS_writeByte( 0x00+DDS_MULTIPLIER, 0x1E );

   // invsinc and other settings
   // addr 0x20 bits: 7=x 6=power down inv sinc
   //                 5=osk enable (shaped keying)
   //                 4=osk int (1 internal multipliers, 0 user specified multipliers)
   //                 3=x 2=x
   //                 1=lsb first (serial I/O) 0=sdo active (serial I/O)
   // 0101 0000 - inv sinc off, internal multipliers, keying off
   DDS_writeByte( 0x50, 0x20 );

   DDS_commit();

   return;
}


//-------------------------------------------------------------------
// unsigned char DDS_readByte ( unsigned char )
//
// Read back one byte from the DDS registers. Mainly useful for
// debugging the DDS routines.
//
unsigned char DDS_readByte(unsigned char addr)
{
   unsigned char temp=0;

   // write address
   DDS_DATA_DIR = 0xFF;
   DDS_DATA_OUT = addr;
   DDS_CTRL_OUT |= DDS_ALE;        // address into latch
   DDS_CTRL_OUT &= ~DDS_ALE; 

   // read data
   DDS_DATA_DIR = 0x00;
   DDS_CTRL_OUT &= ~DDS_NRD;       // "read"=0/lo

   temp = DDS_DATA_IN;

   DDS_CTRL_OUT |= DDS_NRD;        // return "read" to hi
   DDS_DATA_DIR = 0xFF;

   return temp;
}


//-------------------------------------------------------------------
// DDS_writeByte ( unsigned char, unsigned char )
//
// Writes one byte to the DDS but doesn't commit it yet.
//
void DDS_writeByte(unsigned char data, unsigned char addr) 
{
   DDS_DATA_DIR = 0xFF;

   // write address
   DDS_DATA_OUT = addr;
   DDS_CTRL_OUT |= DDS_ALE;      // address into latch
   DDS_CTRL_OUT &= ~DDS_ALE;

   // write data
   DDS_DATA_OUT = data;
   DDS_CTRL_OUT &= ~DDS_NWR;     // "write"=0/lo
   DDS_CTRL_OUT |= DDS_NWR;      // return write to hi

   // remember to call DDS_commit() later
   // to have the AD9854 apply the new settigns
   return;
}


//-------------------------------------------------------------------
// DDS_commit ( )
//
// Commit the transferred DDS data, pulses the IO update clock to
// move the data from the AD9854 internal buffer to its registers.
//
void DDS_commit(void) 
{
   DDS_CTRL_OUT |= DDS_CLK;
   DDS_CTRL_OUT &= ~DDS_CLK;
}


//-------------------------------------------------------------------
// DDS_writeLongTuningword ( long long )
//
// Writes the tuning word to the DDS, but doesn't commit the 
// data yet.
//
void DDS_writeLongTuningword(long long tw) 
{
   long long tmp = tw;
   unsigned char out; int i;
   
   // write last 6 bytes of tuningword (=all DDS TW registers)
   for(i=0;i<6;i++) {
      out = (unsigned char)(tmp&0xFF);
      DDS_writeByte(out, 0x09-i);
      tmp=tmp>>8;
   }
   // remember to call DDS_commit() later
   // to have the AD9854 apply the new settigns
   return;
}




//===================================================================
//
//       OPERATIONAL MODE FUNCTIONS
//


//-------------------------------------------------------------------
// DDS_autoscan1 ( )
//
// For DEBUGGING only
//
void DDS_autoscan1(void) 
{
   signed long scn = 0x04000000;
   // 0x08E00001 = 6.94 MHz
   // 0x01E00001 = 1.6 MHz
   // 0x05400000 = 4.1 MHz
   // 0x04000000 = 3.13 MHz
   signed long tmp;
   signed long dir = POS_STEP;

   DDS_DATA_DIR = 0xFF;

   // load multipliers (just to be safe)

   DDS_DATA_OUT = 0x21; setBit(DDS_CTRL_OUT,DDS_ALE); clrBit(DDS_CTRL_OUT,DDS_ALE);
   DDS_DATA_OUT = 0xFF; clrBit(DDS_CTRL_OUT,DDS_NWR); setBit(DDS_CTRL_OUT,DDS_NWR);
   DDS_DATA_OUT = 0x22; setBit(DDS_CTRL_OUT,DDS_ALE); clrBit(DDS_CTRL_OUT,DDS_ALE);
   DDS_DATA_OUT = 0xFF; clrBit(DDS_CTRL_OUT,DDS_NWR); setBit(DDS_CTRL_OUT,DDS_NWR);
   
   DDS_DATA_OUT = 0x23; setBit(DDS_CTRL_OUT,DDS_ALE); clrBit(DDS_CTRL_OUT,DDS_ALE);
   DDS_DATA_OUT = 0xFF; clrBit(DDS_CTRL_OUT,DDS_NWR); setBit(DDS_CTRL_OUT,DDS_NWR);
   DDS_DATA_OUT = 0x24; setBit(DDS_CTRL_OUT,DDS_ALE); clrBit(DDS_CTRL_OUT,DDS_ALE);
   DDS_DATA_OUT = 0xFF; clrBit(DDS_CTRL_OUT,DDS_NWR); setBit(DDS_CTRL_OUT,DDS_NWR);

   DDS_commit();


   // scan the frequency range

   while(1)
    {

      if(scn<SCAN_LIM_LO) dir=POS_STEP;
      if(scn>SCAN_LIM_HI) dir=NEG_STEP;

      scn += dir;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -