/*
Main code by Richard Visokey AD7C -
www.ad7c.com
*/
#include <rotary.h>
#include <EEPROM.h>
#define DDS_SCLK 8
#define DDS_FSYNC 9
#define DDS_SDATA 10
#define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW);}
#define pulseLow(pin) {digitalWrite(pin, LOW); digitalWrite(pin, HIGH);}
Rotary r = Rotary(2, 3);
const int LEDS[] = {11, 12, 13}; // Пины светодиодов-индикаторов шага престройки
const int_fast32_t INC_VALUES[] = {1000, 250, 25}; // Возможные значения шага перестройки
const int INC_CNT = 3; // Число возможных значений
const int_fast32_t DEFAULT_RX = 3600000; // Частота по умолчанию
int_fast32_t increment;
int cur_inc = 0;
int_fast32_t rx;
int button_state = 0;
//---------------------------------------------------------------------------------------------------------
void setup() {
// Инициализируем глобальные переменные
increment = INC_VALUES[0];
// Работа с EEPROM
// Число 123 используется как маркер, что в памяти не рандомный бред
if (EEPROM.read(0) != 123)
{
rx = DEFAULT_RX;
// EEPROM.clear();
EEPROM.write(0, 123);
EEPROM.put(1, rx);
}
else
EEPROM.get(1, rx);
for (int i = 0; i < INC_CNT; ++i)
{
pinMode(LEDS[i], OUTPUT);
digitalWrite(LEDS[i], HIGH);
}
pinMode(A0, INPUT);
digitalWrite(A0, HIGH);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
pinMode(DDS_FSYNC, OUTPUT);
pinMode(DDS_SCLK, OUTPUT);
pinMode(DDS_SDATA, OUTPUT);
digitalWrite(DDS_SCLK, HIGH);
digitalWrite(DDS_FSYNC, HIGH);
tfr_word(0x2100);
send_frequency(rx);
tfr_word(0xC000);
tfr_word(0x2000);
}
//---------------------------------------------------------------------------------------------------------
void loop()
{
button_state = digitalRead(A0);
if (button_state == LOW)
set_increment();
delay(30);
}
//---------------------------------------------------------------------------------------------------------
ISR(PCINT2_vect)
{
unsigned char result = r.process();
if (result) {
if (result == DIR_CW) {
if ((rx + increment) < 3800000) {
rx = rx + increment;
}
}
else {
if ((rx - increment) > 3500000) {
rx = rx - increment;
}
}
}
EEPROM.put(1, rx);
send_frequency(rx);
}
//---------------------------------------------------------------------------------------------------------
void send_frequency(double frequency)
{
int32_t freq;
int16_t MSB;
int16_t LSB;
int16_t phase = 0xC000;
freq = frequency * 268435 / 25000;
MSB = (int)((freq & 0xFFFC000)>>14);
LSB = (int)(freq & 0x3FFF);
//Установка DB15 и DB14
LSB |= 0x4000;
MSB |= 0x4000;
//tfr_word(0x2100);
tfr_word(LSB);
tfr_word(MSB);
tfr_word(phase);
//tfr_word(0x2000);
}
//---------------------------------------------------------------------------------------------------------
void tfr_word(int16_t data)
{
digitalWrite(DDS_FSYNC, LOW);
for (int i = 0; i < 16; i++) {
digitalWrite(DDS_SDATA, (bool)(data & 0x8000));
data <<= 1;
data &= 0xFFFF;
pulseLow(DDS_SCLK);
}
digitalWrite(DDS_FSYNC, HIGH);
}
//---------------------------------------------------------------------------------------------------------
void set_increment()
{
cur_inc = (cur_inc + 1) % INC_CNT;
increment = INC_VALUES[cur_inc];
for (int i = 0; i < cur_inc; ++i)
digitalWrite(LEDS[i], LOW);
for (int i = cur_inc; i < INC_CNT; ++i)
digitalWrite(LEDS[i], HIGH);
delay(250);
}
//---------------------------------------------------------------------------------------------------------