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
}
}
Beautiful synth. Beautiful display. But we need a second output
返信削除Si5351. But the memory of a little....
It will be realized by mega2560.
削除However, it is difficult by the UNO and the nano.
YES, in the NANO difficult. Can try to cut font library, leave some big numbers (35 font size).
返信削除I wanted to try, but could not figure out how the font is designed for this display. For monochrome display I was able to reduce library.
返信削除Please publish If you can Ucglib to the Compact.
削除Please e- maile, i send file
返信削除us5evd()ukr.net
replace UCG_FONT_SECTION ( "ucg_font_fub35_tr") in the file
返信削除/*
replace UCG_FONT_SECTION ( "ucg_font_fub35_tr") in the file "ucg font vector data"
use chars code only 32,45-57
*/
const ucg_fntpgm_uint8_t ucg_font_fub35_tr[733] UCG_FONT_SECTION("ucg_font_fub35_tr") = {
95,0,5,5,6,6,5,6,7,50,52,255,243,35,247,36,
250,6,111,13,86,
32,6,0,0,193,39, //spase
45,9,141,
33,211,40,248,1,8,
46,9,135,81,193,39,248,192,2,
47,
42,209,41,187,42,43,24,193,74,140,96,101,171,96,37,70,
176,18,35,88,217,42,88,137,17,172,196,8,86,182,10,86,
90,5,43,49,130,149,173,130,1,
48,73,217,40,67,238,81,
154,163,32,36,157,169,28,230,40,6,58,198,145,140,97,40,
99,24,203,16,198,50,194,177,140,112,44,35,28,203,8,199,
114,191,101,132,99,25,225,88,134,48,150,33,140,101,8,67,
29,226,72,6,49,208,65,14,115,152,201,72,8,82,78,83,
16,0,
49,24,207,88,65,46,58,14,82,20,178,136,15,76,
161,17,11,73,204,129,206,255,255,31,
50,47,217,40,67,46,
90,216,147,162,51,149,106,32,6,25,71,58,132,161,142,112,
168,67,158,197,67,30,17,129,40,152,188,116,46,121,169,135,
188,228,33,16,137,31,248,3,26,
51,61,216,40,67,174,89,
214,131,34,51,145,106,28,6,17,7,58,196,145,12,113,164,
35,158,224,17,15,151,44,134,41,46,121,75,107,34,34,143,
120,72,67,30,209,81,174,116,4,4,29,226,56,199,168,200,
100,34,244,172,229,0,
52,61,218,24,65,110,75,160,242,86,
142,213,26,102,132,131,25,225,88,134,56,150,33,14,101,140,
35,29,227,72,6,57,144,81,14,100,148,227,24,230,204,24,
231,40,6,58,200,129,14,98,164,131,124,224,31,8,222,49,
207,71,0,
53,52,216,40,65,110,168,70,125,227,136,231,27,
199,57,194,82,40,82,141,106,36,5,17,7,58,196,145,142,
96,168,35,158,139,142,114,210,17,142,116,4,228,28,163,26,
84,145,144,179,152,3,0,
54,75,217,40,67,46,82,154,163,
32,36,25,170,32,229,32,200,57,198,129,14,113,200,147,52,
228,65,142,115,136,165,28,161,33,71,112,198,37,22,130,8,
197,32,33,65,71,64,148,17,16,245,166,142,112,40,67,28,
202,16,8,58,4,130,142,129,152,163,76,102,58,81,114,154,
130,0,
55,47,216,40,65,46,248,7,168,120,130,71,60,32,
2,15,136,192,3,34,240,128,168,135,64,228,33,16,129,7,
68,224,1,81,15,129,200,67,32,242,16,136,188,228,33,12,
0,
56,76,217,40,67,174,97,22,132,166,82,145,106,36,37,
17,200,65,196,145,14,113,164,67,28,233,16,71,58,196,145,
142,113,156,131,32,229,56,81,114,218,178,32,36,25,164,32,
3,57,199,56,210,17,142,101,132,99,25,225,88,174,245,36,
40,29,2,57,136,184,70,69,168,19,169,198,0,
57,71,217,
40,67,238,89,152,163,162,51,21,138,32,6,25,7,58,134,
145,144,112,168,35,28,234,8,135,122,151,146,112,160,36,32,
101,17,151,120,194,49,156,112,16,70,28,199,40,135,52,228,
153,56,208,49,14,116,140,227,32,228,40,136,153,140,132,32,
229,52,5,1,
};
If the crop is similar to the rest of the fonts, it will add about 3kb. Total will 7K. It may be enough?
返信削除how to eliminate the loud clicks when frequency hopping?
返信削除This problem is difficult in PLL.
削除Hello
返信削除When I use tft 1.44inch I have 27% free space, is any chance to run clk2 for bfo
When running in a bfo, please tell me.
削除Hi
返信削除Good project! It inspired me to make my own, take a look https://www.youtube.com/watch?v=76_tweVlOxc
Hi.
削除I saw. It is a good easy to use VFO.
HI Akio,
返信削除I have a new BITX 40.
The I.F. is 12mhz
I need 5MHZ L.O. = 7.0 Mhz 4.7MHZ =7.3 Mhz
Display should be 7.0 Mhz (L.O.) 5 MHZ 7.3 MHZ (L.O.) 4.7 Mhz
How do I change display frequency? I have L.O. set ok.
DEF_RCW = -2300000L; // CW.
Can you help ? Robert KH2BR rholsti@icloud.com
Hi,Akio
返信削除Add sketch under 1.8 inch screen st775 please, synthesizer on si5351.
Hi Akio San,
返信削除Have you designed a pcb for this?
Sorry no PCB.
削除コメント有難うございます。
返信削除AD9850でVFOを作るとの事、了解です。頑張って作ってください。
Hello Mr. ja2gqp
返信削除I had a request from you
Please send me the hex DDS si5351 file
We haven't been able to fix it for a long time and now we need the hex file
Our LCD type is TFT ILI 9341
Its size is 8 * 2 inches
Please email the hex file to me
This is my email address:
ep3as.83@gmail.com
Thanks a lot
73
Hi EP3AS.
返信削除I'm sorry. I don't have my development environment anymore, so I can't handle it.