2017年9月16日土曜日

stm32 si5351a VFO(With BFO)

 このVFOは、JA2NKD OMのマルチバンドVFO にBFOを付加した物で、stm32F103c8t6+si5351aで構成している。特徴は、BFOが簡単に変更出来る様にした事と、光学エンコーダの採用でアナログ感覚のVFO操作である。BFO変更は、Modeスイッチを長押し(約1秒間スイッチを押す)エンコーダで周波数を調整後、再び、Modeスイッチを長押し(約1秒間)で書換を行う。
光学エンコーダは、中華製400P/R($10位)を使ったため、エンコーダのコントロールSTEPは、1Hz、10Hz、100Hzにした。






回路図である。光学エンコーダの電源は省略してある。stm32への書込みは、シリアルとした。理由は、省メモリとシリアルモニタが使える環境にした。開発環境にST-LINK V2を使った場合、I/O割付に制限がある様なので変更(9/17)した。









スケッチ

JA2NKD OMのオリジナルVFOは、max 8 Bandであるが6 Bandに変更している。VFO周波数は、周波数変化が2秒以上なければ、疑似EEPROMに保存する機能を追加した。si5351a2.hは、オリジナルの物を使っている。ただ、Ucglib.hは私のPC環境で複数のライブラリが参照されるため、参照場所の明確化をした。スケッチと関係ファイルは、download siteのstm32フォルダからダウンロード可能。

///////////////////////////////////////////////////////////////////////////////////
//    stm32 + si5351a VFO(With BFO) Ver1.01
//          (Based on 'JAN2KD 2016.10.19 Multi Band DDS VFO Ver3.1')  
//
//                                                        2017/9/16
//                                                        JA2GQP    
///////////////////////////////////////////////////////////////////////////////////

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

#include "si5351a2.h"                  
#include <SPI.h>
#include <EEPROM.h>
#include <Rotary.h>
#include "src/Ucglib.h"

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

#define ENC_A     PB12                    // Rotary encoder A
#define ENC_B     PB13                    // Rotary encoder B

Rotary r=Rotary(ENC_A,ENC_B);

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

#define   __CS    PB10                    // CS  
#define   __DC    PB0                     // D/C
#define   __RST   PB1                     // RESET

Ucglib_ILI9341_18x240x320_HWSPI ucg(__DC, __CS, __RST);

//----------   CW Tone  -------------------

#define   CW_TONE     700                // 700Hz

//----------   I/O Assign  -------------------

#define   MODE_OUT1    PB15             // 2017/9/17                 
#define   MODE_OUT2    PA8              // 2017/9/17               
#define   BAND_OUT1    PB3
#define   BAND_OUT2    PB4
#define   BAND_OUT3    PB5

#define   SW_BAND      PA0              
#define   SW_MODE      PC14              
#define   SW_STEP      PB14              
#define   SW_RIT       PC15                
#define   SW_TX        PC13              
#define   METER        PA1                

#define   EEP_BAND     0x00               // EEPROM BAND Adress
#define   EEP_INIT     0x0e               //        INIT end Adress

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

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

String    freqt=String(freq);             // Frequency text

long      ifshift = 0;
long      ifshiftb;
long      romb[5];                        // EEPROM bfo copy buffer
long      vfofreq = 0;
long      vfofreqb;              

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

int       rit        = 0;
int       fstep      = 100;
uint16    steprom    = 1;
uint16    fmode      = 3;
uint16    fmodeb     = 3;
int       fmodeold   = 1;
int       flagrit    = 0;
int       fritold    = 0;
int       flagmode   = 0;
int       meterval1  = 0;
int       tmeterval  = 0;
int       romadd     = 0;
int       rombadd    = 0;
int       analogdata = 0;
uint16    band       = 0;                   // 3.5MHz
int       bandmax    = 6;                   // 6band

uint16    Status;
uint16    Data;          

unsigned long eep_freq[4];
int       eep_romadd;
int       eep_fstep;
int       eep_fmode;
unsigned long eep_bfo[6];
int       eep_rombadd;

int_fast32_t timepassed;                    // int to hold the arduino miilis since startup
int       flg_frqwt = 0;                                // Frequency data Wite Flag(EEPROM)
int       flg_bfowt = 0;                                // BFO Wite Flag(EEPROM)
int       flg_bfochg = 0;                               // BFO Wite Flag(EEPROM)


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

void setup() {
  timepassed = millis();

  afio_cfg_debug_ports(AFIO_DEBUG_NONE);    // ST-LINK(PB3,PB4,PA15,PA12,PA11) Can be used
  Wire.begin();                

  pinMode( ENC_A,INPUT_PULLUP);                   // PC13 pull up
  pinMode( ENC_B,INPUT_PULLUP);                   // PC14

  attachInterrupt( ENC_A, Rotaly_enc, CHANGE);    // Encorder A
  attachInterrupt( ENC_B, Rotaly_enc, CHANGE);    //          B

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

  pinMode(SW_BAND,INPUT_PULLUP);
  pinMode(SW_MODE,INPUT_PULLUP);
  pinMode(SW_STEP,INPUT_PULLUP);
  pinMode(SW_RIT,INPUT_PULLUP);
  pinMode(SW_TX,INPUT_PULLUP);
  pinMode(ENC_A,INPUT_PULLUP);                   // pull up encorede A
  pinMode(ENC_B,INPUT_PULLUP);                   //         encorder B

  pinMode (BAND_OUT1,OUTPUT);
  pinMode (BAND_OUT2,OUTPUT);
  pinMode (BAND_OUT3,OUTPUT);
  pinMode(SW_TX,INPUT_PULLUP);
  pinMode(MODE_OUT1,OUTPUT);
  pinMode(MODE_OUT2,OUTPUT);

  Fnc_eepINIT();
  delay(100);
  band2eep();
  delay(100);

  Status = EEPROM.read(EEP_BAND,&band);         // EEPROM read(frequency)
  romadd=0x010+(band*0x10);
  for (int i=0; i<3;i++){
   romf[i]=Fnc_eepRD((romadd+4*i));
  }
  freq = romf[0];
  freqmin = romf[1];
  freqmax = romf[2];
  Status = EEPROM.read(romadd+12,&fmode);
  Status = EEPROM.read(romadd+14,&steprom);

  eep_rombadd=0x090;                             // EEPROM read(BFO)
  for (int i=0; i<4;i++){
    romb[i]=Fnc_eepRD((eep_rombadd+(4*i)));
    eep_bfo[i] = romb[i];  
  }

  if (steprom==1){fstep=1;}                      // STEP set
  if (steprom==2){fstep=10;}
  if (steprom==3){fstep=100;}
  banddataout();
  screen01();
  chlcd();

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

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

void loop() {
  if(digitalRead(SW_STEP) == LOW)               // STEP sw check
    setstep();
  else if(digitalRead(SW_MODE) == LOW)          // MODE sw check
    modesw();
  else if(digitalRead(SW_RIT) == LOW)           // RIT sw check
    setrit();
  else if(digitalRead(SW_BAND) == LOW)          // BAND sw check
    bandcall();

  if (digitalRead(SW_TX)==LOW)                  // TX sw check
    txset();

  if (flagrit==1){
    if (freqrit == fritold){
      meter();
    }  
    if (freqrit!=fritold){
      PLL_write();
      ritlcd();
      fritold=freqrit;
    }
  }
  else{
    if (freq == freqold){
      meter();
    }
    PLL_write();
    freqt=String(freq);
    freqlcd();
    freqold=freq;
  }

  if((flg_frqwt == 1) && (flg_bfochg == 0)){                  // EEPROM auto save 2sec
    if(timepassed+1000 < millis()){
      bandwrite();
      flg_frqwt = 0;
    }
  }
}

//----------  EEPROM Data initialization  ---------------      

void band2eep(){
  Status = EEPROM.read(EEP_INIT,&Data);
  if(Data != 73){                       // Iinitialization check
    Status = EEPROM.write(EEP_BAND,1);
 
    eep_romadd=0x010;                   // BAND:0 ROMadd:0x010
    eep_freq[0]=3500000;
    eep_freq[1]=3500000;
    eep_freq[2]=3800000;
    eep_fmode=0;
    eep_fstep=2;
    band2write();

    eep_romadd=0x020;                   // BAND:1 ROMadd:0x020
    eep_freq[0]=7000000;
    eep_freq[1]=7000000;
    eep_freq[2]=7200000;
    eep_fmode=0;
    eep_fstep=2;
    band2write();

    eep_romadd=0x030;                   // BAND:2 ROMadd:0x030
    eep_freq[0]=10100000;
    eep_freq[1]=10100000;
    eep_freq[2]=10150000;
    eep_fmode=2;
    eep_fstep=1;
    band2write();

    eep_romadd=0x040;                   // BAND:3 ROMadd:0x040
    eep_freq[0]=14000000;
    eep_freq[1]=14000000;
    eep_freq[2]=14350000;
    eep_fmode=1;
    eep_fstep=2;
    band2write();

    eep_romadd=0x050;                   // BAND:4 ROMadd:0x050
    eep_freq[0]=21000000;
    eep_freq[1]=21000000;
    eep_freq[2]=21450000;
    eep_fmode=1;
    eep_fstep=2;
    band2write();

    eep_romadd=0x060;                   // BAND:5 ROMadd:0x060
    eep_freq[0]=28000000;
    eep_freq[1]=28000000;
    eep_freq[2]=29700000;
    eep_fmode=1;
    eep_fstep=2;
    band2write();

    eep_rombadd=0x090;                  // BFO ROMadd:0x090
    eep_bfo[0]=7999600;                 //     LSB
    eep_bfo[1]=8002600;                 //     USB
    eep_bfo[2]=8000400;                 //     CW
    eep_bfo[3]=8001100;                 //     AM

    for (int i=0;i<4;i++){
      Fnc_eepWT(eep_bfo[i],(eep_rombadd+4*i));
    }

    Status = EEPROM.write(EEP_INIT,73); // Initialyzed End code
  }
}

//----------  Function Band Write to EEPROM  ---------------      

void band2write(){
  for (int i=0;i<3;i++){
    Fnc_eepWT(eep_freq[i],(eep_romadd+4*i));
  }
  Status = EEPROM.write(eep_romadd+12,eep_fmode);
  Status = EEPROM.write(eep_romadd+14,eep_fstep);
}

//---------- PLL write ---------------------------

void PLL_write(){
  if(flg_bfochg == 0){
    if (flagrit==0)
      vfofreq=freq+ifshift;
    else
      vfofreq=freq+ifshift+freqrit;

    Vfo_out(vfofreq);                         // DDS out  2016/10/24 JA2GQP
    Bfo_out(ifshift);                         // BFO
  }
  else{
    ifshift = freq;
    Bfo_out(ifshift);                         // BFO
    freq = ifshift;
  }
}

//----------  VFO out  ---------------

void Vfo_out(long frequency){
  if(vfofreq != vfofreqb){
    si5351aSetFrequency(frequency);
    flg_frqwt = 1;                                // EEP Wite Flag
    timepassed = millis();
    vfofreqb = vfofreq;
  }
}

//----------  BFO out  ---------------      

void Bfo_out(long frequency){
  if(ifshift != ifshiftb){
    si5351aSetFrequency2(frequency);
    flg_bfowt = 1;                                // EEP Wite Flag
    ifshiftb = ifshift;
  }
}

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

void meter(){
 meterval1=analogRead(METER);
// meterval1=meterval1/50;                   // old
 meterval1=meterval1/200;                
 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 -----------------------

void Rotaly_enc(){
  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((flg_bfochg == 0) && (freq>=freqmax)){freq=freqmax;}
      }
      else{
        freq=freq-fstep;
        if((flg_bfochg == 0) && (freq<=freqmin)){freq=freqmin;}
      }
    }
  }
}

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

void txset(){
  if(fmode == 2)                              // CW?
    Vfo_out(vfofreq + CW_TONE);               // Vfofreq+700Hz
  else
    Vfo_out(vfofreq);                         // vfo out
 

  ucg.setPrintPos(110,140);
  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(255,0,0);
  ucg.print("ON AIR");
  while(digitalRead(SW_TX) == LOW){
    meter();
  }

  ucg.setFont(ucg_font_fub17_tr);
  ucg.setColor(0,0,0);
  ucg.drawBox(100,120,250,30);  //45
}

//------------- Mode set(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");  

  switch(fmode){
    case 0:                                       // LSB
      ifshift = eep_bfo[0];
      ucg.setPrintPos(12,82);
      ucg.setColor(255,255,0);
      ucg.print("LSB");
      digitalWrite(MODE_OUT1,LOW);
      digitalWrite(MODE_OUT2,LOW);
      break;
    case 1:                                       // USB                                    
      ifshift = eep_bfo[1];
      ucg.setColor(255,255,0);
      ucg.setPrintPos(82,82);
      ucg.print("USB");
      digitalWrite(MODE_OUT1,HIGH);
      digitalWrite(MODE_OUT2,LOW);  
      break;
    case 2:                                       // CW
      ifshift = eep_bfo[2];
      ucg.setPrintPos(12,112);
      ucg.setColor(255,255,0);
      ucg.print("C W");
      digitalWrite(MODE_OUT1,LOW);
      digitalWrite(MODE_OUT2,HIGH);
      break;
    case 3:                                       // AM
      ifshift = eep_bfo[3];
      ucg.setPrintPos(82,112);
      ucg.setColor(255,255,0);
      ucg.print("A M");
      digitalWrite(MODE_OUT1,HIGH);
      digitalWrite(MODE_OUT2,HIGH);
      break;
    default:
      ifshift = eep_bfo[0];
      ucg.setPrintPos(12,82);
      ucg.setColor(255,255,0);
      ucg.print("LSB");
      digitalWrite(MODE_OUT1,LOW);
      digitalWrite(MODE_OUT2,LOW);
      fmode = 0;
      break;
    }
}

//------------- Mode set SW ------------

void modesw(){
int cnt = 0;

  if(flg_bfochg == 0){
    while(digitalRead(SW_MODE) == LOW){
      delay(100);
      cnt++;
      if(10 <= cnt){                              // BFO data change mode(1sec)
        romadd=0x010+(band*0x10);
        romf[0]=Fnc_eepRD(romadd);
        freq = Fnc_eepRD(0x090+(fmode * 4));
        freqt=String(freq);
        freqlcd();
        ucg.setPrintPos(110,140);
        ucg.setFont(ucg_font_fub17_tr);
        ucg.setColor(255,255,0);
        ucg.print("BFO ADJ");
        fmodeb = fmode;
        flg_bfochg = 1;
        break;
      }
    }
  }
  else{
    while(digitalRead(SW_MODE) == LOW){
      delay(100);
      cnt++;
      if(10 <= cnt){                              // BFO data update(1sec)
        ifshift = freq;
        Fnc_eepWT(ifshift,0x090+(fmode * 4));     // data write
        eep_bfo[fmode] = ifshift;
        freq = romf[0];
        freqt=String(freq);
        freqlcd();
        ucg.setFont(ucg_font_fub17_tr);
        ucg.setColor(0,0,0);
        ucg.drawBox(100,120,250,30);  //45
        flg_bfochg = 0;
        fmode--;
        break;
        }
      }
    }
  if(flg_bfochg == 0)
    fmode++;
  modeset();
  PLL_write();
  while(digitalRead(SW_MODE) == 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");
    ritlcd();
  }
  else {
    flagrit=0;
    vfofreq=freq+ifshift;

    Vfo_out(vfofreq);                       // 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(digitalRead(SW_RIT) == LOW);
}

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

void ritlcd(){
  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);
}

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

void setstep(){
  if (fstep==100){
    fstep=1;
  }
  else{
    fstep=fstep * 10;
  }
 steplcd();
 while(digitalRead(SW_STEP) == LOW);
}

//------------- 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==1){ucg.print("     1Hz");}
  if (fstep==10){ucg.print("    10Hz");}
  if (fstep==100){ucg.print("   100Hz");}
}

//----------- 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));
   }
}
//----------- 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( "stm32 VFO(with BFO) Ver1.0 JA2GQP");
  ucg.setFont(ucg_font_fub35_tr);
    ucg.setColor(0,255,0);
    ucg.setPrintPos(273,45);
    ucg.print("0");  
}

//---------- 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]=Fnc_eepRD((romadd+4*i));
  }
  freq = romf[0];
  freqmin = romf[1];
  freqmax = romf[2];
  Status = EEPROM.read(romadd+12,&fmode);
  Status = EEPROM.read(romadd+14,&steprom);

  if (steprom==1){fstep=1;}
  if (steprom==2){fstep=10;}
  if (steprom==3){fstep=100;}

  modeset();
  steplcd();
  freqt=String(freq);
  freqlcd();
  banddataout();
  chlcd();
 while(digitalRead(SW_BAND) == LOW);
}

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

void bandwrite(){
  romadd=0x010+(band*0x010);
    Fnc_eepWT(freq,romadd);
  Status = EEPROM.write(EEP_BAND,band);
  Status = EEPROM.write(romadd+12,fmode);
  if (fstep==1){steprom=1;}
  if (fstep==10){steprom=2;}
  if (fstep==100){steprom=3;}
  Status = EEPROM.write(romadd+14,steprom);
}

//----------  Function EEPROM Initialize  ---------

void Fnc_eepINIT(){
  uint16 dummy;

  EEPROM.PageBase0 = 0x801F000;
  EEPROM.PageBase1 = 0x801F800;
  EEPROM.PageSize  = 0x400;             // 2kB
  dummy = EEPROM.init();
}

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

long Fnc_eepRD(uint16 adr){
  long val = 0;
  uint16 dat,dummy;

  dummy = EEPROM.read(adr,&dat);
  val = dat << 16;
  dummy = EEPROM.read(adr+1,&dat);
  return val | dat;
}

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

void Fnc_eepWT(long dat,uint16 adr){
  uint16 dummy,val;

  val = dat & 0xffff;
  dummy = EEPROM.write(adr+1,val);
  val = dat >> 16;
  val = val & 0xffff;
  dummy = EEPROM.write(adr,val);
}

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

void banddataout(){
  digitalWrite(BAND_OUT1,LOW);
  digitalWrite(BAND_OUT2,LOW);
  digitalWrite(BAND_OUT3,LOW);
  if (band==0){}
  if (band==1){
   digitalWrite( BAND_OUT1,HIGH);
  }
   if (band==2){
   digitalWrite(BAND_OUT2,HIGH);
  }
  if (band==3){
   digitalWrite(BAND_OUT1,HIGH);
   digitalWrite(BAND_OUT2,HIGH);
  }
  if (band==4){
   digitalWrite(BAND_OUT3,HIGH);
  }
  if (band==5){
   digitalWrite(BAND_OUT1,HIGH);
   digitalWrite(BAND_OUT3,HIGH);
  }
  if (band==6){
   digitalWrite(BAND_OUT2,HIGH);
   digitalWrite(BAND_OUT3,HIGH);
  }
  if (band==7){
   digitalWrite(BAND_OUT1,HIGH);
   digitalWrite(BAND_OUT2,HIGH);
   digitalWrite(BAND_OUT3,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 件のコメント:

emercito さんのコメント...

Hi JA2GQP I don´t speak Japanese, but I hope You could Understand English :P

I´m looking for a multifeature VFO which uses SI5351, a0,96 I2C oled and Aduino. There´s something on Internet, but no sketch, nothing. It comes with 18 menus, FCC Standard Channels, even more. Are You cb Vfo able to handle these options?
73 from Brazil :)

JA2GQP さんのコメント...

Hi emercito.

I think it is difficult to find a product that perfectly meets your specifications even if you search the web. I think some kind of modification is necessary.

There is a thing of specification close to the VFO introduced in my Blog.

1.
https://ja2gqp.blogspot.com/2019/04/si5351-oled-3band-vfo.html
This VFO is a simple 3-band thing that does not include BFO.

2.
https://ja2gqp.blogspot.com/2016/06/si5351-vfo.html
This is a multi-band product using nokia5110 for the display. This VFO is popular.

Both VFOs do not have peripheral control such as relay switching circuit control. Relay control can be achieved with a simple modification.

Wander - PY2WY さんのコメント...

hello, is it possible to send me the sketch and the libraries of the version with BFO?
my e-mail: py2wy@hotmail.com
TNX

JA2GQP さんのコメント...

Hi Wander.
Public files are on my download site.
https://sites.google.com/site/ja2gqp/
Download stm32_si5351a.zip from the stm32 folder on this site.

Wander - PY2WY さんのコメント...

I did not find the library #include "src / Ucglib.h"

JA2GQP さんのコメント...

Download the general ones used in Arduino IDE from Git Hub. I only supply customized ones.

JA2GQP さんのコメント...

If it is not included in the zip file, use the one that is generally available.

Wander - PY2WY さんのコメント...

I understood about the library.
when I write from the following error message:
'PB12' was not declared in this scope

JA2GQP さんのコメント...

Public sketches should compile without error. This sketch is a stable software that many people use. PB12 is a port of stm32f103c8t6. The fact that this port is not recognized means that the development environment for stm32f103c8t6 is not ready. Arduino IDE may not have the development environment for stm32f103c8t6.

Wander - PY2WY さんのコメント...

Got a BFO version for arduino nano atmega328?

JA2GQP さんのコメント...

My sketch is stm32 version and BFO compatible. Please read the public contents. It does not work with atmega328p. Atmega328p does not have enough memory so it is difficult to support BFO.

JA2GQP さんのコメント...

If you use atmega32p, it is here.
https://ja2gqp.blogspot.com/2017/06/si5351a-tft-vfo-ver11.html
Please read the contents carefully because various VFOs are available.

Wander - PY2WY さんのコメント...

Now with smt32 correctly installed, when I load Sketch, error message:
exit status 1
'xtalFreq' was not declared in this scope

JA2GQP さんのコメント...

Hi Wander.

Save si5351a2.h in the same directory as the sketch. xtalfreq is declared in si5351a2.h. My site is intended for people who know the basics, so I don't know if I won't reply in the future.

Wander - PY2WY さんのコメント...

everything is working perfectly, just no signal on clk0 and clk2 of SI5153, SDA PB7 and SCL PB6? What should I do, thanks for your patience.

Mikele さんのコメント...

hello ja2gqp
is TFT display 2,8inch 240x320 ok for this project ?
thanks in advance..73 de 9a3xz Mikele

JA2GQP さんのコメント...

Hi Mikele.
OK if SPI 240x320.

Mikele さんのコメント...

thanks so much !