我最初使用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”功能改变信号的频率,它就无法正常工作。
请帮助我,我无法弄清楚我在做什么错误。
答案 0 :(得分:0)
看着这个,我怀疑问题不在于对SetWGFreq()的调用不起作用;问题是第一次时间不起作用。
函数调用将CS引脚驱动为低电平,然后在命令结束时恢复高电平 WG_CS = 0; ... WG_CS = 1;
但是第一次通过时,WG_CS可能已经为0.第一次调用仅用于清除已存在的不完整SPI状态。
只需添加第二次调用SetWGFreq()即可快速测试。如果那解决了,那么你知道解决方案。
通常,在初始化期间,您需要一些可以清除任何加电垃圾的东西。 CS周期至少应清除任何SPI状态。更好地发送状态命令,或重置以建立已知状态
你现在可能已经修好了,问题是什么?