回路図、スケッチはダウンロードサイトsi5351a TFTフォルダに2種類有ります。
si5351_TFT18.zip,si5351_TFT181.zip
回路図である。si5351aモジュールのclk2からBFO出力を行っている。
インクルードファイル
si5351aの制御は、ライブラリを使わずに、インクルードファイルで行っている。このファイルをスケッチと同じフォルダーに保存して使う。周波数が変わる毎に発生するクリック低減のため、PLLリセットを行わない事(コメントアウトしてある)とした。但し、位相制御などタイミングを重視する場合、PLLリセットを行う必要が有るであろう。si5351a2.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
//----------------------------------------------------------------------
// Modifications: JA2GQP,2017/5/20
// 1)Output is CLK0 and CLK2.
// 2)Arduino and stm32duino Operable.
////////////////////////////////////////////////////////////////////////
#include <Wire.h>
#define CLK0_CTRL 16 // Register definitions
#define CLK1_CTRL 17
#define CLK2_CTRL 18
#define MSNA_ADDR 26
#define MSNB_ADDR 34
#define MS0_ADDR 42
#define MS1_ADDR 50
#define MS2_ADDR 58
#define PLL_RESET 177
#define XTAL_LOAD_C 183
#define R_DIV_1 0b00000000 // R-division ratio definitions
#define R_DIV_2 0b00010000
#define R_DIV_4 0b00100000
#define R_DIV_8 0b00110000
#define R_DIV_16 0b01000000
#define R_DIV_32 0b01010000
#define R_DIV_64 0b01100000
#define R_DIV_128 0b01110000
#define Si5351A_ADDR 0x60
#define CLK_SRC_PLL_A 0b00000000
#define CLK_SRC_PLL_B 0b00100000
#define XTAL_FREQ 25000000 // Crystal frequency for Hans' board
////////////////////////////////////////////////////////////////////////
// I2C write
////////////////////////////////////////////////////////////////////////
void Si5351_write(byte Reg , byte Data){
Wire.beginTransmission(Si5351A_ADDR);
Wire.write(Reg);
Wire.write(Data);
Wire.endTransmission();
}
////////////////////////////////////////////////////////////////////////
// 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;
Si5351_write(pll + 0, (P3 & 0x0000FF00) >> 8);
Si5351_write(pll + 1, (P3 & 0x000000FF));
Si5351_write(pll + 2, (P1 & 0x00030000) >> 16);
Si5351_write(pll + 3, (P1 & 0x0000FF00) >> 8);
Si5351_write(pll + 4, (P1 & 0x000000FF));
Si5351_write(pll + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
Si5351_write(pll + 6, (P2 & 0x0000FF00) >> 8);
Si5351_write(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;
Si5351_write(synth + 0, (P3 & 0x0000FF00) >> 8);
Si5351_write(synth + 1, (P3 & 0x000000FF));
Si5351_write(synth + 2, ((P1 & 0x00030000) >> 16) | rDiv);
Si5351_write(synth + 3, (P1 & 0x0000FF00) >> 8);
Si5351_write(synth + 4, (P1 & 0x000000FF));
Si5351_write(synth + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
Si5351_write(synth + 6, (P2 & 0x0000FF00) >> 8);
Si5351_write(synth + 7, (P2 & 0x000000FF));
}
////////////////////////////////////////////////////////////////////////
// Switches off Si5351a output
// Example: si5351aOutputOff(CLK0_CTRL);
// will switch off output CLK0
////////////////////////////////////////////////////////////////////////
void si5351aOutputOff(uint8_t clk){
Si5351_write(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(MSNA_ADDR, 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(MS0_ADDR, divider, 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
// Si5351_write(PLL_RESET, 0x20);
// Finally switch on the CLK0 output (0x4F)
// and set the MultiSynth0 input to be PLL A
Si5351_write(CLK0_CTRL, 0x4F | CLK_SRC_PLL_A); // Strength 8mA
}
////////////////////////////////////////////////////////////////////////
// Set CLK1 output ON and to the specified frequency
// Frequency is in the range 1MHz to 150MHz
// Example: si5351aSetFrequency2(10000000);
// will set output CLK0 to 10MHz
//
// This example sets up PLL B
// and MultiSynth 1
// and produces the output on CLK1
////////////////////////////////////////////////////////////////////////
void si5351aSetFrequency2(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 B with the calculated multiplication ratio
setupPLL(MSNB_ADDR, 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(MS2_ADDR, divider, 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
// Si5351_write(PLL_RESET, 0x80);
// Finally switch on the CLK1 output
// and set the MultiSynth0 input to be PLL B
Si5351_write(CLK2_CTRL, 0x6F | CLK_SRC_PLL_B); // Strength 8mA
}
スケッチ
BFO出力とLOwerヘテロダインに対応。BITX40の設定は、仕様周波数で記述してあるので必要であれば、実周波数に変更する程度で良いだろう。ただ、BITX40実機を持ってないので未確認。//////////////////////////////////////////////////////////////////////////////
// Copyright©2016.JA2GQP.All rights reserved.
// si5351a PLL VFO Ver1.101 << JA2NKD sketch is based >>
// 2017/6/3
// JA2GQP
// << Aruduino IDE 1.8.2 >>
//
//----------------------------------------------------------------------------
// Function
// 1.RIT Operation(-10kHZ to 10kHZ)
// 2.STEP(10,100,1k,10k)
// 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 "si5351a2.h"
#include <SPI.h>
#include <Rotary.h>
#include <EEPROM.h>
#include "Ucglib.h"
//---------- TFT setting ---------------
Ucglib_ST7735_18x128x160_HWSPI ucg(/*sclk= 13, data= 11, */ /*cd=*/ 9 , /*cs=*/ 10, /*reset=*/ 8);
//---------- Encorder setting ---------------
#define ENC_A 2 // Encorder A
#define ENC_B 3 // Encoeder B
Rotary r=Rotary(ENC_A,ENC_B);
//---------- I/O setting -------------------
#define modeout1 7 // DIO7
#define modeout2 12 // DIO12
#define modesw 6 // DIO6
#define stepsw 4 // DIO4
#define ritsw 5 // DIO5
#define txsw A3 // A3
#define s_meter A0 // A0
#define t_meter A1 // A1
//---------- EEPROM Memory Address ----------
#define Frq_Eep 0x00 // Frequency(4byte*4)
#define Stp_Eep 0x10 // STEP(4byte*4)
#define Chn_Eep 0x20 // Channel(1byte*1)
#define Mode_Eep 0x22 // Mode(1byte*1)
#define Eep_Int 0x2e // Eep Init(1byte*1)
#define Max_Chn 4 // Max Channel(4ch)
#define Int_End 73 // Initial end code
//----------- Default Frequency Value --------------------
#define UPPER 0 // Upoper heterodyne
#define LOWER 1 // Lower heterodyne
////////////////////////////////////////////////////////////////
// BITX40 Setting example(Upper heterodyne) No.1
////////////////////////////////////////////////////////////////
#define DEF_FRQ 7050000L // Init Frequency
#define DEF_FMAX 7200000L // Frequency Max
#define DEF_FMIN 7000000L // Min
#define DEF_RLSB 10698500L // RX IF Shift LSB
#define DEF_RUSB 10701500L // USB
#define DEF_RCW 10699200L // CW
#define DEF_RAM 10700000L // AM
#define DEF_TLSB 10698500L // TX IF Shift LSB
#define DEF_TUSB 10701500L // USB
#define DEF_TCW 10700000L // CW
#define DEF_TAM 10700000L // AM
byte hetero = UPPER; // Lower heterodyne set
////////////////////////////////////////////////////////////////
// BITX40 Setting example(Lower heterodyne) No.2
////////////////////////////////////////////////////////////////
/*
#define DEF_FRQ 7050000L // Init Frequency
#define DEF_FMAX 7200000L // Frequency Max
#define DEF_FMIN 7000000L // Min
#define DEF_RLSB 11998500L // RX IF Shift LSB
#define DEF_RUSB 12001500L // USB
#define DEF_RCW 11999400L // CW
#define DEF_RAM 12000000L // AM
#define DEF_TLSB 11998500L // TX IF Shift LSB
#define DEF_TUSB 12001500L // USB
#define DEF_TCW 12000000L // CW
#define DEF_TAM 12000000L // AM
byte hetero = LOWER; // Lower heterodyne set
*/
//----------- Default ETC. Value --------------------
#define DEF_STP 100L // Init STEP
#define 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 ifshiftb;
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 vfofreq = 0; // VFO data
long vfofreqb; // old
char f100m,f10m,fmega,f100k,f10k,f1k,f100,f10,f1;
int vfostep=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() {
Wire.begin();
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){
Vfo_write();
ritlcd();
fritold=freqrit;
}
}
else{
if (freq == freqold){
smeter();
}
Vfo_write();
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;
}
//---------- VFO out ---------------
void Vfo_out(long frequency){
if(vfofreq != vfofreqb){
si5351aSetFrequency(frequency);
vfofreqb = vfofreq;
}
}
//---------- BFO out ---------------
void Bfo_out(long frequency){
if(ifshift != ifshiftb){
si5351aSetFrequency2(frequency);
ifshiftb = ifshift;
}
}
//---------- S-meter --------------------------
void smeter(){
smeterval1=analogRead(s_meter);
smeterval1=smeterval1/50;
if (smeterval1>14){smeterval1=14;} //15
int sx1=sx1+(smeterval1*9); //16
sx1=sx1+21; //41
int sx2=0;
sx2=sx2+(40+((15-smeterval1)*9)); //ucg_font_6x10_mf
ucg.setFont(ucg_font_fub20_tn); //ucg_font_fub35_tn
ucg.setColor(0,0,0); // BLACK
ucg.drawBox(sx1,99,sx2,8);
ucg.setPrintPos(20,109); //40,200
for(int i=1;i<=smeterval1;i++){
if (i<=8){
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); // BLACK
ucg.drawBox(20,99,135,8); //41,180,270,16
tmeterval=analogRead(t_meter);
tmeterval=tmeterval/50;
if (tmeterval>14){tmeterval=14;}
int sx1=sx1+(tmeterval*9);
sx1=sx1+21;
int sx2=0;
sx2=sx2+(40+((15-tmeterval)*9));
ucg.setFont(ucg_font_fub20_tn); //35ucg_font_fub20_tn
ucg.setColor(0,0,0); //BLACK
ucg.drawBox(sx1,78,sx2,8);
ucg.setPrintPos(20,90); //85(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;
}
}
}
}
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(){
long vfofreq_RX = vfofreq;;
long ifshift_RX = ifshift;;
// noInterrupts();
if(hetero == UPPER){ // Upper heterodyne
if (flagmode==0){ifshift=txshiftLSB;}
if (flagmode==1){ifshift=txshiftUSB;}
if (flagmode==2){ifshift=txshiftCW;}
if (flagmode==3){ifshift=txshiftAM;}
vfofreq=freq+ifshift;
}
else{ // Lower heterodyne
if (flagmode==0){ifshift=txshiftLSB;}
if (flagmode==1){ifshift=txshiftUSB;}
if (flagmode==2){ifshift=txshiftCW;}
if (flagmode==3){ifshift=txshiftAM;}
vfofreq=ifshift-freq;
}
Vfo_out(vfofreq); // vfo out
Bfo_out(ifshift); // BFO out
ucg.setPrintPos(70,75); //140,140
ucg.setFont(ucg_font_6x10_mf); //17ucg_font_fub11_tn
ucg.setColor(255,0,0);
ucg.print("ON AIR");
while(digitalRead(txsw) == LOW){
tmeter();
}
vfofreq = vfofreq_RX;
ifshift = ifshift_RX;
ucg.drawBox(15,63,95,15); //30,120,250,30 // ON AIR Erase
Vfo_write();
ucg.drawBox(20,80,135,8); //41,145,270,16 // Level Erase
// interrupts();
}
//------------- Mode change(LSB-USB-CW-AM) ------------
void modeset(){
ucg.setFont(ucg_font_6x10_mf); //17ucg_font_fub11_tn
// if (fmode==0){
if (fmode==1){ // 2016/8/3
ifshift=ifshiftUSB;
flagmode = 1; // 2016/8/3
ucg.setColor(255,255,0); //Black?
ucg.setPrintPos(44,43); //(82,82
ucg.print("USB");
ucg.setPrintPos(9,43); //12,82
ucg.setColor(0,0,0); //Black Yellow
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(9,60); //12,112
ucg.setColor(255,255,0); //Yellow
ucg.print("C W");
ucg.setPrintPos(44,43); //82,82
ucg.setColor(0,0,0); //Black
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(44,60); //82,112
ucg.setColor(255,255,0); //Yellow
ucg.print("A M");
ucg.setColor(0,0,0); //Black
ucg.setPrintPos(9,60); //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(9,43); //12,82
ucg.setColor(255,255,0); //Yellow
ucg.print("LSB");
ucg.setPrintPos(44,60); //82,112
ucg.setColor(0,0,0); //Black
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;}
Vfo_write();
while(digitalRead(modesw) == LOW);
}
//------------ Rit SET ------------------------------
void setrit(){
if(flagrit==0){
flagrit=1;
ucg.setFont(ucg_font_6x10_mf); //11ucg_font_fub11_tn
ucg.setPrintPos(95,55); //190,110
ucg.setColor(255,0,0);
// freqrit=0;
ritlcd();
}
else {
flagrit=0;
if(hetero == UPPER)
vfofreq=freq+ifshift;
else
vfofreq=ifshift-freq;
Vfo_out(vfofreq); // vfo Out
freqt=String(freq);
ucg.setFont(ucg_font_6x10_mf); //11ucg_font_fub11_tn
ucg.setPrintPos(95,55); //190,110
ucg.setColor(255,255,255);
// ucg.print("RIT");
ucg.setColor(0,0,0);
ucg.drawRBox(112,52,44,10,1); //222,92,91,21,3
freqrit=0;
}
while(digitalRead(ritsw) == LOW);
}
//----------- Rit screen ----------------------
void ritlcd(){
noInterrupts();
ucg.setColor(0,0,0);
ucg.drawBox(111,51,45,13); //222,92,91,21 110,50,47,15,
ucg.setFont(ucg_font_6x10_mf); //17 ucg_font_fub11_tn
ucg.setColor(0,255,255);
ucg.setPrintPos(115,61); //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); //0,0,0
ucg.drawRBox(111,33,45,11,1); //221,61,93,23,3
ucg.setFont(ucg_font_6x10_mf); //17ucg_font_fub11_tn
ucg.setColor(255,255,255);
ucg.setPrintPos(110,43); //220,80
if (fstep==10000){ucg.print(" 10KHz");}
if (fstep==1000){ucg.print(" 1KHz");}
if (fstep==100){ucg.print(" 100Hz");}
if (fstep==10){ucg.print(" 10Hz");}
}
//----------- Main frequency screen -------------------
void freqlcd(){
ucg.setFont(ucg_font_osr18_tn); //35 ucg_font_fub20_tn
int mojisuu=(freqt.length());
if(freq<1000000){
ucg.setColor(0,0,0);
ucg.drawBox(52,7,9,20); //103,9,15,36
}
if(f100k !=(freqt.charAt(mojisuu-6))){
ucg.setColor(0,0,0);
ucg.drawBox(59,7,15,20); //118,9,28,36
ucg.setPrintPos(59,24); //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(59,7,15,20); //118,9,28,36
}
if(f10k !=(freqt.charAt(mojisuu-5))){
ucg.setColor(0,0,0);
ucg.drawBox(73,6,15,20); //146,9,28,36
ucg.setPrintPos(73,24); //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(73,6,14,19); //146,9,28,36
}
if(f1k !=(freqt.charAt(mojisuu-4))){
ucg.setColor(0,0,0);
ucg.drawBox(87,6,14,19); //174,9,28,36
ucg.setPrintPos(87,24); //(174,45
ucg.setColor(0,255,0);
ucg.print(freqt.charAt(mojisuu-4));
f1k = (freqt.charAt(mojisuu-4));
}
if(freq>=1000){
ucg.setPrintPos(101,24); //202,45
ucg.setColor(0,255,0);
ucg.print(".");
}
if(freq<1000){
ucg.setColor(0,0,0);
ucg.drawBox(101,6,8,19); // (202,9,15,36
}
if(f100 !=(freqt.charAt(mojisuu-3))){
ucg.setColor(0,0,0);
ucg.drawBox(109,6,14,19); //217,9,28,36
ucg.setPrintPos(108,24); //(215,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(109,6,14,19); //217,9,28,36
}
if(f10 !=(freqt.charAt(mojisuu-2))){
ucg.setColor(0,0,0);
ucg.drawBox(123,6,14,19); //245,9,28,36
ucg.setPrintPos(123,24); //(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,160,28,3); //0,0,320,55,5 OUTside
//ucg.drawRFrame(0,0,159,27,2); //1,1,318,53,5 INside
ucg.setColor(0,128,255); //FILL COLOR for MODE back
ucg.drawRBox(2,33,30,12,1); //5,60,60,25,3 LSB
ucg.drawRBox(37,33,30,12,1); //75,60,60,25,3 USB
ucg.drawRBox(2,50,30,12,1); //5,90,60,25,3 CW
ucg.drawRBox(37,50,30,12,1); //(75,90,60,25,3 AM
ucg.setFont(ucg_font_6x10_mf); //17
ucg.setPrintPos(9,43); //12,82
ucg.setColor(0,0,0);
ucg.print("LSB");
ucg.setPrintPos(44,43); //82,82
ucg.print("USB");
ucg.setPrintPos(9,60); //12,112
ucg.print("C W");
ucg.setPrintPos(44,60); //(82,112
ucg.print("A M");
ucg.setColor(255,255,255);
ucg.drawRFrame(110,32,47,15,1); //220,60,95,25,3 STEP frame
ucg.drawRFrame(110,50,47,15,1); //220,90,95,25,3 RIT frame
ucg.setColor(255,255,100); //100,100,100
ucg.setPrintPos(7,105); //15,200
ucg.print("S:");
ucg.setPrintPos(7,85); //15,165
ucg.print("P:");
ucg.setFont(ucg_font_6x10_mf); //11ucg_font_fub11_tn
ucg.setColor(250,255,0);
ucg.setPrintPos(80,43); //175,80
ucg.print("STEP");
ucg.setPrintPos(80,60); //190,110
ucg.setColor(255,255,0);
ucg.print("RIT");
ucg.setColor(255,255,255); //100,100,100
ucg.setPrintPos(20,115); //40,210
ucg.print("1--3---6---9--Over---");
ucg.setPrintPos(20,95); //40,175
ucg.print("1--3---5-----10------");
ucg.setPrintPos(5,127); //10,230
ucg.setColor(235,0,200);
ucg.print("si5351a VFO Ver1.1 JA2GQP" );
ucg.setFont(ucg_font_osr18_tn); //35 ucg_font_fub20_tf???
ucg .setPrintPos(37,24); //75,45
ucg.setColor(0,255,0);
ucg.print("7"); //Frequency
ucg.setPrintPos(51,24); //103,45
ucg.print(".");
ucg.setPrintPos(138,24); //273,45
ucg.print("0"); //Frequency end
}
//--------------- VFO Write -------------------------------
void Vfo_write(){
if (flagrit==0){
if(hetero == UPPER)
vfofreq=freq+ifshift;
else
vfofreq=ifshift-freq;
Vfo_out(vfofreq); // DDS out
}
if(flagrit==1){
if(hetero == UPPER)
vfofreq=freq+ifshift+freqrit;
else
vfofreq=ifshift-freqrit-freq;
Vfo_out(vfofreq); // DDS out
}
Bfo_out(ifshift); // BFO
}
回路図のTFT分解能に誤記があり、修正した。
返信削除BFOの送信シフト処理に問題が有った為、スケッチを修正し、Ver1.101とした。
返信削除坂本と申します常々拝見いたしておりありがとうございます。
返信削除Adafruitのsi5351モジュールとArduinoでsi5351a2.hをつかわさせていただきマルチ出力を発振させてみました。拍子抜けするぐらい簡単に希望の2周波数と+10dmb以上ある出力が取り出せ感動いたしました、ありがとうございます。(これでAD9851からも卒業できそうです。^^)
si5351aSetFrequency()で出力させてスペアナ(Gigast5)で見ますと単出力であれば基本周波数とN倍高調波のみできれいに並んでおりますが双出力にします片方の出力を影響を受けた表示となるようです。近接するck0 ck2 でしかも出力も大きいのでいたし方ないのかなとも思っております。
すみません追伸です、Adafruitのsi5351モジュールがわずかですが低い周波数となるようです。モジュールは10pFで設定されているようですが
返信削除#define XTAL_LOAD_C 183 を適当に変更してみたのですが変化なしでした。
お教えください。
初めまして、田口 典克と申します。
返信削除休眠中のアマチュア無線家です。
リタイヤ後の過ごし方を模索中の中で、昔趣味にしていた
ラジオの製作をコツコツとはじめています。
JA2GQP水野さんとJA2NKD松浦さんのブログには大変おせわになっています。
既に、参考にさせていただいた記事で、DDS VFO(7MHzシングルSP用)
とRF ANALYZER は完成し、活躍をはじめました。
最近、SOLTEC工房さんより手に入れたキット基板でSi5351仕様のVFOの製作
に取り掛かり、ハードウェアーは、完成したのですがスケッチをどうしても
旨く書き込めないのです。秋月より購入した。ARDUINO NANO互換機(Next purpie)
が原因とも思えないので、書き込み手順に何か原因が有るのかよくわかりません!
大変恐縮ですが、なにか手がかりになる事がありましたら御教示願えればと思い
投稿させていただきました。
田口さん こんにちは
削除水野です。
SOFTECのVFOとの事、了解です。
まず、コンパイルする環境として、スケッチと同じフォルダにsi5351a2.hを置いてください。
ヘッダーファイルが正しく設定されていれば、コンパイルは通るはずです。
次に、Arduino IDE ツールのボード:”Arduino Nano”、プロセッサ:”ATmega328P”と
なってますか?
更に、シリアルポートが正しく認識されてますか?
秋月のボードの素性が判りませんが、シリアルポートを正しく認識しているか確認して下さい。
(コントロールパネルからデバイスマネージャを開いて確かめれば良いと思います。)
ボード、CPU、シリアルポートが正しく設定されていれば、書込み出来る筈です。
それでも不明であれば、エラーメッセージの画面を送ってください。
以上
ご連絡ありがとうございます。
削除田口です。
早速ですが、si5351a2.hの#includeエラーはでなくなりましたが今度は、
#include ・・・・
でコンパイルエラーとなってしまいました。
ソフトはさっぱり理解できていないので、いちいち私のボケ頭脳は、
フリーズしてしまいます。
Arduino IDEツールの認識と設定関係は、水野さんのご指摘の通りに
なっていますので書き込み段階のチェックはOKかと思います。
このブログ上で画像の添付方法がわかりませんのでメールアドレスを
G-mail宛にご連絡いただけらば、表示された内容をPDFにしたファイルを
送ります。
大変、お手数をお掛けして申し訳ありませんが、よろしくお願いいたします。
追伸、田口です。
返信削除エラーメッセージは、
「C:\Users\90010017\Downloads\si5351_TFT181\si5351_TFT181.ino:27:20: fatal error: Rotary.h: No such file
ordirectory
#include
^
compilation terminated.exit status 1ボードArduino Nanoに対するコンパイル時にエラーが発生しました。」
です。
田口さん
削除こちらにメール下さい。
ja2gqp@gmail.com
田口さん
削除水野です。
原因が判りました。Rotaly.hがインストールされてない為に、エラーになっている様です。こちらからダウンロードして、ライブラリをインストールしてください。
https://github.com/brianlow/Rotary
I am using a tft display with ILI9341 18xx240x320. I only have VFO displaying in upper left 1/4 quadrant of the display I have worked for 2 weeks every day trying to figure what is wrong. I am turning to you for help.
返信削除How can I make the VFO fill the whole screen? My email is rholsti@icloud.com Thank you, I hope to hear from you soon. 73's, KH2BR
ILI9341 18xx240x320でTFTディスプレイを使用しています。何が問題なのかを理解するために毎日2週間作業したディスプレイの左上1/4象限にVFOを表示しているだけです。私はあなたに助けを求めています。
VFOを画面全体に表示させるにはどうすればよいですか?私のメールはrholsti@icloud.comです。ありがとうございます。ご連絡をお待ちしております。 73年代、KH2BR
ILI 9341 18 xx 240 x 320 de TFT disupurei o shiyō shite imasu. Nani ga mondaina no ka o rikai suru tame ni mainichi 2-shūkan sagyō shita disupurei no hidariue 1/ 4 shōgen ni VFO o hyōji shite iru dakedesu. Watashi wa anata ni tasuke o motomete imasu. VFO o gamen zentai ni hyōji sa seru ni wa dōsureba yoidesu ka? Watashi no mēru wa rholsti@ icloud. Komudesu. Arigatōgozaimasu. Go renraku o omachi shite orimasu. 73-Nendai, KH 2 BR
saya mengupload program VFO ini dan sudah tampil di display st7735 dgn tampilan frekuensi output dari 7.000.000 s/d 7.200.000 saja
返信削除yang kami tanyakan dibagian mana sketch yang perlu di edit jika akan menampilkan frekuensi output dari minimum 3.000.000 s/d 30.000.000
atas jawabannya sebelum dan sesudahnya diucapkan terima kasih
salam
M zuri
Mohon maaf tulisan diatas kami betulkan menjadi :
返信削除saya mengupload program VFO ini dan sudah tampil di display st7735 dgn tampilan frekuensi frekuensi dari 7.000.000 s / d 7.200.000 saja
yang kami tanyakan dibagian mana sketch yang perlu di edit jika akan menampilkan frekuensi output dari minimum 3.000.000 dam maximum 30.000.000
atas jawaban sebelum dan sebelum diucapkan terima kasih
For many months I have tried to make your ILI9431 VFO work properly. The breadboard setup passes all the examples and they display properly.
返信削除From what I see, the fixed part of the display is showing properly but none of the variable data appears. A "0" does show on the frequency space, however.
I can't tell if the rotor works because there in on visible frequency. The RF analyzer does work on the same breadboard. Other scripts work as well.
Any suggestions of where to look? Thanks, Jack
Hi JACK
返信削除There was a case where the operation was unstable.
Please download it from the download site as it has been fixed.
https://sites.google.com/view/en2gqp
si5351a_TFT181.zip in the si5351s TFT folder