/*
** Управление синтезатором частоты на AD9850
** Генератор качающейся частоты на два диапазона
*/

#include <LiquidCrystal.h>

#define RESET 8 // pin 8 - вход сброса модуля AD9850 (RST)
#define FQ_UD 9  // pin 9 - вход обновления частоты модуля AD9850 (FQ)
#define W_CLK 10  // pin 10 - стробирующий вход модуля AD9850 (CLK)
#define DATA 11  // pin 11 - вход последовательных данных модуля AD9850 (D7)

#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }

#define band_select 13 // pin 13 - вход переключателя диапазонов
#define bands_number 2 // количество диапазонов

const float band[bands_number*2] = {
                                    3450.0, 3850.0,// диапазон №0 
                                    6900.0, 7300.0 // диапазон №1
                                   };
byte current_band;      // номер текущего диапазона

double Frequency;       // частота генератора
unsigned long time_s;
const float change_step = 10;   // шаг изменения частоты
const float time_step = 500; //интервал изменения в микросекундах

LiquidCrystal lcd(0, 1, 4, 5, 6, 7);
 
void setup()
{  
  pinMode(FQ_UD, OUTPUT);// для выдачи на модуль AD9850
  pinMode(W_CLK, OUTPUT);// для выдачи на модуль AD9850
  pinMode(DATA, OUTPUT);// для выдачи на модуль AD9850
  pinMode(RESET, OUTPUT);// для выдачи на модуль AD9850
  pinMode(band_select, INPUT);// для чтения с переключателя диапазонов
  digitalWrite(band_select, HIGH);// включаем подтягивающий резистор
 
  pulseHigh(RESET);
  pulseHigh(W_CLK);
  pulseHigh(FQ_UD);  // разрешение последовательного режима AD9850
  current_band = digitalRead(band_select);
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Freq ");
  lcd.print(band[current_band*2]/1000);
  lcd.print(" - ");
  lcd.print(band[current_band*2+1]/1000);
  //delay(2000);
  Frequency = band[current_band*2];
  sendFrequency(Frequency*1000);// начальная установка частоты AD9850 в Гц
  time_s = micros();
} 
 
void loop()
{
 if ((micros() - time_s) > time_step)//раз в time_step меняем частоту
   {
   Frequency += change_step;
   if(current_band != digitalRead(band_select))
        {
         current_band = digitalRead(band_select);
         lcd.setCursor(0, 0);
         lcd.print("Freq ");
         lcd.print(band[current_band*2]/1000);
         lcd.print(" - ");
         lcd.print(band[current_band*2+1]/1000); 
        }
   if (Frequency > band[current_band*2+1])
        Frequency = band[current_band*2];
   sendFrequency(Frequency*1000);//установка частоты AD9850 в Гц
   time_s = micros();
   }
}


void tfr_byte(byte data)// последовательная передача байта в модуль AD9850 на вход DATA
{
  for (int i=0; i<8; i++, data>>=1)
  {
    digitalWrite(DATA, data & 0x01);
    pulseHigh(W_CLK);   //строб каждого бита
  }
}
 
 
void sendFrequency(double frequency)// расчет и передача управляющего 32 битного числа "frequency tuning word"
                                    //для задания частоты: frequency = <sys clock> * <frequency tuning word>/2^32
{
  unsigned long freq = frequency * 4294967295/125000000;  // расчет числа
  for (int b=0; b<4; b++, freq>>=8)
   {
    tfr_byte(freq & 0xFF);//передача числа в AD9850
   }
  tfr_byte(0x000);   // завершающий байт, все 0
  pulseHigh(FQ_UD);  // строб новой частоты
}
