AD9833 — генератор сигналов с низким энергопотреблением. Позволяет генерировать сигналы с частотой до 12.5 МГц синусоидальной, треугольной и прямоугольной формы. Управление осуществляется с использованием трехпроводного интерфейса SPI.
Основные характеристики микросхемы:
- Цифровое программирование частоты и фазы.
- Потребляемая мощность 12.65 мВт при напряжении 3 В.
- Диапазон выходных частот от 0 МГц до 12.5 МГц.
- Разрешение 28 бит (0.1 Гц при частоте опорного сигнала 25 МГц).
- Синусоидальные, треугольные и прямоугольные выходные колебания.
- Напряжение питания от 2.3 В до 5.5 В.
- Трехпроводной интерфейс SPI.
- Расширенный температурный диапазон: от –40°C до +105°C.
- Опция пониженного энергопотребления.
Используя платформу Arduino можно организовать управление модулем генератора на AD9833. При генерации синусоидальных и треугольных импульсов амплитуда изменяется в диапазоне 38мВ…0,65В. При генерации импульсов прямоугольной формы на выходе присутствует сигнал уровня TTL.
Управление генератором состоит из трех кнопок и энкодера, вся информация будет выводится на дисплей LCD1602 + I2C (I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.)
Частота генератора устанавливается при помощи энкодера, при нажатии на кнопку энкодера происходит перебор разрядов (0.1,1,10,100,1000,10000,100000,1000000,10000000), в каждом разряде частоты можно установить значение от 0 до 9.
Первая кнопка (ON/OFF) позволяет включать и отключать режим генерации, вторая кнопка изменяет форму сигнала, третья стирает частоту которая была установлена при помощи энкодера.
При установке частоты генератор переходит в режим отключения генерации.
#include <SPI.h> #include <EEPROM.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> //Библиотека - http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1 #include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip #include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей Encoder myEnc(9, 8);//CLK, DT float f=9.4; long b,h_bit,l_bit,f_lcd,f_ust; const long f25 = 25000985;// частота кварца, если нет эталонного частотомера установите частоту 25000000 Гц int a[9],i,form; bool w=1,on; long oldPosition = -999,newPosition,times; void setup() { Wire.begin();Serial.begin(9600); lcd.init();lcd.backlight(); MsTimer2::set(1, to_Timer);MsTimer2::start(); lcd.setCursor(0,0);lcd.print(" AD9833 ");delay(3000);lcd.clear();// ЗАСТАВКА pinMode(7,INPUT); // sw pinMode(2,INPUT_PULLUP);// on/off out pinMode(3,INPUT_PULLUP);// dac,sin,tri pinMode(4,INPUT_PULLUP);// F = 0 if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении a[0] = EEPROM.read(0);a[1] = EEPROM.read(1);a[2] = EEPROM.read(2);a[3] = EEPROM.read(3);a[4] = EEPROM.read(4);a[5] = EEPROM.read(5); a[6] = EEPROM.read(6);a[7] = EEPROM.read(7);a[8] = EEPROM.read(8);form = EEPROM.read(9); ad(); } void loop() { if(digitalRead(4)==LOW){a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=0;a[6]=0;a[7]=0;a[8]=0;w=1;on=0;delay(300);} if(digitalRead(3)==LOW){form++;w=1;on=0;if(form>2){form=0;};delay(300);} if(digitalRead(7)==LOW){i++;w=1;on=0;if(i>8){i=0;};delay(300);} if(digitalRead(2)==LOW&&on==0){on=1;delay(300);w=1;} if(digitalRead(2)==LOW&&on==1){on=0;delay(300);w=1;} if(on==1){lcd.setCursor(0,1);lcd.print("OUT_ON ");i=100;}else{lcd.setCursor(0,1);lcd.print("OUT_OFF");} if (newPosition != oldPosition){oldPosition = newPosition;a[i]=a[i]+newPosition;if(a[i]>9){a[i]=9;}if(a[i]<0){a[i]=0;}myEnc.write(0);newPosition=0;} if(a[0]>1){a[0]=1;}if(a[0]==1&&a[1]>2){a[1]=2;}if(a[0]==1&&a[1]==2&&a[2]>5){a[2]=5;} lcd.setCursor(0,0);lcd.print("F "); if(i==0){if(millis()-times<500){lcd.print(a[0]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[0]);} if(i==1){if(millis()-times<500){lcd.print(a[1]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[1]);} lcd.print("."); if(i==2){if(millis()-times<500){lcd.print(a[2]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[2]);} if(i==3){if(millis()-times<500){lcd.print(a[3]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[3]);} if(i==4){if(millis()-times<500){lcd.print(a[4]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[4]);} lcd.print("."); if(i==5){if(millis()-times<500){lcd.print(a[5]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[5]);} if(i==6){if(millis()-times<500){lcd.print(a[6]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[6]);} if(i==7){if(millis()-times<500){lcd.print(a[7]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[7]);} lcd.print(","); if(i==8){if(millis()-times<500){lcd.print(a[8]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[8]);} f=a[0]*pow(10,7)+a[1]*pow(10,6)+a[2]*pow(10,5)+a[3]*pow(10,4)+a[4]*pow(10,3)+a[5]*pow(10,2)+a[6]*10+a[7]+float(a[8]*0.1); lcd.print("Hz"); if(on==0){f=0;} if(w==1){ad(); EEPROM.update(0, a[0]);EEPROM.update(1, a[1]);EEPROM.update(2, a[2]);EEPROM.update(3, a[3]);EEPROM.update(9, form); EEPROM.update(4, a[4]);EEPROM.update(5, a[5]);EEPROM.update(6, a[6]);EEPROM.update(7, a[7]);EEPROM.update(8, a[8]); lcd.setCursor(11,1); switch(form){ case 0: lcd.print("DAC");WriteAD9833(0x2028);break; case 1: lcd.print("SIN");WriteAD9833(0x2000);break; case 2: lcd.print("TRI");WriteAD9833(0x2002);break; } w=0;} }// loop void WriteAD9833(uint16_t Data){ SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV2, MSBFIRST, SPI_MODE2)); digitalWrite(SS, LOW); delayMicroseconds(1); SPI.transfer16(Data); digitalWrite(SS, HIGH); SPI.endTransaction(); } void ad(){ b = f*pow(2,28)/f25; if(b<16383){l_bit = b + 0x4000 ;h_bit = 0x4000;} else{h_bit = (b>>14) + 0x4000;l_bit = b - (h_bit<<14) + 0x4000;} SPI.begin(); WriteAD9833(0x2100);// 0010 0001 0000 0000 - Reset + DB28 WriteAD9833(l_bit); // 0100 0000 0000 0000 - Freq0 LSB WriteAD9833(h_bit); // 0100 0000 0000 0000 - Freq0 MSB WriteAD9833(0xC000);// 1100 0000 0000 0000 - Phase0 WriteAD9833(0x2000);// 0010 0000 0000 0000 - Exit Reset } void to_Timer(){newPosition = myEnc.read()/4;}
Тестирование
Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=1580#p1580