-1

我最初用 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”功能改变信号的频率,它就不起作用了。

请帮帮我,我不知道我在做什么错误。

4

1 回答 1

0

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

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

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

您可以通过简单地添加第二次调用 SetWGFreq() 来快速测试。如果解决了,那么您就知道解决方案了。

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

你现在可能已经解决了这个问题,有什么问题?

于 2012-12-31T10:56:15.427 回答