2016年12月9日金曜日

バリキャップ容量測定治具

近頃バリキャップの入手が難しくなってきている。そこで、バリキャップの代替をする為に、測定治具を作った。LC meterにアダプタを付加する方式で、既存のLC meterの改造を行わない事にした。ツマミが付いた部分が、バリキャップ測定治具である。
 
測定治具は、アダプタ方式にしたので、取付/取外しが容易な構造にした。













回路図










バリキャップ代替
手持品の代替として使えそうな物の、特性を測った。





        

2016年11月17日木曜日

Nextion TFT

Nextion 3.2"TFTを入手した。 このLCDは、インテリジェントTFTで、制御機器(PC,マイコンなど)からのシリアル通信で画面コントロールが出来る。最もシンプルの構成は、Nextionのみで動作する。マイコンなどによる画面制御では、メモリ、表示速度など神経を使わなければ出来ないアプリケーションも多々ある。表示部を分散した事で、より自由度の高いプログラムングが出来るであろう。今回、スイッチ画像を作り、タッチパネル操作でLED点灯/消灯る事が出来た。
開発は、 Nextion Editor  とNextionに書き込む為の、USBアダプタ又は、マイクロSDカードが必要。SDカードは必須でなく、USBアダプタでもNextionに書込み出来る。SDカードを使う方が、書込み時間が少なく、お薦めである。
Nextion資料は、ライブラリ  、命令セット。また購入先は、こちら またはAliexpress、e-Bayなど。
 
NextionとUNOを使ったLチカ。画面をタッチすると、UNOのDIO(13)に接続のLEDが点灯/消灯する。 












スケッチ

int char1,char2;
int charflag=0;

void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
}

void loop() {
 if (Serial.available()>1)
{
 if (charflag)
  {
  char2=Serial.read();
  if (char2==0) digitalWrite(13,HIGH);
  else if (char2==0x01) digitalWrite(13,LOW);
  charflag=0;
  }
  else
  {
   char1=Serial.read();
   if(char1==0x65) charflag=1;
  }
 }
}

NextionのHMIファイル、ArduinoスケッチなどダウンロードサイトのNextionフォルダからDownload可能。
    




     

2016年10月27日木曜日

si5351a_TFT_Ver3.1 VFO

JA2NKD松浦OM開発のAD9850_TFT_Ver3.1(Multi-Band対応)をsi5351aに移植した。今回、機能追加は行わなかったので、チップが異なる以外、全く同じである。このVFOは、EEPROM初期値設定を別スケッチで書込みを行っている。同OMのBlogを読んで、設定されたい。EEPROM初期値設定スケッチがバージョンアップされて齟齬が危惧される為、Download siteにvfo_v3_eepスケッチのコピーを保存した。 IDEは、1.6.12(最新版)を使った。





Arduino nano/UNO対応の回路図である。スイッチ入力がアナログポートを使ったレベルによる入力判定を行っている。












ヘッダーファイル

si5351a.hは、スケッチと同じフォルダーに入れる事。Download siteにヘッダーファイル、スケッチ、vfo_v3_eepを保存した。

////////////////////////////////////////////////////////////////////////
// Author: Hans Summers, 2015
// Website: http://www.hanssummers.com
//
// A very very simple Si5351a demonstration
// using the Si5351a module kit http://www.hanssummers.com/synth
// Please also refer to SiLabs AN619 which describes all the registers to use
//----------------------------------------------------------------------
// Addered: JA2GQP,2016/8/18
////////////////////////////////////////////////////////////////////////

#define I2C_START       0x08
#define I2C_START_RPT   0x10
#define I2C_SLA_W_ACK   0x18
#define I2C_SLA_R_ACK   0x40
#define I2C_DATA_ACK    0x28
#define I2C_WRITE       0b11000000
#define I2C_READ        0b11000001

#define SI_CLK0_CONTROL 16            // Register definitions
#define SI_CLK1_CONTROL 17
#define SI_CLK2_CONTROL 18
#define SI_SYNTH_PLL_A  26
#define SI_SYNTH_PLL_B  34
#define SI_SYNTH_MS_0   42
#define SI_SYNTH_MS_1   50
#define SI_SYNTH_MS_2   58
#define SI_PLL_RESET    177

#define SI_R_DIV_1      0b00000000  // R-division ratio definitions
#define SI_R_DIV_2      0b00010000
#define SI_R_DIV_4      0b00100000
#define SI_R_DIV_8      0b00110000
#define SI_R_DIV_16     0b01000000
#define SI_R_DIV_32     0b01010000
#define SI_R_DIV_64     0b01100000
#define SI_R_DIV_128    0b01110000

#define SI_CLK_SRC_PLL_A 0b00000000
#define SI_CLK_SRC_PLL_B 0b00100000

#define XTAL_FREQ       25000000    // Crystal frequency for Hans' board

uint8_t i2cStart(){
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWSR & 0xF8);
}

void i2cStop(){
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

  while ((TWCR & (1<<TWSTO))) ;
}

uint8_t i2cByteSend(uint8_t data){
  TWDR = data;

  TWCR = (1<<TWINT) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWSR & 0xF8);
}

uint8_t i2cByteRead(){
  TWCR = (1<<TWINT) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWDR);
}

uint8_t i2cSendRegister(uint8_t reg, uint8_t data){
  uint8_t stts;

  stts = i2cStart();
  if (stts != I2C_START)
    return 1;

  stts = i2cByteSend(I2C_WRITE);
  if (stts != I2C_SLA_W_ACK)
    return 2;

  stts = i2cByteSend(reg);
  if (stts != I2C_DATA_ACK)
    return 3;

  stts = i2cByteSend(data);
  if (stts != I2C_DATA_ACK)
    return 4;

  i2cStop();

  return 0;
}

uint8_t i2cReadRegister(uint8_t reg, uint8_t *data){
  uint8_t stts;

  stts = i2cStart();
  if (stts != I2C_START)
    return 1;

  stts = i2cByteSend(I2C_WRITE);
  if (stts != I2C_SLA_W_ACK)
    return 2;

  stts = i2cByteSend(reg);
  if (stts != I2C_DATA_ACK)
    return 3;

  stts = i2cStart();
  if (stts != I2C_START_RPT)
    return 4;

  stts = i2cByteSend(I2C_READ);
  if (stts != I2C_SLA_R_ACK)
    return 5;

  *data = i2cByteRead();

  i2cStop();

  return 0;
}

// Init TWI (I2C)
//
void i2cInit(){
  TWBR = 92;
  TWSR = 0;
  TWDR = 0xFF;
//#ifdef ARDUINO_AVR_MEGA2560
//  PRR0 = 0;
//#else
  PRR = 0;
//#endif
}

////////////////////////////////////////////////////////////////////////
// Set up specified PLL with mult, num and denom
// mult is 15..90
// num is 0..1,048,575 (0xFFFFF)
// denom is 0..1,048,575 (0xFFFFF)
///////////////////////////////////////////////////////////////////////

void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom){
  uint32_t P1;                            // PLL config register P1
  uint32_t P2;                            // PLL config register P2
  uint32_t P3;                            // PLL config register P3

  P1 = (uint32_t)(128 * ((float)num / (float)denom));
  P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
  P2 = (uint32_t)(128 * ((float)num / (float)denom));
  P2 = (uint32_t)(128 * num - denom * P2);
  P3 = denom;

  i2cSendRegister(pll + 0, (P3 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 1, (P3 & 0x000000FF));
  i2cSendRegister(pll + 2, (P1 & 0x00030000) >> 16);
  i2cSendRegister(pll + 3, (P1 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 4, (P1 & 0x000000FF));
  i2cSendRegister(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  i2cSendRegister(pll + 6, (P2 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 7, (P2 & 0x000000FF));
}

////////////////////////////////////////////////////////////////////////
// Set up MultiSynth with integer divider and R divider
// R divider is the bit value which is OR'ed onto the appropriate
// register, it is a #define in si5351a.h
////////////////////////////////////////////////////////////////////////

void setupMultisynth(uint8_t synth, uint32_t divider, uint8_t rDiv){
  uint32_t P1;                          // Synth config register P1
  uint32_t P2;                          // Synth config register P2
  uint32_t P3;                          // Synth config register P3

  P1 = 128 * divider - 512;
  P2 = 0;                               // P2 = 0, P3 = 1 forces an integer value for the divider
  P3 = 1;

  i2cSendRegister(synth + 0, (P3 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 1, (P3 & 0x000000FF));
  i2cSendRegister(synth + 2, ((P1 & 0x00030000) >> 16) | rDiv);
  i2cSendRegister(synth + 3, (P1 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 4, (P1 & 0x000000FF));
  i2cSendRegister(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  i2cSendRegister(synth + 6, (P2 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 7, (P2 & 0x000000FF));
}

////////////////////////////////////////////////////////////////////////
// Switches off Si5351a output
// Example: si5351aOutputOff(SI_CLK0_CONTROL);
// will switch off output CLK0
////////////////////////////////////////////////////////////////////////

void si5351aOutputOff(uint8_t clk){
  i2cSendRegister(clk, 0x80);           // Refer to SiLabs AN619 to see
                                        //bit values - 0x80 turns off the output stage
}

////////////////////////////////////////////////////////////////////////
// Set CLK0 output ON and to the specified frequency
// Frequency is in the range 1MHz to 150MHz
// Example: si5351aSetFrequency(10000000);
// will set output CLK0 to 10MHz
//
// This example sets up PLL A
// and MultiSynth 0
// and produces the output on CLK0
////////////////////////////////////////////////////////////////////////

void si5351aSetFrequency(uint32_t frequency){
  uint32_t pllFreq;
  uint32_t xtalFreq = XTAL_FREQ;
  uint32_t l;
  float f;
  uint8_t mult;
  uint32_t num;
  uint32_t denom;
  uint32_t divider;

  divider = 900000000 / frequency;        // Calculate the division ratio. 900,000,000 is the maximum internal
                                          // PLL frequency: 900MHz
  if (divider % 2) divider--;             // Ensure an even integer
                                          //division ratio

  pllFreq = divider * frequency;          // Calculate the pllFrequency:
                                          //the divider * desired output frequency

  mult = pllFreq / xtalFreq;              // Determine the multiplier to
                                          //get to the required pllFrequency
  l = pllFreq % xtalFreq;                 // It has three parts:
  f = l;                                  // mult is an integer that must be in the range 15..90
  f *= 1048575;                           // num and denom are the fractional parts, the numerator and denominator
  f /= xtalFreq;                          // each is 20 bits (range 0..1048575)
  num = f;                                // the actual multiplier is mult + num / denom
  denom = 1048575;                        // For simplicity we set the denominator to the maximum 1048575

                                          // Set up PLL A with the calculated  multiplication ratio
  setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
                                          // Set up MultiSynth divider 0, with the calculated divider.
                                          // The final R division stage can divide by a power of two, from 1..128.
                                          // reprented by constants SI_R_DIV1 to SI_R_DIV128 (see si5351a.h header file)
                                          // If you want to output frequencies below 1MHz, you have to use the
                                          // final R division stage
  setupMultisynth(SI_SYNTH_MS_0, divider, SI_R_DIV_1);
                                          // Reset the PLL. This causes a glitch in the output. For small changes to
                                          // the parameters, you don't need to reset the PLL, and there is no glitch
//  i2cSendRegister(SI_PLL_RESET, 0xA0);  // 2016/10/23 JA2GQP
                                          // Finally switch on the CLK0 output (0x4F)
                                          // and set the MultiSynth0 input to be PLL A
  i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
}

////////////////////////////////////////////////////////////////////////     <<  JA2GQP >>
// Power strength
// Example: SetPower(1);
// The setting range is from 1 to 4
////////////////////////////////////////////////////////////////////////

void SetPower(byte power){
  switch(power){
    case 1:
      i2cSendRegister(SI_CLK0_CONTROL,76);  // CLK0 drive strength = 2mA; power level ~ -10dB
      break;
    case 2:
      i2cSendRegister(SI_CLK0_CONTROL,77);  // CLK0 drive strength = 4mA; power level ~ -6dB
      break;
    case 3:
      i2cSendRegister(SI_CLK0_CONTROL,78);  // CLK0 drive strength = 6mA; power level ~ -3dB
      break;
    case 4:
      i2cSendRegister(SI_CLK0_CONTROL,79);  // CLK0 drive strength = 8mA; power level := 0dB
      break;
    default:
      i2cSendRegister(SI_CLK0_CONTROL,76);  // CLK0 drive strength = 2mA; power level ~ -10dB
      break;
  }
}

スケッチ

//----------------------------------------------------------------------------------
//    Multi Band DDS VFO Ver3.1      
//                         JA2NKD 2016.10.19  
//     Aruduino IDE 1.6.12
//     Arduino nano/UNO
//  
// <Rotary.h>    https://github.com/brianlow/Rotary
// <EF_AD9850.h> http://forum.arduino.cc/index.php?topic=77483.0
// "Ucglib.h"    https://github.com/olikraus/ucglib
// "si5351a.h"   https://sites.google.com/site/ja2gqp/
//---------------------------------------------------------------------------------
// si5351a transplant  2016/10/23  JA2GQP
//       (si5351a.h is original hedder file.)
//---------------------------------------------------------------------------------

//---------- Library include ----------

#include "si5351a.h"                      // 2016/10/23 JA2GQP
#include <SPI.h>
#include <EEPROM.h>
#include <Rotary.h>
//#include <EF_AD9850.h>                  // 2016/10/23 JA2GQP
#include "Ucglib.h"

/*
 * Hardware SPI Pins:
 * Arduino nano sclk=13, data=11
*/

// I/O setting

  const byte __CS=10;
  const byte __DC=9;
  const byte __RST=8;

  const byte modeout1=7;                    // 2016/10/24 JA2GQP
  const byte modeout2=12;                   //
  const byte bandout1=4;                    //
  const byte bandout2=5;                    //
  const byte bandout3=6;                    //
  const byte txsw=A3;                       //
  const byte meterin=A0;                    //
  const byte analogsw=A1;                   //

//  EF_AD9850 AD9850(ddsclock,ddsfqup,ddsreset,ddsdata);  // 2016/10/23 JA2GQP
  Rotary r=Rotary(2,3);
  Ucglib_ILI9341_18x240x320_HWSPI ucg(__DC, __CS, __RST);

//---------- Variable setting ----------

  long romf[4];
  long freq =7100000;
  long freqmax=7200000;
  long freqmin=7000000;
  long freqold=0;
  long freqrit=0;

  String freqt=String(freq);

  long ifshift = 0;
  long ifshiftLSB =8998500; // VFO>frequency USB/LSB is turn over
  long ifshiftUSB =9001500;
  long ifshiftCW  =8999200;
  long ifshiftAM  =9000000;
  long txshiftLSB =8998500;
  long txshiftUSB =9001500;
  long txshiftCW  =9000000;
  long txshiftAM  =9000000;
  long ddsfreq = 0;
  long ddsfreqb;           // 2016/10/23 JA2GQP

  char f100m,f10m,fmega,f100k,f10k,f1k,f100,f10,f1;

  int ddsstep=2;
  int rit=0;
  int fstep=100;
  int steprom=1;
  int fmode=3;
  int fmodeold=1;
  int flagrit=0;
  int fritold=0;
  int flagmode=0;
  int meterval1=0;
  int tmeterval=0;
  int romadd=0;
  int analogdata=0;
  int band=0;
  int bandmax=8;

//----------  Initialization  Program  ----------------------

void setup() {
  i2cInit();                             // I2c initialaz  2016/10/23 JA2GQP

  delay(100);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
 //ucg.begin(UCG_FONT_MODE_SOLID);
  ucg.clearScreen();
  ucg.setRotate270();

  pinMode (bandout1,OUTPUT);
  pinMode (bandout2,OUTPUT);
  pinMode (bandout3,OUTPUT);
  pinMode(txsw,INPUT_PULLUP);
  pinMode(modeout1,OUTPUT);
  pinMode(modeout2,OUTPUT);

  PCICR |=(1<<PCIE2);
  PCMSK2 |=(1 << PCINT18) | (1 << PCINT19);
  sei();

//  AD9850.init();                      // 2016/10/23 JA2GQP                    
//  AD9850.reset();                     // 2016/10/23 JA2GQP

  band=EEPROM.read(0x01);
  romadd=0x010+(band*0x10);
  for (int i=0; i<3;i++){
   romf[i]=eepread((romadd+4*i));
  }
  freq = romf[0];
  freqmin = romf[1];
  freqmax = romf[2];
  fmode = EEPROM.read(romadd+12);
  steprom = EEPROM.read(romadd+13);
  if (steprom==1){fstep=10;}
  if (steprom==2){fstep=100;}
  if (steprom==3){fstep=1000;}
  if (steprom==4){fstep=10000;}
  banddataout();
  screen01();
  chlcd();
  if (fmode==0){fmode=3;}
  else{fmode=fmode-1;}
  modeset();
  steplcd();
  freqt=String(freq);
  freqlcd();
}

//----------  Main program  ---------------------------------

void loop() {

  analogdata=analogRead(analogsw);
//  ucg.setPrintPos(12,157);
//  ucg.setColor(255,255,255);
//  ucg.print(analogdata);
 
    if (analogdata<50){                  
      setstep();
    } else if (analogdata<300){          
      modeset();
    } else if (analogdata<600){          
      setrit();
    }else if (analogdata<750){            
      bandcall();
    }else if (analogdata<980){            
      bandwrite();
    }
  if (digitalRead(txsw)==LOW){txset();}
  if (flagrit==1){
    if (freqrit == fritold){
      meter();
    }  
    if (freqrit!=fritold){
      ddswrite();
      ritlcd();
      fritold=freqrit;
    }
  }
  else{
    if (freq == freqold){
        meter();
    }
  ddswrite();
  freqt=String(freq);
  freqlcd();
  freqold=freq;
  }
}

//----------  Function DDS set  --------------- 2016/10/23  JA2GQP      

void Fnc_Dds(long frequency){
  if(ddsfreq != ddsfreqb){
    si5351aSetFrequency(frequency);
    SetPower(1);
    ddsfreqb = ddsfreq;
  }
}

//---------- meter --------------------------

void meter(){
 meterval1=analogRead(meterin);
 meterval1=meterval1/50;
 if (meterval1>15){meterval1=15;}
  int sx1=sx1+(meterval1*17);
  sx1=sx1+41;
  int sx2=0;
  sx2=sx2+(40+((15-meterval1)*17));
  ucg.setFont(ucg_font_fub35_tr);
  ucg.setColor(0,0,0);
  ucg.drawBox(sx1,180,sx2,16);
  ucg.setPrintPos(40,200);
  for(int i=1;i<=meterval1;i++){
    if (i<=9){
      ucg.setColor(0,255,255);
      ucg.print("-");
    }
    else{
      ucg.setColor(255,0,0);
      ucg.print("-");
    }
  }
}

//---------- Encoder Interrupt -----------------------

ISR(PCINT2_vect) {
  if (flagrit==1){
  unsigned char result = r.process();
    if(result) {
      if(result == DIR_CW){
        freqrit=freqrit+fstep;
        if (freqrit>=10000){
          freqrit=10000;
        }
     }
     else{
      freqrit=freqrit-fstep;
      if (freqrit<=-10000){
        freqrit=-10000;
      }
    }
   }
  }
  else{
    unsigned char result = r.process();
      if(result) {
        if(result == DIR_CW){
          freq=freq+fstep;
          if (freq>=freqmax){freq=freqmax;}
        }
        else{
          freq=freq-fstep;
          if (freq<=freqmin){freq=freqmin;}
        }
     }
  }
}

//------------ On Air -----------------------------

void txset(){
  noInterrupts();
    if (fmode==0){ddsfreq=freq+txshiftLSB;}
    if (fmode==1){ddsfreq=freq+txshiftUSB;}
    if (fmode==2){ddsfreq=freq+txshiftCW;}
    if (fmode==3){ddsfreq=freq+txshiftAM;}

//    AD9850.wr_serial(0x00,ddsfreq);       // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                       // DDS out  2016/10/24 JA2GQP

    ucg.setPrintPos(110,140);
    ucg.setFont(ucg_font_fub17_tr);
    ucg.setColor(255,0,0);
    ucg.print("ON AIR");
    while(digitalRead(txsw) == LOW){
      meter();
    }
  ucg.setFont(ucg_font_fub17_tr);
    ucg.setColor(0,0,0);
    ucg.drawBox(100,120,250,30);  //45
    ddswrite();
    interrupts();
  }

//------------- Mode change(LSB-USB-CW-AM) ------------

void modeset(){
  ucg.setFont(ucg_font_fub17_tr);
    ucg.setPrintPos(82,82);
    ucg.setColor(0,0,0);
    ucg.print("USB");
    ucg.setPrintPos(12,82);
    ucg.print("LSB");
    ucg.setPrintPos(82,112);
    ucg.print("A M");
    ucg.setPrintPos(12,112);
    ucg.print("C W");  
  if (fmode==0){
    ifshift=ifshiftUSB;
    ucg.setColor(255,255,0);
    ucg.setPrintPos(82,82);
    ucg.print("USB");
    digitalWrite(modeout1,HIGH);
    digitalWrite(modeout2,LOW);  
  }
  if(fmode==1){
    ifshift=ifshiftCW;
    ucg.setPrintPos(12,112);
    ucg.setColor(255,255,0);
    ucg.print("C W");
    digitalWrite(modeout1,LOW);
    digitalWrite(modeout2,HIGH);
  }
  if (fmode==2){
    ifshift=ifshiftAM;
    ucg.setPrintPos(82,112);
    ucg.setColor(255,255,0);
    ucg.print("A M");
    digitalWrite(modeout1,HIGH);
    digitalWrite(modeout2,HIGH);
    }
  if (fmode==3){
    ifshift=ifshiftLSB;
    ucg.setPrintPos(12,82);
    ucg.setColor(255,255,0);
    ucg.print("LSB");
    digitalWrite(modeout1,LOW);
    digitalWrite(modeout2,LOW);
  }
  fmode=fmode+1;
  if (fmode==4){fmode=0;}
  ddswrite();
  while(analogRead(analogsw) <1000);
}

//------------ Rit SET ------------------------------

void setrit(){
  if(flagrit==0){
    flagrit=1;
    ucg.setFont(ucg_font_fub11_tr);
    ucg.setPrintPos(190,110);
    ucg.setColor(255,0,0);
    ucg.print("RIT");
    ritlcd();
  }
  else {
    flagrit=0;
    ddsfreq=freq+ifshift;

//    AD9850.wr_serial(0x00,ddsfreq);       // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                       // DDS Out  2016/10/23 JA2GQP

    freqt=String(freq);
    ucg.setFont(ucg_font_fub11_tr);
    ucg.setPrintPos(190,110);
    ucg.setColor(255,255,255);
    ucg.print("RIT");
    ucg.setColor(0,0,0);
    ucg.drawRBox(222,92,91,21,3);
    freqrit=0;
  }
  while(analogRead(analogsw) <1000);
}

//----------- Rit screen ----------------------

void ritlcd(){
  noInterrupts();
  ucg.setColor(0,0,0);
  ucg.drawBox(222,92,91,21);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(230,110);
  ucg.print(freqrit);
  interrupts();
}

//-------------- encorder frequency step set -----------

void setstep(){
  noInterrupts();
  if (fstep==10000){
    fstep=10;
  }
  else{
    fstep=fstep * 10;
  }
 steplcd();
 while(analogRead(analogsw) < 1000);
 interrupts();
}

//------------- Step Screen ---------------------------

void steplcd(){
  ucg.setColor(0,0,0);
  ucg.drawRBox(221,61,93,23,3);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(220,80);
  if (fstep==10){ucg.print("    10Hz");}
  if (fstep==100){ucg.print("   100Hz");}
  if (fstep==1000){ucg.print("    1KHz");}
  if (fstep==10000){ucg.print("  10KHz");}
}

//----------- Main frequency screen -------------------

void freqlcd(){
  ucg.setFont(ucg_font_fub35_tn);
  int mojisuu=(freqt.length());
  if(freq<100){
    ucg.setColor(0,0,0);
    ucg.drawBox(217,9,28,36);  
  }
  if(f10 !=(freqt.charAt(mojisuu-2))){
    ucg.setColor(0,0,0);
    ucg.drawBox(245,9,28,36);
    ucg.setPrintPos(245,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-2));
    f10 = (freqt.charAt(mojisuu-2));
  }
/*
  if(freq<10){
    ucg.setColor(0,0,0);
    ucg.drawBox(245,9,28,36);  
     }
  if(f1 !=(freqt.charAt(mojisuu-1))){
    ucg.setColor(0,0,0);
    ucg.drawBox(273,9,28,36);
    ucg.setPrintPos(273,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-1));  
    f1  = (freqt.charAt(mojisuu-1));
  }
*/
  if(freq<1000){
    ucg.setColor(0,0,0);
    ucg.drawBox(202,9,15,36);      
    }
  if(f100 !=(freqt.charAt(mojisuu-3))){
    ucg.setColor(0,0,0);
    ucg.drawBox(217,9,28,36);
    ucg.setPrintPos(217,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-3));
    f100 = (freqt.charAt(mojisuu-3));
  }
  if(freq>=1000){
    ucg.setPrintPos(202,45);
    ucg.setColor(0,255,0);
    ucg.print(".");
  }
  if(freq<10000){
    ucg.setColor(0,0,0);
    ucg.drawBox(146,9,28,36);  
    }
  if(f1k !=(freqt.charAt(mojisuu-4))){
    ucg.setColor(0,0,0);
    ucg.drawBox(174,9,28,36);
    ucg.setPrintPos(174,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-4));    
    f1k  = (freqt.charAt(mojisuu-4));
  }
  if(freq<100000){
    ucg.setColor(0,0,0);
    ucg.drawBox(118,9,28,36);
  }
  if(f10k !=(freqt.charAt(mojisuu-5))){
    ucg.setColor(0,0,0);
    ucg.drawBox(146,9,28,36);
    ucg.setPrintPos(146,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-5));
    f10k = (freqt.charAt(mojisuu-5));
  }
   if(freq<1000000){
    ucg.setColor(0,0,0);
    ucg.drawBox(103,9,15,36);
    }
  if(f100k !=(freqt.charAt(mojisuu-6))){
    ucg.setColor(0,0,0);
    ucg.drawBox(118,9,28,36);
    ucg.setPrintPos(118,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-6));
    f100k = (freqt.charAt(mojisuu-6));
  }
     
   if(freq>=1000000){
    ucg.setPrintPos(103,45);
    ucg.setColor(0,255,0);
    ucg.print(".");
  }
   if(freq<10000000){
     ucg.setColor(0,0,0);
    ucg.drawBox(47,9,28,36);
     }
   if(fmega !=(freqt.charAt(mojisuu-7))){
    ucg.setColor(0,0,0);
    ucg.drawBox(75,9,28,36);
    ucg .setPrintPos(75,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-7));
    fmega  = (freqt.charAt(mojisuu-7));
   }
   if(freq<100000000){
    ucg.setColor(0,0,0);
    ucg.drawBox(19,9,28,36);
       }
   if (f10m !=(freqt.charAt(mojisuu-8))){
    ucg.setColor(0,0,0);
    ucg.drawBox(47,9,28,36);
    ucg .setPrintPos(47,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-8));
    f10m = (freqt.charAt(mojisuu-8));
   }

/*
  ucg.setPrintPos(19,45);
  if(freq>=100000000){
    if(f100m !=(freqt.charAt(0))){
      ucg.setColor(0,0,0);
      ucg.drawBox(19,9,28,36);
      ucg .setPrintPos(19,45);
      ucg.setColor(0,255,0);
      ucg.print(freqt.charAt(0));
      f100m = (freqt.charAt(0));
    }
  }
*/

}
//----------- Basic Screen -------------------------

void screen01(){
  ucg.setColor(255,255,255);
  ucg.drawRFrame(1,1,314,55,5);
  ucg.drawRFrame(2,2,312,53,5);
  ucg.setColor(50,50,50);
  ucg.drawRBox(5,60,60,25,3);
  ucg.drawRBox(75,60,60,25,3);
  ucg.drawRBox(5,90,60,25,3);
  ucg.drawRBox(75,90,60,25,3);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setPrintPos(12,82);
  ucg.setColor(0,0,0);
  ucg.print("LSB");
  ucg.setPrintPos(82,82);
  ucg.print("USB");
  ucg.setPrintPos(12,112);
  ucg.print("C W");
  ucg.setPrintPos(82,112);
  ucg.print("A M");
  ucg.setColor(255,255,255);
  ucg.drawRFrame(220,60,95,25,3);
  ucg.drawRFrame(220,90,95,25,3);
  ucg.setFont(ucg_font_fub11_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(175,80);
  ucg.print("STEP");
  ucg.setPrintPos(190,110);
  ucg.setColor(255,255,255);
  ucg.print("RIT");
  ucg.setColor(100,100,100);
  ucg.setPrintPos(10,210);
  ucg.print(" S:  1-----3-------6-------9---Over--------");
  ucg.setPrintPos(10,177);
  ucg.print(" P:  1-----3-----5-----------10--------------");
  ucg.setPrintPos(10,230);
  ucg.setColor(235,0,200);
  ucg.print(" Home Blew DDS-VFO Ver3.1 JA2NKD");
  ucg.setFont(ucg_font_fub35_tr);
    ucg.setColor(0,255,0);
//    ucg.setPrintPos(19,45);
//    ucg.print("4");
//    ucg.setPrintPos(47,45);
//    ucg.print("3");
//    ucg.setPrintPos(75,45);
//    ucg.print("7");
//    ucg.setPrintPos(103,45);
//    ucg.print(".");
    ucg.setPrintPos(273,45);
    ucg.print("0");  
}

//---------- DDS Frequency write -----------

void ddswrite(){
  if (flagrit==0){
    ddsfreq=freq+ifshift;

//    AD9850.wr_serial(0x00,ddsfreq);         // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                         // DDS out  2016/10/24 JA2GQP
  }
  if(flagrit==1){
    ddsfreq=freq+ifshift+freqrit;
 //   AD9850.wr_serial(0x00,ddsfreq);         // 2016/10/23 JA2GQP
    Fnc_Dds(ddsfreq);                         // DDS out  2016/10/24 JA2GQP
  }
}

//---------- Band data call from eeprom ----------

void bandcall(){
  band=band+1;
  if (band>(bandmax-1)){band=0;}
  romadd=0x010+(band*0x010);
 for (int i=0; i<3;i++){
   romf[i]=eepread((romadd+4*i));
  }
  freq = romf[0];
  freqmin = romf[1];
  freqmax = romf[2];
  fmode = EEPROM.read(romadd+12);
  steprom = EEPROM.read(romadd+13);
  if (fmode >=1 ){
    fmode=fmode-1;
  }else if (fmode==0){
    fmode=3;
  }
  if (steprom==1){fstep=10;}
  if (steprom==2){fstep=100;}
  if (steprom==3){fstep=1000;}
  if (steprom==4){fstep=10000;}
  modeset();
  steplcd();
  freqt=String(freq);
  freqlcd();
  banddataout();
  chlcd();
}

//---------- Band data write to eeprom ----------

void bandwrite(){
  romadd=0x010+(band*0x010);
 // for (int i=0;i<3;i++){
    eepwrite(freq,romadd);
//  }
  EEPROM.write(0x001,band);
  EEPROM.write(romadd+12,fmode);
  if (fstep==10){steprom=1;}
  if (fstep==100){steprom=2;}
  if (fstep==1000){steprom=3;}
  if (fstep==10000){steprom=4;}
  EEPROM.write(romadd+13,steprom);
  ucg.setPrintPos(110,140);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,0,0);
  ucg.print("Complete!!");
  delay (500);
  ucg.setColor(0,0,0);
  ucg.drawBox(100,120,250,30);
  //ucg.drawBox(41,145,270,16);
}

 //---------- EEPROM Write(4byte) subroutine ----------

void eepwrite(unsigned long f0,int epadd){
  for (int i=0; i<=3;i++){
  EEPROM.write(epadd+i,f0%256);
  f0=f0/256;
  }
}

//---------- EEPROM Read(4byte) subroutin ----------

unsigned long eepread(int epadd){
  unsigned long f0=0;
  for (int i=3; i >=0 ;i--){
    f0=f0*256+EEPROM.read(epadd+i);
    }
    return f0;
}

//---------- Band data output I/O ----------

void banddataout(){
  digitalWrite(bandout1,LOW);
  digitalWrite(bandout2,LOW);
  digitalWrite(bandout3,LOW);
  if (band==0){}
  if (band==1){
   digitalWrite( bandout1,HIGH);
  }
   if (band==2){
   digitalWrite(bandout2,HIGH);
  }
  if (band==3){
   digitalWrite(bandout1,HIGH);
   digitalWrite(bandout2,HIGH);
  }
  if (band==4){
   digitalWrite(bandout3,HIGH);
  }
  if (band==5){
   digitalWrite(bandout1,HIGH);
   digitalWrite(bandout3,HIGH);
  }
  if (band==6){
   digitalWrite(bandout2,HIGH);
   digitalWrite(bandout3,HIGH);
  }
  if (band==7){
   digitalWrite(bandout1,HIGH);
   digitalWrite(bandout2,HIGH);
   digitalWrite(bandout3,HIGH);  
  }
}

//----------  Band No.(Chanel No.) write to LCD ----------

void chlcd(){
ucg.setColor(0,0,0);
ucg.drawBox(5,120,80,20);
ucg.setFont(ucg_font_fub11_tr);
ucg.setPrintPos(12,137);
ucg.setColor(255,255,255);
ucg.print("CH: ");
ucg.print(band+1);
}





       

2016年9月18日日曜日

6 pole Crystal filter 

今まで、G3UUR回路で水晶発振子分類のみ行っていたが、パラメータを求めるプログラムを探した所、フィルタのシュミレーションまで出来るDishal203が見つかった。G3UUR methodによる水晶発振子パラメータをDishal203を使って求め、6poleクリスタルフィルタを作った。水晶の選別とDishal203へのパラメータを正しく入力すれば、無調整で計算値に近似した特性が得られる事が判った。
 

switch ON(F1)、switch off(F2)を以降の説明で表す事とする。 この回路で注意すべき点は、33pFを使うが実装前にコンデンサ容量を実測(小数点第一位までの読み取り精度が必要)の事。製作したチェッカーは、実測値35.2pFであった。(470pFは、測定の必要なし)コンデンサの測定は、単体で行う事。Webの記事で基板などに実装時の容量と記した記事も見受けられるが、実装時の容量をCswとして入力すると、帯域巾が目標値より狭くなる傾向がある。 

G3UUR methodによる水晶発振子チェッカー製作例。電源電圧9V(006P)で使っている。


水晶発振子チェッカーに周波数カウンタ(最少分解能1Hz程度)を繋ぎ、switch F1側(ON)とswitch F2側(off)の周波数を1Hz単位まで読み取る。更に、水晶発振子の容量を0.1pF単位まで読み取る。水晶発振子の選別は、F1周波数を許容差30Hz以内(目標帯域巾の1/100位)、1グループに纏める。許容差100Hzで選別などの記事もあるが、無調整では上手く出来ないであろう。また、許容差100Hzを超えるものは、選外とした方が良い。
 

Csw値(33pF単体で測定した値)、水晶発振子の静電容量(0.1pF単位まで必要)、F1(SW CLOSE)周波数、F2(SW OPEN)周波数を入力し、Calculateを選び演算する。(470pFは、そのまま入力する)この演算は、6個の水晶発振子全て行い、Lm(mH),Cm(fF),fs(kHz)を記録する。更に、6個のCp(pF),Lm(mH),Cm(fF),fs(kHz)平均値を求め、記録する。
 

Lm(mH),fs(kHz),Cp(pF)の各々の平均値を入力する。帯域巾B3db(kHz) 2.7、PB ripple(0..3db) 0.1,# of xtals(2..14) 6を各々入力する。各々の値を入力後、Calculateを選び演算する。また、フィルタ特性の数値データは、show Tableを選べば表示出来る。
 

FRMSによる実測スペクトル。計算したフィルタの入出力インピーダンスは、512.2Ωであった。FRMSの入出力インピーダンスが50Ωの為、2kΩのVR(約462Ω)をFRMS入出力に繋ぎ、抵抗マッチングさせた。抵抗による疑似マッチングにより、約10dBの損失がある。



フィルタ回路図。値は全て計算値。コンデンサは、実測し、合成容量で最大誤差0.3pF以内で実装。 

   基板サイズ 48 x 27 
    

2016年8月18日木曜日

si5351a TFT VFO

Arduino UNO/nanoとUglibを組合わせ、TFT表示をさせる場合、メモリ不足でコンパイル出来ない。そこで、多くのメモリ消費させるsi5351ライブラリを使わず、コンパクトなヘッダーファイルを使う事で、メモリ消費を抑えた。si5351aコントロールに必要な部分は、インクルードファイルの形で定義。但し、si5351aコントロール機能は少なく、clok0の1チャンネルのみ。必要なファイルは、si5351a TFTフォルダからダウンロード出来る。Arduino IDE 1.6.9及び、1.6.10で動作確認しました。

Arduno UNO/nano共通の回路図。














Headder File

スケッチと同じディレクトリに、下記内容のファイル”si5351a.h”を保存する。


////////////////////////////////////////////////////////////////////////
// Author: Hans Summers, 2015
// Website: http://www.hanssummers.com
//
// A very very simple Si5351a demonstration
// using the Si5351a module kit http://www.hanssummers.com/synth
// Please also refer to SiLabs AN619 which describes all the registers to use
//----------------------------------------------------------------------
// Addered: JA2GQP,2016/8/18
////////////////////////////////////////////////////////////////////////

#define I2C_START       0x08
#define I2C_START_RPT   0x10
#define I2C_SLA_W_ACK   0x18
#define I2C_SLA_R_ACK   0x40
#define I2C_DATA_ACK    0x28
#define I2C_WRITE       0b11000000
#define I2C_READ        0b11000001

#define SI_CLK0_CONTROL 16            // Register definitions
#define SI_CLK1_CONTROL 17
#define SI_CLK2_CONTROL 18
#define SI_SYNTH_PLL_A  26
#define SI_SYNTH_PLL_B  34
#define SI_SYNTH_MS_0   42
#define SI_SYNTH_MS_1   50
#define SI_SYNTH_MS_2   58
#define SI_PLL_RESET    177

#define SI_R_DIV_1      0b00000000  // R-division ratio definitions
#define SI_R_DIV_2      0b00010000
#define SI_R_DIV_4      0b00100000
#define SI_R_DIV_8      0b00110000
#define SI_R_DIV_16     0b01000000
#define SI_R_DIV_32     0b01010000
#define SI_R_DIV_64     0b01100000
#define SI_R_DIV_128    0b01110000

#define SI_CLK_SRC_PLL_A 0b00000000
#define SI_CLK_SRC_PLL_B 0b00100000

#define XTAL_FREQ       25000000    // Crystal frequency for Hans' board

uint8_t i2cStart(){
  TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWSR & 0xF8);
}

void i2cStop(){
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

  while ((TWCR & (1<<TWSTO))) ;
}

uint8_t i2cByteSend(uint8_t data){
  TWDR = data;

  TWCR = (1<<TWINT) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWSR & 0xF8);
}

uint8_t i2cByteRead(){
  TWCR = (1<<TWINT) | (1<<TWEN);

  while (!(TWCR & (1<<TWINT))) ;

  return (TWDR);
}

uint8_t i2cSendRegister(uint8_t reg, uint8_t data){
  uint8_t stts;

  stts = i2cStart();
  if (stts != I2C_START)
    return 1;

  stts = i2cByteSend(I2C_WRITE);
  if (stts != I2C_SLA_W_ACK)
    return 2;

  stts = i2cByteSend(reg);
  if (stts != I2C_DATA_ACK)
    return 3;

  stts = i2cByteSend(data);
  if (stts != I2C_DATA_ACK)
    return 4;

  i2cStop();

  return 0;
}

uint8_t i2cReadRegister(uint8_t reg, uint8_t *data){
  uint8_t stts;

  stts = i2cStart();
  if (stts != I2C_START)
    return 1;

  stts = i2cByteSend(I2C_WRITE);
  if (stts != I2C_SLA_W_ACK)
    return 2;

  stts = i2cByteSend(reg);
  if (stts != I2C_DATA_ACK)
    return 3;

  stts = i2cStart();
  if (stts != I2C_START_RPT)
    return 4;

  stts = i2cByteSend(I2C_READ);
  if (stts != I2C_SLA_R_ACK)
    return 5;

  *data = i2cByteRead();

  i2cStop();

  return 0;
}

// Init TWI (I2C)
//
void i2cInit(){
  TWBR = 92;
  TWSR = 0;
  TWDR = 0xFF;
  PRR = 0;
}

////////////////////////////////////////////////////////////////////////
// Set up specified PLL with mult, num and denom
// mult is 15..90
// num is 0..1,048,575 (0xFFFFF)
// denom is 0..1,048,575 (0xFFFFF)
///////////////////////////////////////////////////////////////////////

void setupPLL(uint8_t pll, uint8_t mult, uint32_t num, uint32_t denom){
  uint32_t P1;                            // PLL config register P1
  uint32_t P2;                            // PLL config register P2
  uint32_t P3;                            // PLL config register P3

  P1 = (uint32_t)(128 * ((float)num / (float)denom));
  P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
  P2 = (uint32_t)(128 * ((float)num / (float)denom));
  P2 = (uint32_t)(128 * num - denom * P2);
  P3 = denom;

  i2cSendRegister(pll + 0, (P3 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 1, (P3 & 0x000000FF));
  i2cSendRegister(pll + 2, (P1 & 0x00030000) >> 16);
  i2cSendRegister(pll + 3, (P1 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 4, (P1 & 0x000000FF));
  i2cSendRegister(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  i2cSendRegister(pll + 6, (P2 & 0x0000FF00) >> 8);
  i2cSendRegister(pll + 7, (P2 & 0x000000FF));
}

////////////////////////////////////////////////////////////////////////
// Set up MultiSynth with integer divider and R divider
// R divider is the bit value which is OR'ed onto the appropriate
// register, it is a #define in si5351a.h
////////////////////////////////////////////////////////////////////////

void setupMultisynth(uint8_t synth, uint32_t divider, uint8_t rDiv){
  uint32_t P1;                          // Synth config register P1
  uint32_t P2;                          // Synth config register P2
  uint32_t P3;                          // Synth config register P3

  P1 = 128 * divider - 512;
  P2 = 0;                               // P2 = 0, P3 = 1 forces an integer value for the divider
  P3 = 1;

  i2cSendRegister(synth + 0, (P3 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 1, (P3 & 0x000000FF));
  i2cSendRegister(synth + 2, ((P1 & 0x00030000) >> 16) | rDiv);
  i2cSendRegister(synth + 3, (P1 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 4, (P1 & 0x000000FF));
  i2cSendRegister(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
  i2cSendRegister(synth + 6, (P2 & 0x0000FF00) >> 8);
  i2cSendRegister(synth + 7, (P2 & 0x000000FF));
}

////////////////////////////////////////////////////////////////////////
// Switches off Si5351a output
// Example: si5351aOutputOff(SI_CLK0_CONTROL);
// will switch off output CLK0
////////////////////////////////////////////////////////////////////////

void si5351aOutputOff(uint8_t clk){
  i2cSendRegister(clk, 0x80);           // Refer to SiLabs AN619 to see
                                        //bit values - 0x80 turns off the output stage
}

////////////////////////////////////////////////////////////////////////
// Set CLK0 output ON and to the specified frequency
// Frequency is in the range 1MHz to 150MHz
// Example: si5351aSetFrequency(10000000);
// will set output CLK0 to 10MHz
//
// This example sets up PLL A
// and MultiSynth 0
// and produces the output on CLK0
////////////////////////////////////////////////////////////////////////

void si5351aSetFrequency(uint32_t frequency){
  uint32_t pllFreq;
  uint32_t xtalFreq = XTAL_FREQ;
  uint32_t l;
  float f;
  uint8_t mult;
  uint32_t num;
  uint32_t denom;
  uint32_t divider;

  divider = 900000000 / frequency;  // Calculate the division ratio. 900,000,000 is the maximum                        // internal
                                                 // PLL frequency: 900MHz
  if (divider % 2) divider--;             // Ensure an even integer
                                                //division ratio

  pllFreq = divider * frequency;      // Calculate the pllFrequency:
                                                //the divider * desired output frequency

  mult = pllFreq / xtalFreq;            // Determine the multiplier to
                                                //get to the required pllFrequency
  l = pllFreq % xtalFreq;                 // It has three parts:
  f = l;                                        // mult is an integer that must be in the range 15..90
  f *= 1048575;                           // num and denom are the fractional parts, the numerator and denominator
  f /= xtalFreq;                           // each is 20 bits (range 0..1048575)
  num = f;                                  // the actual multiplier is mult + num / denom
  denom = 1048575;                    // For simplicity we set the denominator to the maximum 1048575

                                          // Set up PLL A with the calculated  multiplication ratio
  setupPLL(SI_SYNTH_PLL_A, mult, num, denom);
                                          // Set up MultiSynth divider 0, with the calculated divider.
                                          // The final R division stage can divide by a power of two, from                                               // 1..128.
                                          // reprented by constants SI_R_DIV1 to SI_R_DIV128 (see                                                       // si5351a.h header file)
                                          // If you want to output frequencies below 1MHz, you have to use                                           // the
                                          // final R division stage
  setupMultisynth(SI_SYNTH_MS_0, divider, SI_R_DIV_1);
                                          // Reset the PLL. This causes a glitch in the output. For small                                                 // changes to
                                          // the parameters, you don't need to reset the PLL, and there is                                             // no glitch
  i2cSendRegister(SI_PLL_RESET, 0xA0);
                                          // Finally switch on the CLK0 output (0x4F)
                                          // and set the MultiSynth0 input to be PLL A
  i2cSendRegister(SI_CLK0_CONTROL, 0x4F | SI_CLK_SRC_PLL_A);
}

/////////////////////////////////////////////////////////// <<JA2GQP >>
// Power strength
// Example: SetPower(1);
// The setting range is from 1 to 4
////////////////////////////////////////////////////////////////////////

void SetPower(byte power){
  switch(power){
    case 1:
      i2cSendRegister(SI_CLK0_CONTROL,76);  // CLK0 strength = 2mA; power level ~ -10dB
      break;
    case 2:
      i2cSendRegister(SI_CLK0_CONTROL,77);  // CLK0 strength = 4mA; power level ~ -6dB
      break;
    case 3:
      i2cSendRegister(SI_CLK0_CONTROL,78);  // CLK0 strength = 6mA; power level ~ -3dB
      break;
    case 4:
      i2cSendRegister(SI_CLK0_CONTROL,79);  // CLK0 strength = 8mA; power level := 0dB
      break;
    default:
      i2cSendRegister(SI_CLK0_CONTROL,76);  // CLK0 strength = 2mA; power level ~ -10dB
      break;
  }
}

Sketch

ベースとなるスケッチは、JA2NKD松浦OMの2.2"TFT版AD9850 DDS VFOで、si5351a PLLに移植。オリジナルと異なる点は、Arduino UNO/nano対応とメモリ機能。


//////////////////////////////////////////////////////////////////////////////
//       Copyright©2016.JA2GQP.All rights reserved.
//            si5351a PLL VFO Ver1.0      << JA2NKD sketch is based >>      
//                                                    2016/8/18
//                                                    JA2GQP  
//                      << Aruduino IDE 1.6.X >>
//
//----------------------------------------------------------------------------  
//  Function
//    1.RIT Operation(-10kHZ to 10kHZ)
//    2.STEP(10,100,1k,10k,100k)
//    3.Memory Operation is Push RIT
//    4.Protection Operation At The Time Of Transmission
//    5.Memory 4ch(LSB,USB.CW,AM)
//    6.IF shift
//----------------------------------------------------------------------------  
//  Library
//          <Rotary.h>    https://github.com/brianlow/Rotary
//          "Ucglib.h"    https://github.com/olikraus/ucglib
//
//////////////////////////////////////////////////////////////////////////////

//---------- include Files ---------------

#include "si5351a.h"
#include <SPI.h>
#include <Rotary.h>
#include <EEPROM.h>
#include "Ucglib.h"

//----------   TFT setting  ---------------

/////////////////////
//  Hardware SPI Pins:
//  Arduino nano sclk=13, data=11
/////////////////////

const byte   __CS = 10;
const byte   __DC = 9;
const byte   __RST = 8;

/////////////////////
// Ucglib Assign
/////////////////////

  Ucglib_ILI9341_18x240x320_HWSPI ucg(__DC, __CS, __RST);

//----------   Encorder setting  ---------------

const byte  ENC_A = 2;                     // Encorder A
const byte  ENC_B = 3;                     // Encoeder B

  Rotary r=Rotary(ENC_A,ENC_B);

//----------   I/O setting  -------------------

const byte modeout1 = 7;                  // DIO7
const byte modeout2 = 12;                // DIO12
const byte modesw = 6;                    // DIO6
const byte stepsw = 4;                     // DIO4
const byte ritsw = 5;                       // DIO5
const byte txsw = A3;                      // A3
const byte s_meter = A0;                  // A0
const byte t_meter = A1;                  // A1

//----------  EEPROM Memory Address   ----------

const byte  Frq_Eep = 0x00;               // Frequency(4byte*4)
const byte  Stp_Eep = 0x10;               // STEP(4byte*4)
const byte  Chn_Eep = 0x20;               // Channel(1byte*1)
const byte  Mode_Eep = 0x22;              // Mode(1byte*1)
const byte  Eep_Int = 0x2e;               // Eep Init(1byte*1)

const byte  Max_Chn = 4;                  // Max Channel(4ch)
const byte  Int_End = 73;                 // Initial end code

//----------- Default Value --------------------

const long  DEF_FRQ  =  7050000L;         // Init Frequency
const long  DEF_FMAX =  7200000L;         // Frequency Max
const long  DEF_FMIN =  7000000L;         //           Min
const long  DEF_RLSB = 10698500L;         // RX IF Shift LSB
const long  DEF_RUSB = 10701500L;         //             USB
const long  DEF_RCW  = 10699200L;         //             CW
const long  DEF_RAM  = 10700000L;         //             AM
const long  DEF_TLSB = 10698500L;         // TX IF Shift LSB
const long  DEF_TUSB = 10701500L;         //             USB
const long  DEF_TCW  = 10700000L;         //             CW
const long  DEF_TAM  = 10700000L;         //             AM

const long  DEF_STP = 100L;               // Init STEP
const byte  DEF_Mode = 0;                 // 0=LSB 1=USB 2=CW 3=AM

//----------  Memory Assign  ------------------

long freq    = DEF_FRQ;                   // Frequency data
long freqb;                                     //           old data
long freqmax = DEF_FMAX;              // VFO Upper Limit
long freqmin = DEF_FMIN;                //     Lower Limit
long freqold = 0;
long freqrit = 0;
String freqt=String(freq);
long ifshift = 0;
long ifshiftLSB = DEF_RLSB;               // RX IF Shift LSB
long ifshiftUSB = DEF_RUSB;              //             USB
long ifshiftCW = DEF_RCW;                 //             CW
long ifshiftAM = DEF_RAM;                 //             AM
long txshiftLSB = DEF_TLSB;              // TX IF Shift LSB
long txshiftUSB = DEF_TUSB;             //             USB
long txshiftCW = DEF_TCW;                //             CW
long txshiftAM = DEF_TAM;                //             AM
long ddsfreq = 0;                         // VFO data
long ddsfreqb;                            //     old
char f100m,f10m,fmega,f100k,f10k,f1k,f100,f10,f1;
int ddsstep=2;
int rit=0;
int fstep = DEF_STP;                      // Default Step
int fmode;
int fmodeold=1;
int flagrit=0;
int fritold=0;
int flagmode=0;
int smeterval1=0;
int tmeterval=0;
byte Byt_Chn;                             // Channel SW
byte Byt_Chnb;                            //            Old

//----------  Initialization  Program  ----------------------

void setup() {
  i2cInit();                             // I2c initialaz

  delay(100);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
  ucg.clearScreen();
  ucg.setRotate90();

  pinMode (stepsw,INPUT_PULLUP);
  pinMode (ritsw,INPUT_PULLUP);
  pinMode(txsw,INPUT_PULLUP);
  pinMode(modesw,INPUT_PULLUP);
  pinMode(modeout1,OUTPUT);
  pinMode(modeout2,OUTPUT);

  PCICR |=(1<<PCIE2);
  PCMSK2 |=(1 << PCINT18) | (1 << PCINT19);
  sei();

  screen01();

  if(EEPROM.read(Eep_Int) != Int_End){  // Eep initialaz
    delay(10);
    Fnc_Eep_Int();
  }

  Byt_Chn = EEPROM.read(Chn_Eep);       // Channel
  Byt_Chnb = Byt_Chn;                    //
  Fnc_Eep_Rd();                          // EEPROM Read

  modeset();                             // modeset * 4 times
  modeset();
  modeset();
  modeset();

  steplcd();
  freqt=String(freq);
  freqlcd();
 }

//----------  Main program  ---------------------------------

void loop() {
  if (digitalRead(stepsw)==LOW){setstep();}
  if (digitalRead(modesw)==LOW){modeset();}
  if (digitalRead(ritsw)==LOW){setrit();Fnc_Eep_Wt(Byt_Chn);}
  if (digitalRead(txsw)==LOW){txset();}

    if(Byt_Chnb != Byt_Chn){             // CH SW OLD != NEW?
      Fnc_Eep_Wt(Byt_Chnb);
      Byt_Chnb = Byt_Chn;
      Fnc_Eep_Rd();
      steplcd();
    }
     
  if (flagrit==1){
    if (freqrit == fritold){
      smeter();
    }  

    if (freqrit!=fritold){
      ddswrite();
      ritlcd();
      fritold=freqrit;
    }
  }
  else{
    if (freq == freqold){
        smeter();
    }
//  ddsfreq=freq+ifshift;
    ddswrite();
    freqt=String(freq);
    freqlcd();
    freqold=freq;
  }
}

//---------- Function Eeprom Initialization ------------

void Fnc_Eep_Int(){
  int i;

  for (i=0;i<48;i++)                               // 0 clear(48byte)
    EEPROM.write(i, 0);

  for(i=0;i<Max_Chn;i++){
    Fnc_Eep_Sav4(DEF_FRQ,Frq_Eep+i*4);            // Frequency(7.10MHz)
    Fnc_Eep_Sav4(DEF_STP,Stp_Eep+i*4);            // Step(100Hz)
  }

  EEPROM.write(Chn_Eep,0);
  EEPROM.write(Mode_Eep,DEF_Mode);
  EEPROM.write(Eep_Int,Int_End);                 // Init end set(73)
}

//----------  Function EEPROM Read  ---------          

void Fnc_Eep_Rd(){
  if((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
    freq = Fnc_Eep_Lod4(Frq_Eep+Byt_Chn*4);
  else{
    freq = Fnc_Eep_Lod4(Frq_Eep+0);
    Byt_Chn = 0;
  }

  if((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
    fstep = Fnc_Eep_Lod4(Stp_Eep+Byt_Chn*4);
  else
    fstep = Fnc_Eep_Lod4(Stp_Eep+0);
 
  fmode = EEPROM.read(Mode_Eep);
}

//----------  Function EEPROM Write  -------------------

void Fnc_Eep_Wt(byte chn){
  if((0 <= chn) && (chn < Max_Chn)){
    Fnc_Eep_Sav4(freq,Frq_Eep+chn*4);
    Fnc_Eep_Sav4(fstep,Stp_Eep+chn*4);
  }

  EEPROM.write(Chn_Eep,Byt_Chn);
  EEPROM.write(Mode_Eep,fmode);
}

//----------  Function Save EEPROM 4byte  --------  

void Fnc_Eep_Sav4(long value,int address){
  address += 3;
  for(int i = 0;i < 4;i++){
    byte toSave = value & 0xFF;
    if(EEPROM.read(address) != toSave){
      EEPROM.write(address,toSave);
      }
    value = value >> 8;
    address--;
  }
}

//----------  Function Load EEPROM 4byte  ---------  

long Fnc_Eep_Lod4(int address){
  long value = 0;
  for(int i = 0;i < 4;i++){
    value = value | EEPROM.read(address);
    if( i < 3){
      value = value << 8;
      address++;
      }
  }
  return value;
}

//----------  Function DDS set  ---------------      

void Fnc_Dds(long frequency){
  if(ddsfreq != ddsfreqb){
    si5351aSetFrequency(frequency);
    SetPower(1);
    ddsfreqb = ddsfreq;
  }
}

//---------- S-meter --------------------------

void smeter(){
 smeterval1=analogRead(s_meter);
 smeterval1=smeterval1/50;
 if (smeterval1>15){smeterval1=15;}
  int sx1=sx1+(smeterval1*17);
  sx1=sx1+41;
  int sx2=0;
  sx2=sx2+(40+((15-smeterval1)*17));
  ucg.setFont(ucg_font_fub35_tr);
  ucg.setColor(0,0,0);
  ucg.drawBox(sx1,180,sx2,16);
  ucg.setPrintPos(40,200);
  for(int i=1;i<=smeterval1;i++){
    if (i<=9){
      ucg.setColor(0,255,255);
      ucg.print("-");
    }
    else{
      ucg.setColor(255,0,0);
      ucg.print("-");
    }
  }
}

//---------- Transmission Power meter ------------------

void tmeter(){
  ucg.setColor(0,0,0);
 ucg.drawBox(41,180,270,16);
 tmeterval=analogRead(t_meter);
 tmeterval=tmeterval/50;
 if (tmeterval>15){tmeterval=15;}
  int sx1=sx1+(tmeterval*17);
  sx1=sx1+41;
  int sx2=0;
  sx2=sx2+(40+((15-tmeterval)*17));
  ucg.setFont(ucg_font_fub35_tr);
  ucg.setColor(0,0,0);
  ucg.drawBox(sx1,145,sx2,16);
  ucg.setPrintPos(40,165);
  for(int i=1;i<=tmeterval;i++){
    if (i<=9){
      ucg.setColor(250,80,0);
      ucg.print("-");
    }
    else{
      ucg.setColor(250,0,0);
      ucg.print("-");
    }
  }
}

//---------- Encoder Interrupt -----------------------

ISR(PCINT2_vect) {
  if (flagrit==1){
  unsigned char result = r.process();
    if(result) {
      if(result == DIR_CW){
        freqrit=freqrit+fstep;
        if (freqrit>=10000){
          freqrit=10000;
        }
     }
    else{
        freqrit=freqrit-fstep;
        if (freqrit<=-10000){
          freqrit=-10000;
        }
    }
 //   ddswrite();
    }
  }

  else{
    unsigned char result = r.process();
      if(result) {
        if(result == DIR_CW){
          freq=freq+fstep;
          if (freq>=freqmax){freq=freqmax;}
        }
        else{
          freq=freq-fstep;
          if (freq<=freqmin){freq=freqmin;}
        }
     }
  }

}

//------------ On Air -----------------------------

void txset(){
  noInterrupts();
    if (flagmode==0){ddsfreq=freq+txshiftLSB;}
    if (flagmode==1){ddsfreq=freq+txshiftUSB;}
    if (flagmode==2){ddsfreq=freq+txshiftCW;}
    if (flagmode==3){ddsfreq=freq+txshiftAM;}

    Fnc_Dds(ddsfreq);                            // DDS out
 
    ucg.setPrintPos(140,140);
    ucg.setFont(ucg_font_fub17_tr);
    ucg.setColor(255,0,0);
    ucg.print("ON AIR");
    while(digitalRead(txsw) == LOW){
      tmeter();
    }
    ucg.setColor(0,0,0);
    ucg.drawBox(30,120,250,30);
    ddswrite();
    ucg.drawBox(41,145,270,16);
    interrupts();
  }

//------------- Mode change(LSB-USB-CW-AM) ------------

void modeset(){
  ucg.setFont(ucg_font_fub17_tr);
//  if (fmode==0){                          
  if (fmode==1){                              // 2016/8/3
    ifshift=ifshiftUSB;
    flagmode = 1;                             // 2016/8/3
    ucg.setColor(255,255,0);
    ucg.setPrintPos(82,82);
    ucg.print("USB");
    ucg.setPrintPos(12,82);
    ucg.setColor(0,0,0);
    ucg.print("LSB");  
    digitalWrite(modeout1,HIGH);
    digitalWrite(modeout2,LOW);
  }

//  if(fmode==1){                          
  if(fmode==2){                              // 2016/8/3
    ifshift=ifshiftCW;
    flagmode = 2;                            // 2016/8/3
    ucg.setPrintPos(12,112);
    ucg.setColor(255,255,0);
    ucg.print("C W");
    ucg.setPrintPos(82,82);
    ucg.setColor(0,0,0);
    ucg.print("USB");
    digitalWrite(modeout1,LOW);
    digitalWrite(modeout2,HIGH);
  }

//  if (fmode==2){                          
  if (fmode==3){                              // 2016/8/3
    ifshift=ifshiftAM;
    flagmode = 3;                             // 2016/8/3
    ucg.setPrintPos(82,112);
    ucg.setColor(255,255,0);
    ucg.print("A M");
    ucg.setColor(0,0,0);    
    ucg.setPrintPos(12,112);
    ucg.print("C W");
    digitalWrite(modeout1,HIGH);
    digitalWrite(modeout2,HIGH);
    }

//  if (fmode==3){                          
  if (fmode==0){                              // 2016/8/3
    ifshift=ifshiftLSB;
    flagmode = 0;                             // 2016/8/3
    ucg.setPrintPos(12,82);
    ucg.setColor(255,255,0);
    ucg.print("LSB");
    ucg.setPrintPos(82,112);
    ucg.setColor(0,0,0);
    ucg.print("A M");
    digitalWrite(modeout1,LOW);
    digitalWrite(modeout2,LOW);
  }

  fmode=fmode+1;

  Byt_Chn++;                              
  if(Byt_Chn > 3)            
    Byt_Chn = 0;

  if (fmode==4){fmode=0;}
  ddswrite();
  while(digitalRead(modesw) == LOW);
}

//------------ Rit SET ------------------------------

void setrit(){
  if(flagrit==0){
    flagrit=1;
    ucg.setFont(ucg_font_fub11_tr);
    ucg.setPrintPos(190,110);
    ucg.setColor(255,0,0);
    ucg.print("RIT");
//    freqrit=0;
    ritlcd();
  }
  else {
    flagrit=0;
    ddsfreq=freq+ifshift;
    Fnc_Dds(ddsfreq);                       // DDS Out
    freqt=String(freq);
    ucg.setFont(ucg_font_fub11_tr);
    ucg.setPrintPos(190,110);
    ucg.setColor(255,255,255);
    ucg.print("RIT");
    ucg.setColor(0,0,0);
    ucg.drawRBox(222,92,91,21,3);
    freqrit=0;
  }
  while(digitalRead(ritsw) == LOW);
}

//----------- Rit screen ----------------------

void ritlcd(){
  noInterrupts();
  ucg.setColor(0,0,0);
  ucg.drawBox(222,92,91,21);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(230,110);
  ucg.print(freqrit);
  interrupts();
}

//-------------- encorder frequency step set -----------

void setstep(){
  noInterrupts();
  if (fstep==10000){
    fstep=10;
  }
  else{
    fstep=fstep * 10;
  }

 steplcd();
 while(digitalRead(stepsw) == LOW);
 interrupts();
}

//------------- Step Screen ---------------------------

void steplcd(){
  ucg.setColor(0,0,0);
  ucg.drawRBox(221,61,93,23,3);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(220,80);
  if (fstep==10){ucg.print("    10Hz");}
  if (fstep==100){ucg.print("   100Hz");}
  if (fstep==1000){ucg.print("    1KHz");}
  if (fstep==10000){ucg.print("  10KHz");}
}

//----------- Main frequency screen -------------------

void freqlcd(){
  ucg.setFont(ucg_font_fub35_tn);
  int mojisuu=(freqt.length());
/*
  ucg.setPrintPos(19,45);
  if(freq>=100000000){
    if(f100m !=(freqt.charAt(0))){
      ucg.setColor(0,0,0);
      ucg.drawBox(19,9,28,36);
      ucg .setPrintPos(19,45);
      ucg.setColor(0,255,0);
      ucg.print(freqt.charAt(0));
      f100m = (freqt.charAt(0));
    }
  }

   if(freq<100000000){
    ucg.setColor(0,0,0);
    ucg.drawBox(19,9,28,36);
       }
   if (f10m !=(freqt.charAt(mojisuu-8))){
    ucg.setColor(0,0,0);
    ucg.drawBox(47,9,28,36);
    ucg .setPrintPos(47,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-8));
    f10m = (freqt.charAt(mojisuu-8));
   }

   if(freq<10000000){
     ucg.setColor(0,0,0);
    ucg.drawBox(47,9,28,36);
     }
   if(fmega !=(freqt.charAt(mojisuu-7))){
    ucg.setColor(0,0,0);
    ucg.drawBox(75,9,28,36);
    ucg .setPrintPos(75,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-7));
    fmega  = (freqt.charAt(mojisuu-7));
   }

  if(freq>=1000000){
    ucg.setPrintPos(103,45);
    ucg.setColor(0,255,0);
    ucg.print(".");
  }
*/
  if(freq<1000000){
    ucg.setColor(0,0,0);
    ucg.drawBox(103,9,15,36);
    }
  if(f100k !=(freqt.charAt(mojisuu-6))){
    ucg.setColor(0,0,0);
    ucg.drawBox(118,9,28,36);
    ucg.setPrintPos(118,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-6));
    f100k = (freqt.charAt(mojisuu-6));
  }
 
  if(freq<100000){
    ucg.setColor(0,0,0);
    ucg.drawBox(118,9,28,36);
  }
  if(f10k !=(freqt.charAt(mojisuu-5))){
    ucg.setColor(0,0,0);
    ucg.drawBox(146,9,28,36);
    ucg.setPrintPos(146,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-5));
    f10k = (freqt.charAt(mojisuu-5));
  }
 
  if(freq<10000){
    ucg.setColor(0,0,0);
    ucg.drawBox(146,9,28,36);  
    }
  if(f1k !=(freqt.charAt(mojisuu-4))){
    ucg.setColor(0,0,0);
    ucg.drawBox(174,9,28,36);
    ucg.setPrintPos(174,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-4));    
    f1k  = (freqt.charAt(mojisuu-4));
  }

  if(freq>=1000){
    ucg.setPrintPos(202,45);
    ucg.setColor(0,255,0);
    ucg.print(".");
  }

  if(freq<1000){
    ucg.setColor(0,0,0);
    ucg.drawBox(202,9,15,36);      
    }
  if(f100 !=(freqt.charAt(mojisuu-3))){
    ucg.setColor(0,0,0);
    ucg.drawBox(217,9,28,36);
    ucg.setPrintPos(217,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-3));
    f100 = (freqt.charAt(mojisuu-3));
  }

  if(freq<100){
    ucg.setColor(0,0,0);
    ucg.drawBox(217,9,28,36);  
  }
  if(f10 !=(freqt.charAt(mojisuu-2))){
    ucg.setColor(0,0,0);
    ucg.drawBox(245,9,28,36);
    ucg.setPrintPos(245,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-2));
    f10 = (freqt.charAt(mojisuu-2));
  }
/*
  if(freq<10){
    ucg.setColor(0,0,0);
    ucg.drawBox(245,9,28,36);  
     }
  if(f1 !=(freqt.charAt(mojisuu-1))){
    ucg.setColor(0,0,0);
    ucg.drawBox(273,9,28,36);
    ucg.setPrintPos(273,45);
    ucg.setColor(0,255,0);
    ucg.print(freqt.charAt(mojisuu-1));  
    f1  = (freqt.charAt(mojisuu-1));
  }
*/
}

//----------- Basic Screen -------------------------

void screen01(){
  ucg.setColor(255,255,255);
  ucg.drawRFrame(0,0,320,55,5);
  ucg.drawRFrame(1,1,318,53,5);
  ucg.setColor(50,50,50);
  ucg.drawRBox(5,60,60,25,3);
  ucg.drawRBox(75,60,60,25,3);
  ucg.drawRBox(5,90,60,25,3);
  ucg.drawRBox(75,90,60,25,3);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setPrintPos(12,82);
  ucg.setColor(0,0,0);
  ucg.print("LSB");
  ucg.setPrintPos(82,82);
  ucg.print("USB");
  ucg.setPrintPos(12,112);
  ucg.print("C W");
  ucg.setPrintPos(82,112);
  ucg.print("A M");
  ucg.setColor(255,255,255);
  ucg.drawRFrame(220,60,95,25,3);
  ucg.drawRFrame(220,90,95,25,3);
  ucg.setColor(100,100,100);
  ucg.setPrintPos(15,200);
  ucg.print("S:");
  ucg.setPrintPos(15,165);
  ucg.print("P:");
  ucg.setFont(ucg_font_fub11_tr);
  ucg.setColor(255,255,255);
  ucg.setPrintPos(175,80);
  ucg.print("STEP");
  ucg.setPrintPos(190,110);
  ucg.setColor(255,255,255);
  ucg.print("RIT");
  ucg.setColor(100,100,100);
  ucg.setPrintPos(40,210);
  ucg.print("1-----3-------6-------9---Over--------");
  ucg.setPrintPos(40,175);
  ucg.print("1-----3----5------------10--------------");
  ucg.setPrintPos(10,230);
  ucg.setColor(235,0,200);
  ucg.print  ("si5351a PLL VFO Ver.1.0 JA2GQP");
  ucg.setFont(ucg_font_fub35_tr);
    ucg .setPrintPos(75,45);
    ucg.setColor(0,255,0);
    ucg.print("7");
    ucg.setPrintPos(103,45);
    ucg.print(".");
    ucg.setPrintPos(273,45);
    ucg.print("0");  
}

//--------------- DDS Write -------------------------------

void ddswrite(){
  if (flagrit==0){
    ddsfreq=freq+ifshift;
    Fnc_Dds(ddsfreq);                               // DDS out
  }

  if(flagrit==1){
    ddsfreq=freq+ifshift+freqrit;
    Fnc_Dds(ddsfreq);                              // DDS out
  }

}