基于Si5351a模块制作VFO

2025-02-15

我基于Si5351a模块制作了VFO。为了提高频率的精度,我借助了GPS PPS信号。

基于Si5351a模块制作VFO (https://www.qianyan.tech/) 头条 第1张

Si5351a是制作精确时钟的好芯片。但由于其晶体振荡器电路的原因,存在一定的频率误差。将其频率与GPS PPS进行比较,可以得到两者之差的校正值。该频率校正值可用于VFO校正。

基于Si5351a模块制作VFO (https://www.qianyan.tech/) 头条 第2张

原理图

基于Si5351a模块制作VFO (https://www.qianyan.tech/) 头条 第3张

基于Si5351a模块制作VFO (https://www.qianyan.tech/) 头条 第4张

代码


/


/ 2025.01.07 pps OK, Sw1.2 OK 91%/62%


// 2024.12.09 tiny4kOLED


// 2024.11.16 Refered and Changed for R909-VFO-GPS


// added correction FREQ display


// changed store condition correction


// GITHUB https://github.com/Nobcha/R909-VFO-GPS


// D2:PPS,D5:2.5M,D7:EN,D0/RX:GPS/TX,LCD1602


//


// gps-calibration-5351


// https://github.com/csqwdy/gps-calibration-5351/blob/main/README.md


// 2022-03-06 Modified the encoder to work in signal change interrupt mode,


// Original was SQ1GU http://sq1gu.tobis.com.pl/en/dds


// include the library code:


#include <TINYGPS++.H>


// Change to OLED


#include


#include


#include


#include


#include


#include


#include


// The TinyGPS++ object


TinyGPSPlus gps;


Si5351 si5351;


#define control 2 // 1=button ,2=EP11 ,3=EP12


// Set up MCU pins


#define GPS_Enable 7


#define ppsPin 2 // GPS-PPS INT


#define re_sw A0


#define encoderPinA 4 // Signal change INT


#define encoderPinB 3 //


#define ledPin A1


#define func_sw A2 // SW1:<80, SW2:<250,


#define Freq2 1000000000ULL


volatile byte seqA = 0;


volatile byte seqB = 0;


volatile byte cnt1 = 0;


volatile byte cnt2 = 0;


volatile boolean right = false;


volatile boolean left = false;


volatile boolean button = false;


// configure variables


unsigned long XtalFreq = 100000000;


unsigned long XtalFreq_old = 100000000;


long stab;


long correction = 0;


byte stab_count = 44;


unsigned long mult = 0, Freq = 10000000;


int second = 0, minute = 0, hour = 0;


int zone = 9;


unsigned int tcount = 0;


unsigned int tcount2 = 0;


int validGPSflag = false;


char c;


boolean newdata = false;


boolean GPSstatus = true;


byte new_freq = 1;


unsigned long freq_step = 1000;


byte encoderOLD, menu = 6, band = 1, f_step = 1;


boolean time_enable = true;


unsigned long pps_correct_time;


byte pps_valid = 0;


byte correct_byte = 1;


float stab_float;


unsigned long button_on_time;


boolean oled_turn = 1;


boolean vfo_counter = true; // true vfo


boolean new_c_freq = 0;


boolean pps_error = 1;


int func_sw_value;


// prototype


void PPSinterrupt(void);


void timezone_on_oled(void);


void stab_on_oled(void);


void correct_freq(void);


void corr_on_oled(void);


void freq2_on_oled(void);


void step_on_oled(void);


void band_on_oled(void);


void time_on_oled(void);


void sat_on_oled(void);


void freq_on_oled(unsigned long);


void update_si5351a(void);


void correct_si5351a(void);


static void GPSproces(unsigned long);


void change_up(void);


void change_down(void);


void loglat_on_oled(void);


void vfo_fr_oled (void);


void date_on_oled(void);


//*******************************************************************************


// Timer 1 overflow intrrupt vector. Count 2.5MHz


//*******************************************************************************


ISR(TIMER1_OVF_vect)


{


mult++; //Increment multiplier


TIFR1 = (1 << TOV1); //Clear overlow flag


}


//*********************************************************************


// Judge the rotating direction


// Signal change interrupt


本文编译自


h


ackster


.io

相关推荐