Скетч для Arduino Nano+Adafruit SI5351+LCD1602+модуль энкодера с кнопкой и подтягивающими резисторами:
/*
This entire program is taken from Jason Mildrum, NT7S and Przemek
Sadowski, SQ9NJE.
http://nt7s.com/
http://sq9nje.pl/
http://ak2b.blogspot.com/
ИЗМЕНЕН ДЛЯ ПРИЕМНИКА С ПЧ1=45МГц ПЧ2=455кГц
ЕСЛИ
КОМПИЛЯТОР БУДЕТ РУГАТЬСЯ, НАДО ПРОВЕРИТЬ ВЕРСИЮ БИБЛИОТЕКИ <si5351.h>! В ДАННОМ СКЕТЧЕ ИСПОЛЬЗУЕТСЯ
БИБЛИОТЕКА Si5351-2.1.4
SCL – A5, SDA – A4
*/
#include <Rotary.h>
#include <si5351.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define F_MIN 100000L // FMIN
#define F_MAX 30000000L // FMAX
#define OLED_RESET 4 // не используется
#define ENCODER_A 3 // Encoder pin A, digital3
#define ENCODER_B 2 // Encoder pin B,
digital2
#define ENCODER_BTN 5 // digital5
#define
LCD_ADDR 0x27 // Проверить адрес скетчем "I2C
Scanner"
#define LCD_SYMBOLS 16 // кол-во символов
#define LCD_STRINGS 2 // кол-во строк
LiquidCrystal_I2C lcd(LCD_ADDR,
LCD_SYMBOLS, LCD_STRINGS); // Сreating LCD instance
Si5351 si5351;
Rotary r = Rotary(ENCODER_A, ENCODER_B);
int_fast32_t vfo = 4625000; // начальная
частота настройки
int_fast32_t IF1 = 45000000; // 45МГц
int_fast32_t IF2 = 44545000; //44.545МГц
volatile uint32_t radix = 100; //start
step size
boolean changed_f = 0;
int_fast32_t cal_factor = 720;
// Calibration factor Si5351
/**************************************/
/* Interrupt service routine for
*/
/* encoder frequency change
*/
/**************************************/
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result == DIR_CW)
set_frequency(1);
else if (result == DIR_CCW)
set_frequency(-1);
}
/**************************************/
/* Change the frequency
*/
/* dir = 1 Increment */
/* dir = -1 Decrement */
/**************************************/
void set_frequency(short dir)
{
if(dir == 1)
vfo += radix;
if(dir == -1)
vfo -= radix;
if(vfo > F_MAX)
vfo = F_MAX;
if(vfo < F_MIN)
vfo = F_MIN;
changed_f = 1;
}
/**************************************/
/* Read the button with debouncing
*/
/**************************************/
boolean get_button()
{
if(!digitalRead(ENCODER_BTN))
{
delay(20);
if(!digitalRead(ENCODER_BTN))
{
while(!digitalRead(ENCODER_BTN));
return 1;
}
}
return 0;
}
/**************************************/
/* Displays the frequency
*/
/**************************************/
void display_frequency()
{
uint16_t f, g;
lcd.setCursor(4, 0);
f = vfo / 1000000; //variable
is now vfo instead of 'frequency'
if(f<10)
lcd.print(' ');
lcd.print(f);
lcd.print('.');
f = (vfo % 1000000)/1000;
if(f<100)
lcd.print('0');
if(f<10)
lcd.print('0');
lcd.print(f);
lcd.print('.');
f = vfo % 1000;
if(f<100)
lcd.print('0');
if(f<10)
lcd.print('0');
lcd.print(f);
lcd.print("Hz");
lcd.setCursor(0, 1);
Serial.println(vfo);
lcd.setCursor(0, 1);
lcd.print("IF+45MHz");
}
/**************************************/
/* Displays the frequency change step */
/**************************************/
void display_radix()
{
lcd.setCursor(10, 1);
switch(radix)
{
case 10:
lcd.print(" 10");
break;
case 100:
lcd.print(" 100");
break;
case 1000:
lcd.print(" 1k");
break;
case 10000:
lcd.print(" 10k");
break;
case 100000:
lcd.print("100k");
break;
}
lcd.print("Hz");
}
void setup()
{
Serial.begin(19200);
lcd.backlight();
lcd.init();
lcd.begin(LCD_SYMBOLS, LCD_STRINGS);
lcd.clear();
lcd.begin(16, 2);
lcd.clear();
pinMode(BFO_On_Off,INPUT);
digitalWrite(BFO_On_Off,HIGH);
Wire.begin();
si5351.init(SI5351_CRYSTAL_LOAD_8PF,0,0);
si5351.set_correction(cal_factor * SI5351_FREQ_MULT,
SI5351_PLL_INPUT_XO);
si5351.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
si5351.set_freq((vfo + IF1) * SI5351_FREQ_MULT, SI5351_CLK0);
si5351.set_freq(IF2 * SI5351_FREQ_MULT, SI5351_CLK2);
pinMode(ENCODER_BTN, INPUT_PULLUP);
PCICR |= (1 << PCIE2); // Enable pin change interrupt for the
encoder
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
display_frequency(); // Update
the display
display_radix();
}
void loop()
{
// Update the display if the frequency has been changed
if(changed_f)
{
display_frequency();
si5351.set_freq((vfo+IF1)*SI5351_FREQ_MULT, SI5351_CLK0);
changed_f = 0;
}
// Button press changes the frequency change step
if(get_button())
{
switch(radix)
{
case 10:
radix = 100;
break;
case 100:
radix = 1000;
break;
case 1000:
radix = 10000;
break;
case 10000:
radix = 100000;
break;
case 100000:
radix = 10;
break;
}
display_radix();
}
}
Комментариев нет:
Отправить комментарий