最初に 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 通信を使用しています。信号の周波数を設定する関数と、信号の位相を変更する関数をもう 1 つ作成しました。
「FREQ」と入力した周波数値を入力すると、スイッチケースにコマンドを書きました。「PHASE」と同じように、入力した周波数で信号を生成します。信号の位相を変更できます。したがって、コマンドを使用して信号の周波数と位相を正常に設定できます。
今私の問題は、
コードを実行するときに、波形発生器を 125 kHz に初期化したいです。電源のオフ/オン時でも 125KHz である必要があります。ユーザーが周波数を 125 から他の値に変更したい場合は、「FREQ」機能を使用する必要があります。
そのために、while ループに入る前に、メイン プログラムで「 SetWGFreq」関数を呼び出しました。
SetWGFreq(125); //波形発生器を初期化 125 kH
なぜ機能しなかったのかわかりません。
ただし、この関数を while ループに配置すると機能しますが (最初は 125KHz で信号が生成されます)、「FREQ」は機能しません。その後、「FREQ」機能を使用して信号の周波数を変更したい場合、機能していませんでした。
これで私を助けてください、私がしている間違いが何であったかわかりませんでした。