merhaba forum
AD9833 sinyal jeneratörünü düzgün çalıştıramadım
https://github.com/Bardia-Afshar/AD9833-STM32
burdaki kütüphaneyi kullandım delayleri fazla fazla verdim
ama sadece sinüs dalga oluşturuyor ve de frekansı sweep yaptıramadım
ayrıca frekans da tam doğru çalışmıyor 20 KHz veriyorum 19830 Hz oluşuyor
acaba bu IC yi düzgün çalıştırabilen var mı ?
kodlarımı ekliyorum
teşekkür
(https://i.imgyukle.com/2021/05/07/OBWPVG.png)
uint8_t disptimer=0;
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//showtime();
HAL_Delay(100);
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
disptimer++;
frqfl=20000.5F+(float)(disptimer*5);phsfl=100.0F;
AD9833_Init();
// AD9833_SetWaveData(/*frqfl,phsfl*/);
}
/* USER CODE END 3 */
}
/*
* ad9833.c
*
*/
#include "AD9833.h"
#include "main.h"
// ------------------- Variables ----------------
uint16_t FRQLW = 0; // MSB of Frequency Tuning Word
uint16_t FRQHW = 0; // LSB of Frequency Tuning Word
uint32_t phaseVal=0; // Phase Tuning Value
uint8_t WKNOWN=0; // Flag Variable
extern float frqfl,phsfl;
// -------------------------------- Functions --------------------------------
void Delay(volatile uint32_t delay){
while(delay--){};
}
// ------------------------------------------------ Software SPI Function
void writeSPI(uint16_t word) {
for (uint8_t i = 0; i < 16 ; i++) {
if(word & 0x8000) HAL_GPIO_WritePin(AD9833PORT,AD9833DATA,GPIO_PIN_SET); //bit=1, Set High
else HAL_GPIO_WritePin(AD9833PORT,AD9833DATA,GPIO_PIN_RESET); //bit=0, Set Low
Delay(5);
HAL_GPIO_WritePin(AD9833PORT,AD9833SCK,GPIO_PIN_RESET); //Data is valid on falling edge
Delay(5);
HAL_GPIO_WritePin(AD9833PORT,AD9833SCK,GPIO_PIN_SET);
word = word<<1; //Shift left by 1 bit
}
HAL_GPIO_WritePin(AD9833PORT,AD9833DATA,GPIO_PIN_RESET); //Idle low
Delay(5);
}
// ------------------------------------------------ Sets Output Wave Type
void AD9833_SetWave(uint16_t Wave){
switch(Wave){
case 0:
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_RESET);
writeSPI(0x2000); // Value for Sinusoidal Wave
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_SET);
WKNOWN=0;
break;
case 1:
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_RESET);
writeSPI(0x2028); // Value for Square Wave
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_SET);
WKNOWN=1;
break;
case 2:
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_RESET);
writeSPI(0x2002); // Value for Triangle Wave
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_SET);
WKNOWN=2;
break;
default:
break;
}
}
// ------------------------------------------------ Sets Wave Frequency & Phase (In Degree) In PHASE0 & FREQ0 Registers
void AD9833_SetWaveData(void/*float Frequency,float Phase*/){
float Frequency,Phase;
Delay(5);
Frequency=frqfl;Phase=phsfl;
// ---------- Tuning Word for Phase ( 0 - 360 Degree )
if(Phase<0)Phase=0; // Changing Phase Value to Positive
if(Phase>360)Phase=360; // Maximum value For Phase (In Degree)
phaseVal = ((int)(Phase*(4096/360)))|0XC000; // 4096/360 = 11.37 change per Degree for Register And using 0xC000 which is Phase 0 Register Address
// ---------- Tuning word for Frequency
long freq=0;
freq=(int)(((Frequency*pow(2,28))/FMCLK)+1); // Tuning Word
FRQHW=(int)((freq & 0xFFFC000) >> 14); // FREQ MSB
FRQLW=(int)(freq & 0x3FFF); // FREQ LSB
FRQLW |= 0x4000;
FRQHW |= 0x4000;
// ------------------------------------------------ Writing DATA
HAL_GPIO_WritePin(AD9833PORT,AD9833DATA,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833PORT,AD9833SCK,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_RESET); //low = selected
Delay(5);
writeSPI(0x2100); // enable 16bit words and set reset bit
writeSPI(FRQLW);
writeSPI(FRQHW);
writeSPI(phaseVal);
writeSPI(0x2000); // clear reset bit
Delay(5);
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_SET); //high = deselected
//AD9833_SetWave(WKNOWN);
Delay(5);
return;
}
// ------------------------------------------------ Initializing AD9833
void AD9833_Init(/*uint16_t WaveType,float FRQ,float Phase*/void){
// float FRQ,Phase;
HAL_GPIO_WritePin(AD9833PORT,AD9833DATA,GPIO_PIN_SET); // Set All SPI pings to High
HAL_GPIO_WritePin(AD9833PORT,AD9833SCK,GPIO_PIN_SET); // Set All SPI pings to High
HAL_GPIO_WritePin(AD9833PORT,AD9833SS,GPIO_PIN_SET); // Set All SPI pings to High
AD9833_SetWave(2);//WaveType); // Type Of Wave
//FRQ= frqfl;Phase=phsfl;
AD9833_SetWaveData();//FRQ,Phase); // Frequency & Phase Set
return;
}
Burada bahsedılmış
https://www.ercankoclar.com/soru-cevap-forum/topic/ad9833-sinyal-jenaratorunu-nasil-programliyabiliriz/?part=2
https://www.kontrolkalemi.com/forum/konu/programlanabilir-sinyal-jenerat%C3%B6r%C3%BC.123799/
Alıntı yapılan: magnetron - 07 Mayıs 2021, 12:44:02ayrıca frekans da tam doğru çalışmıyor 20 KHz veriyorum 19830 Hz oluşuyor
Bu fark %1 in altında bir hataya tekabül ediyor. Muhtemelen 25MHz lik kristalin tam olarak 25.000.000 Hz olarak çalışmamasından kaynaklanıyordur. Kristalin uçlarında kullanılan kapasitelerden birini trimer kondansatörle değiştirip 25MHz akort edersen hata düzelecektir. Yada yazılımla ofset vererek kalibre etme yöntemini seçebilirsin. Diğer kısımlar için fikrim yok.
Merhaba,
Ben arduino da denemiştim. Bahsettiğiniz gibi ufak tefek frekans sapmaları oluyor. Bütün dalga formları düzgün bir şekilde çıkıyordu.
Alıntı yapılan: eeburakdemir - 07 Mayıs 2021, 21:51:58Merhaba,
Ben arduino da denemiştim. Bahsettiğiniz gibi ufak tefek frekans sapmaları oluyor. Bütün dalga formları düzgün bir şekilde çıkıyordu.
hocam yararlandığınız kütüphanenin internet linkini paylaşır mısınız
teşekkür
Alıntı yapılan: yas - 07 Mayıs 2021, 14:20:31Bu fark %1 in altında bir hataya tekabül ediyor. Muhtemelen 25MHz lik kristalin tam olarak 25.000.000 Hz olarak çalışmamasından kaynaklanıyordur. Kristalin uçlarında kullanılan kapasitelerden birini trimer kondansatörle değiştirip 25MHz akort edersen hata düzelecektir. Yada yazılımla ofset vererek kalibre etme yöntemini seçebilirsin. Diğer kısımlar için fikrim yok.
Buradaki frekans hatası kristal kararlılığından çok fazla, hadi diyelim kristalimiz +-100ppm olsun, bu 1 MHz de 100 Hz demektir. 20 KHz de ise 2 Hz civarında olur. DDS in çıkışı master osilatörün 2^N de biri olacak, kontrolü böyle yapmak lazım. Örneğin master frekans 10.220 MHz ise çıkışta 5.110 MHz, 2.555 MHz gibi frekanslar kontrol edilerek DDS e doğru yazıldığı anlaşılabilir.
Bu modeli hiç kullanmadım ama bu kadar frekans sapması normal gelmedi. Başka bir hata olmalı, frekans formülü datasheet te var :
Output frequency= fMCLK/2^28 × FREQREG.
fMCLK DDS e verdiğimiz clock frekans, FREQREG de 28 bit bir register. Bu register a yazılan değerin doğru olduğuna emin olmak lazım, floating işlemlerde bir hata olmuş olabilir. Örneğin bu registere 2^27, 2^26, 2^25, 2^20 gibi basit değerler yazıp çıkış frekansının fMCLK frekansının yarısı, 1/4... olup olmadığını görmek lazım.
olmaz ama bir ihtimal ,program Clok şartını incelemek gerekebilir,zira bu çin modüllerin iki varyantı var 25 ve 27 MHz..
@magnetron aşağıdaki linkdeki gibi bağlantı yapmıştim. Buradaki adımları dene birde. Ayrıca istenilen frekansın yüzde yüz bulunamaması bir tek sende olan bir durum değil. Bende kullanırken forumlardan okuduğum kadarıyla ve osiloskoptaki gödüğüm değerler , okadar kadı kızında da olur dercesineydi.
https://www.instructables.com/Signal-Generator-AD9833/
çalışan arduino kodları
/*
AD9833 Pin Arduino Pin Description
CLK SCK SPI Clock pin
DAT MOSI SPI Master Out Slave In data pin
FNC User defined SPI transfer enable (active LOW)
VCC 5V Recommend a 10 uF capacitor in parallel with a 0.1 uF capacitor
GND GND
*/
#include <AD9833.h>
#define FNC_PIN 4
AD9833 gen(FNC_PIN);
// Signal type - SINE_WAVE, TRIANGLE_WAVE, SQUARE_WAVE, and HALF_SQUARE_WAVE
void setup() {
gen.Begin();
gen.ApplySignal(SINE_WAVE,REG0,100);
gen.EnableOutput(true);
}
void loop() {
}
Alıntı yapılan: berkay_91 - 08 Mayıs 2021, 01:39:22çalışan arduino kodları
hocam kodlar eksik olabilir mi
Alıntı yapılan: ferdem - 07 Mayıs 2021, 22:33:15Buradaki frekans hatası kristal kararlılığından çok fazla, hadi diyelim kristalimiz +-100ppm olsun, bu 1 MHz de 100 Hz demektir. 20 KHz de ise 2 Hz civarında olur. DDS in çıkışı master osilatörün 2^N de biri olacak, kontrolü böyle yapmak lazım. Örneğin master frekans 10.220 MHz ise çıkışta 5.110 MHz, 2.555 MHz gibi frekanslar kontrol edilerek DDS e doğru yazıldığı anlaşılabilir.
Alıntı YapVariation(HZ)=(f*ppm)/10^6
olarak hesaplanmalı bu durumda 100ppm de 25MHz için 2500Hz lik sapma olabilir. Kristallerde merkez frekans toleransı haricinde birde sıcaklığın büyük etken olduğu frekans stabilitesi var onu ve kristal uçlarındaki kapasitelerin etkisini hiç hesaba katmadım bile. Bu tarz çalışmalarda kalibrasyon çok önemli ise akort için mutlaka trimer olmalı diye düşünüyorum. Çünkü dds osc nin 25Mhz olduğunu varsayarak işlemleri gerçekleştiriyor osc değişirse (yani referans değişirse) sonucun hesaplanandan farklı çıkması normal. Bunlara + ilave olarak referans alınarak mukayese yapılan ölçüm aletinin de doğruluğu ayrı bir konu. Gerçeğe göre -50 Hz bizde hata olsa, +80 Hz referans alınan cihazda hata olsa hata 130Hz sapma ölçeriz. Ölçümün referansa göre hatasız olması için sapmamızın referans alınan ölçüm aletindeki ile aynı olması gerekli.
Alıntı yapılan: magnetron - 08 Mayıs 2021, 11:13:04hocam kodlar eksik olabilir mi
kodlar eksik olamaz hocam, uygun kütüphaneyi eklememiş olabilirsiniz kütüphane linki
https://dosya.co/vsz5844i4j4x/AD9833-Library-Arduino-master.rar.html (https://dosya.co/vsz5844i4j4x/AD9833-Library-Arduino-master.rar.html)
bu kodları kullanarak aşağıdaki projeyi yaptım