AD9833 — генератор сигналов (Arduino)(2)

Ранее в http://rcl-radio.ru/?p=78387 был показан пример создания генератора сигнала синусоидальной, треугольной и прямоугольной формы на базе модуля AD9833.

AD9833 — генератор сигналов с низким энергопотреблением. Позволяет генерировать сигналы с частотой до 12.5 МГц синусоидальной, треугольной и прямоугольной формы. Управление осуществляется с использованием трехпроводного интерфейса SPI.

Основные характеристики микросхемы:

  • Цифровое программирование частоты и фазы.
  • Потребляемая мощность 12.65 мВт при напряжении 3 В.
  • Диапазон выходных частот от 0 МГц до 12.5 МГц.
  • Разрешение 28 бит (0.1 Гц при частоте опорного сигнала 25 МГц).
  • Синусоидальные, треугольные и прямоугольные выходные колебания.
  • Напряжение питания от 2.3 В до 5.5 В.
  • Трехпроводной интерфейс SPI.
  • Расширенный температурный диапазон: от –40°C до +105°C.
  • Опция пониженного энергопотребления.

На этой странице показан аналогичный пример создания генератора с использованием платформы Arduino, но в место энкодера для задания необходимой частоты будет использована гибкая матричная клавиатура 4 на 3, что значительно упрощает ввод необходимой частоты.

Дополнительно помимо гибкой матричной клавиатуры будет использована одна кнопка, которая позволяет изменять форму сигнала.

Вся информация будет как и предыдущем примере выводится на дисплей LCD1602 + I2C (I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.)

Частота генератора устанавливается при помощи клавиатуры, Вы просто набираете необходимую частоту и нажимаете кнопку «*», для удаления текущей частоты для ввода нового значения частоты нажимается кнопка «#».

#include <SPI.h>
#include <EEPROM.h> 
#include <iarduino_KB.h>  // https://github.com/tremaru/iarduino_KB.git
#include <LiquidCrystal_I2C.h> //Библиотека -  http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
  LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
  iarduino_KB KB(6,5,4,3,2,1,0); /// 6543 210
 
long b,h_bit,l_bit,f_lcd,f_ust;
const long f25 = 25000985;// частота кварца, если нет эталонного частотомера установите частоту 25000000 Гц
bool w=1,on;
long times,code[8],ccc;
int i,i1,form;
 
 
void setup() {
  Wire.begin();lcd.init();lcd.backlight(); KB.begin(KB3);
  pinMode(8,INPUT_PULLUP);   // форма сигнала
  lcd.setCursor(0,0);lcd.print("     AD9833   ");delay(3000);lcd.clear();// ЗАСТАВКА
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении
  ad();
}
 
 
void loop() {
/////////////////// клавиатура + кнопка //////////////////////////////////////////////////////////////////////////////////////// 
  if(digitalRead(8)==LOW){form++;w=1;if(form>2){form=0;};delay(300);} 
  if(KB.check(KEY_DOWN )){
 
     if(KB.getNum==15){i=0;ccc=0;w=1;on=0;for(i1=0;i1<8;i1++){code[i]=0;}} // # стереть число
     if(KB.getNum==14&&on==0&&w==0){w=1;on=1;delay(200);} // * вкл.ген
     if(KB.getNum==14&&on==1&&w==0){w=1;on=0;delay(200);} // * откл.ген
     if(KB.getNum<10&&i<8){
      code[i] = KB.getNum; 
   switch(i){
     case 0: ccc = code[0];break;
     case 1: ccc = code[0]*10 + code[1];break;
     case 2: ccc = code[0]*100 + code[1]*10 + code[2];break;
     case 3: ccc = code[0]*1000 + code[1]*100 + code[2]*10 + code[3];break;
     case 4: ccc = code[0]*10000 + code[1]*1000 + code[2]*100 + code[3]*10 + code[4];break;
     case 5: ccc = code[0]*100000 + code[1]*10000 + code[2]*1000 + code[3]*100 + code[4]*10 + code[5];break;
     case 6: ccc = code[0]*1000000 + code[1]*100000 + code[2]*10000 + code[3]*1000 + code[4]*100 + code[5]*10 + code[6];break;
     case 7: ccc = code[0]*10000000 + code[1]*1000000 + code[2]*100000 + code[3]*10000 + code[4]*1000 + code[5]*100 + code[6]*10 + code[7];break;
    }i++; if(i>7){i=8;}delay(200);}
    }
 
///////////////// вывод на lcd ////////////////////////////////////////////////////////////
   lcd.setCursor(0,0);lcd.print("F ");lcd.print(ccc/10000000);lcd.print(ccc/1000000%10);lcd.print(".");lcd.print(ccc/100000%10);lcd.print(ccc/10000%10);
   lcd.print(ccc/1000%10);lcd.print(".");lcd.print(ccc/100%10);lcd.print(ccc/10%10);lcd.print(ccc%10);lcd.print(" Hz ");
   if(on==1){lcd.setCursor(0,1);lcd.print("OUT_ON ");i=100;}else{lcd.setCursor(0,1);lcd.print("OUT_OFF");}
 
  if(w==1){ad(); 
  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(){
  if(on==1){b = ccc*pow(2,28)/f25;}else{b=0;}
  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
  }

Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=1857#p1857

Comments

Добавить комментарий

Войти с помощью: