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);
}





       

18 件のコメント:

  1. コメント有難うございます。

    返信削除
  2. はじめまして、JA0UFZ/戸井と申します。
    soltecのボードにOMのスケッチを利用させていただきました。無事に動かすことができました。ありがとうございました。

    返信削除
    返信
    1. JA0UFZ戸井OM
      Blogを見て作って頂き、有難うございました。

      削除
  3. Hi
    When I compile this file with Arduino software I got this massage:
    (i2cinit was not declared in this scope)
    why? can you help me about this problem?
    if you have final hex file and send for me very better.thanks.

    返信削除
  4. Hi Mr Mizuno.My call is CN8LI & my name is Said.I assembled the SI5351 TFT ver3.1 for my homemade TRX but the rotary don't works.The SI5351 & the rotay are connected. As i am a fan of the 6m magic band how can i have this in this project & how to add the 100khz step Pse ?? 73s de CN8LI/Said

    返信削除
  5. Hi CN8LI.
    My blog is aimed at those who have the ability to customize their own. For that reason, they are all open to the public. Please note that we will not be able to respond in the future. This time, I uploaded the customized one here. It will be unconditionally deleted on April 16, so please download CN8LI.zip.
    https://sites.google.com/site/ja2gqp/

    返信削除
  6. Hi Mr Mizuno
    Very thanks for your help and sorry for the disturb.
    73s de CN8LI / Said

    返信削除
  7. Hi CN8LI.
    You are welcome.
    I have confirmed the operation, so I think there is no problem.
    73.

    返信削除
  8. こんにちは
    私はこの計画を立てました
    しかし問題がある
    ロータリーは正常ですが、回転部分は機能しません
    ロータリーは頻度を変えない
    どうしたの ?

    返信削除
  9. こんにちは
    案内してください
    回転の問題は何ですか?
    ロータリーは機能せず、周波数を変更しません
    どうしたの?

    返信削除
  10. Hi EP3AS.
    Is the TX signal of A3 (DIO17) open (5V) during reception?
    Receive when this TX pin is open. Send when closed.
    Encoder operation will not be accepted during transmission.

    返信削除
  11. Hi sir
    Forgive me for being late
    I tested it
    Send mode is disconnected
    But the frequency switches and rotary switches do not work
    I can not change the frequency and it is not possible to change the steps

    返信削除
  12. Hi EP3AS.
    As you can see in the blog, did you write to the EEPROM?
    If you do not write to EEPROM, it will not operate normally.
    If it still does not work, there is a problem with the encoder circuit.

    返信削除
  13. Hello
    Thank you very much for answering
    I checked all the hardware components and they are safe
    I wrote with EEPROM
    I do not know what the problem is
    Please give me the complete file of this DDS
    Maybe my colleague entered the wrong file
    thank you
    73

    返信削除
  14. I forgot to tell you
    I built this circuit with ad9850
    Please give me the full program and file of this
    I could hardly find your blog
    Thank you for your answer
    73

    返信削除
  15. Dear EP3AS.

    Ver3.1 using AD9850 that I made does not exist.
    Ver3.1_si5351a is only si5351a. However, rotary encoders are a common problem and will be explained.

    Since Rotarl.h has been upgraded, I found that it does not work properly. I will explain how to use the timestamp of Rotaly.h and Rotaly.cpp 2019/01/03 (latest version at the moment).

    Add the following line to the sketch setup.
    r.begin();


    An example

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

    void setup() {
    i2cInit(); // I2c initialaz 2016/10/23 JA2GQP
    r.begin(); // 20/20/7/16

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

    返信削除
  16. Hi JA2GQP
    I have been following your blog with great interest.
    In this connection, I have fallen in love with your si5351a_TFT_Ver3.1.
    I have made some changes to it so that it matches my needs.
    In si5351.h I have added CLK1 so I can run with a BFO.
    In your vfo_v3_eep.ino, I have in one version extended the number of bands from 7 to 10, so that I could make a 10 band transceiver, 160 to 10m.
    In another version of vfo_v3_eep.ino I only have 2 bands left as this is to be used for a 1 band transceiver either 6m or 4m.
    The si5351a_TFT_Ver3.1.ino itself I have changed several parameters, partly I have added BFO on CLK1, just as I have removed your
    Carrier switch to make room for a 10 band switch instead, and pin 12 is changed from mode switch to PTT out, where I via a BC547 can
    draw an external relay RX/TX.
    Finally, I have changed the screen layout a bit, so that I can only see the exact mode USB LSB etc.
    I hope this is OK?
    If you like, I can send you the modified files.

    Kind regards OZ6YK John

    返信削除
  17. Hello John.
    Your plan is wonderful.
    I'm late in replying because I was setting up the development environment.
    If you agree, I would like to upload your project to my blog.
    Sketches, schematics, documentation if any.
    Send it to me as a zip file via gmail.
    en2gqp@gmail.com

    返信削除