将波形发生器初始化为特定频率

时间:2012-12-04 11:23:15

标签: c avr

我最初使用125 kHz生成正弦波的问题很小。这看起来很简单,但是我花了很多时间,但我无法弄清楚问题是什么。我正在使用CodeVisionAVR编译器。

我正在使用ATmega32-A微控制器,AD9833可编程波形发生器来产生正弦波。我已经写了这段代码。

#include <MEGA32.h>
#include <main.h>
#include <interface.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <delay.h>
#include <sleep.h>

 // GLOBAL VARIABLES
 unsigned int i;

 //Status
 unsigned char state = 0;
 unsigned char debug = 0;
 unsigned int status = 0x0010;

 //External variables
 unsigned char Command;
 unsigned int  Param;
 extern unsigned char rx_counter0; 


 //Initialize registers
 void init(void){

    #asm("cli");        //Disable global interrupt

    // Input/Output Ports initialization
    // Port B initialization 
    PORTB=0x00;
    DDRB=0xBF;

    // Port C initialization
    PORTC=0x00;
    DDRC=0xC3;

    // Port D initialization
    PORTD=0x00;
    DDRD=0xFC;

    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART0 Mode: Asynchronous
    // USART Baud Rate: 9600
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x67;
    UCSRA=0x00;
    UCSRB=0xD8;
   //UCSRC=0x86;

   // SPI initialisation
   // SPI clock rate fck/16
   // SPI master
   // SPI MSB first
   // SPI CPOL = 1, CPHA = 1
   SPCR=0x5D;
   //PORTB.1 = 1;    //Flash CS high
   PORTB.3 = 1;    //ADC CS high

  //Global enable interrupts
  #asm("sei")
 }

 void runCom(void){

         switch(Command){

                        case(NO_COM):
                            Command = 0;
                            break;

                        case(FREQ):
                            if(Param < 500)
                                SetWGFreq(Param);   
                                Command = 0;
                            break; 

                        case(PHASE):
                            if(Param < 4095)
                                SetWGPhase(Param);
                            Command = 0;
                            break;          
                        default:
                            Command = 0;
                            break;   
                    }
             }

  void main(void){
        status = 0x0010;
        init();                                     //Initialize controller

        SetWGFreq(125);     //Initialize waveformgenerator 125 kH     

        debug = 0;              //Controls output during motor running      
   while (1){

         if(rx_counter0) getCom();                     
         if(Command)     runCom();

          }
       }
   }
   #asm("WDR");        //Reset WD timer 
 }  // EOF "while(1)"
} // EOF "main(void)"


unsigned char spi(unsigned char data) 
{ 
//Start transmision 
SPDR = data; 
//Wait for transmision complete 
while (!(SPSR & 0x80)); 
return SPDR; 
}        



//Sets the waveform generator output to given kHz
void SetWGFreq(unsigned int freq)
{
unsigned long freg;
char fByte0;
char fByte1;
char fByte2;
char fByte3;

freg = (unsigned long)freq*33554.432;   //Number based on a MCLK of 8 MHz
fByte0 = (char)freg;
fByte1 = (char)(freg>>8);
fByte1 = (fByte1 & 0x3F) | 0x40;        //clears bits 15 and 14, then sets for FREQ0
fByte2 = (char)(freg>>14);              //byte1 only has 6 bits, so move over by 8+6
fByte3 = (char)(freg>>22);              //byte1 only has 6 bits, so move over by 8+8+6
fByte3 = (fByte3 & 0x3F) | 0x40;        //clears bits 15 and 14, then sets for FREQ0

SPCR = 0x5A;        //Set SPI to mode 2 and Fosc/64
WG_CS = 0;
while(WG_CS_PIN);   //Wait for chip select pin to go low
spi(0x20);          //Load control register with B28 high
spi(0x00);
spi(fByte1);
spi(fByte0);
spi(fByte3);
spi(fByte2);
WG_CS = 1;
}

我在ATmega32-A和AD9833之间使用SPI通信。我写了一个用于设置信号频率的功能,还有一个用于改变信号相位的功能。

当我输入“FREQ”和频率值时,我已经在开关情况下写入命令,无论您输入的是什么频率,它都会产生信号,与“PHASE”相同,我可以改变信号的相位。所以我能够使用命令成功设置信号的频率和相位。

现在我的问题是,

我希望在运行代码时将波形发生器初始化为125 kHz。即使断电/开电也应该是125KHz。如果用户想要将频率从125改为任何其他,则必须使用“FREQ”功能 为此,我在进入while循环之前在主程序中调用了“SetWGFreq”函数。

  

SetWGFreq(125); //初始化波形发生器125 kH

我不知道为什么它不起作用。

但是当将此功能置于while循环中时它正在工作(最初信号是以125KHz产生的)但是“FREQ”不起作用。这意味着如果我想要使用“FREQ”功能改变信号的频率,它就无法正常工作。

请帮助我,我无法弄清楚我在做什么错误。

1 个答案:

答案 0 :(得分:0)

看着这个,我怀疑问题不在于对SetWGFreq()的调用不起作用;问题是第一次时间不起作用。

函数调用将CS引脚驱动为低电平,然后在命令结束时恢复高电平 WG_CS = 0; ... WG_CS = 1;

但是第一次通过时,WG_CS可能已经为0.第一次调用仅用于清除已存在的不完整SPI状态。

只需添加第二次调用SetWGFreq()即可快速测试。如果那解决了,那么你知道解决方案。

通常,在初始化期间,您需要一些可以清除任何加电垃圾的东西。 CS周期至少应清除任何SPI状态。更好地发送状态命令,或重置以建立已知状态

你现在可能已经修好了,问题是什么?