Постоянные читатели

среда, 28 июля 2021 г.

 Скетч для 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();

    }  

  }


Комментариев нет:

Отправить комментарий