А у меня как раз методом тыка получилось вот так. И оно работает, только при переключении с
частотомера на генератор перестаёт работать энкодер, приходиться делать сброс и тогда можно
переключать частоту энкодером.
#include <SPI.h>
#include <EEPROM.h>
#include <FreqCount.h>
#include <LiquidCrystal_I2C.h> //Библиотека - http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <Encoder.h> // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
Encoder myEnc(9, 8);//CLK, DT
float f=9.4;
long b,h_bit,l_bit,f_lcd,f_ust;
const long f25 = 25000000;// частота кварца, если нет эталонного частотомера установите частоту 25000000 Гц
int a[9],i,form,h_g,y;
bool w=1,on;
long oldPosition = -999,newPosition,times;
unsigned long t_0;float t0;
int x1,n=3,r;
void setup() {
Wire.begin();Serial.begin(9600);
lcd.init();lcd.backlight();
MsTimer2::set(1, to_Timer);MsTimer2::start();
lcd.setCursor(0,0);lcd.print("AD9833 GENERATOR");
lcd.setCursor(0,1);lcd.print(" FREQ METR ");delay(3000);lcd.clear();// ЗАСТАВКА
pinMode(7,INPUT); // sw
pinMode(2,INPUT_PULLUP);// on/off out
pinMode(3,INPUT_PULLUP);// dac,sin,tri
pinMode(4,INPUT_PULLUP);// F = 0
pinMode(A1,INPUT); // ЧАСТОТОМЕР/ГЕНЕРАТОР
if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении
a[0] = EEPROM.read(0);a[1] = EEPROM.read(1);a[2] = EEPROM.read(2);a[3] = EEPROM.read(3);a[4] = EEPROM.read(4);a[5] = EEPROM.read(5);
a[6] = EEPROM.read(6);a[7] = EEPROM.read(7);a[8] = EEPROM.read(8);form = EEPROM.read(9);
ad();
}
void WriteAD9833(uint16_t Data){
SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV2, MSBFIRST, SPI_MODE2));
digitalWrite(SS, LOW);
delayMicroseconds(1);
SPI.transfer16(Data);
digitalWrite(SS, HIGH);
SPI.endTransaction();
}
void ad(){
b = f*pow(2,28)/f25;
if(b<16383){l_bit = b + 0x4000 ;h_bit = 0x4000;}
else{h_bit = (b>>14) + 0x4000;l_bit = b - (h_bit<<14) + 0x4000;}
SPI.begin();
WriteAD9833(0x2100);// 0010 0001 0000 0000 - Reset + DB28
WriteAD9833(l_bit); // 0100 0000 0000 0000 - Freq0 LSB
WriteAD9833(h_bit); // 0100 0000 0000 0000 - Freq0 MSB
WriteAD9833(0xC000);// 1100 0000 0000 0000 - Phase0
WriteAD9833(0x2000);// 0010 0000 0000 0000 - Exit Reset
}
void to_Timer(){newPosition = myEnc.read()/4;}
void loop() {
if(analogRead(1)>600){h_g++;y=0;delay(300);if(h_g>1){h_g=0;}}// ГЕНЕРАТОР/ЧАСТОТОМЕР (ПО УМОЛЧАНИЮ ПЕРВЫЙ ГЕНЕРАТОР)
if(h_g==1){ i=0; // ЧАСТОТОМЕР ////////////////////////////////////////////////////////////////////
if(y==1){FreqCount.begin(1000);}
if(digitalRead(7)==LOW){n++;x1=0;delay(100);}// ВЫБОР ВРЕМЕНИ ИЗМЕРЕНИЯ ПРИ ПОМОЩИ КНОПКИ ЭНКОДЕРА
lcd.setCursor(0,1);
if(n==1){x1++;if(x1==1){FreqCount.begin(100);}r=-1;lcd.print("T = 0.1 s ");}
if(n==2){x1++;if(x1==1){FreqCount.begin(10000);}r=1;lcd.print("T = 10 s ");}
if(n==3){x1++;if(x1==1){FreqCount.begin(1000);}r=0;lcd.print("T = 1 s ");}
if(n>3){n=1;}
lcd.setCursor(0,0);
lcd.print("F = "); // ВЫВОД ЧАСТОТЫ
if(t_0>=1000000 && n==3){t0=t_0/1000000.0;lcd.print(t0,6+r);lcd.print(" MHz");}
if(t_0<1000000 && n==3){t0=t_0/1000.0;lcd.print(t0,3+r);lcd.print(" kHz");}
if(t_0>=100000 && n==1){t0=t_0/100000.0;lcd.print(t0,6+r);lcd.print(" MHz");}
if(t_0<100000 && n==1){t0=t_0/100.0;lcd.print(t0,3+r);lcd.print(" kHz");}
if(t_0>=10000000 && n==2){t0=t_0/10000000.0;lcd.print(t0,6+r);lcd.print("MHz");}
if(t_0<10000000 && n==2){t0=t_0/10000.0;lcd.print(t0,3+r);lcd.print(" kHz");}
if (FreqCount.available()) {
t_0 = FreqCount.read(); // ИЗМЕРЕНИЕ ЧАСТОТЫ
lcd.setCursor(10,1);lcd.print("***");// ИНДИКАЦИЯ ИЗМЕРЕНИЯ
}
delay(200);
lcd.clear();
}
if(h_g==0){// ГЕНЕРАТОР //////////////////////////////////////////////////////////////////
if(digitalRead(4)==LOW){a[0]=0;a[1]=0;a[2]=0;a[3]=0;a[4]=0;a[5]=0;a[6]=0;a[7]=0;a[8]=0;w=1;on=0;delay(300);}
if(digitalRead(3)==LOW){form++;w=1;on=0;if(form>2){form=0;};delay(300);}
if(digitalRead(7)==LOW){i++;w=1;on=0;if(i>8){i=0;};delay(300);}
if(digitalRead(2)==LOW&&on==0){on=1;delay(300);w=1;}
if(digitalRead(2)==LOW&&on==1){on=0;delay(300);w=1;}
if(on==1){lcd.setCursor(0,1);lcd.print("OUT_ON ");i=100;}else{lcd.setCursor(0,1);lcd.print("OUT_OFF");}
if (newPosition != oldPosition){oldPosition = newPosition;a[i]=a[i]+newPosition;if(a[i]>9){a[i]=9;}if(a[i]<0){a[i]=0;}myEnc.write(0);newPosition=0;}
if(a[0]>1){a[0]=1;}if(a[0]==1&&a[1]>2){a[1]=2;}if(a[0]==1&&a[1]==2&&a[2]>5){a[2]=5;}
lcd.setCursor(0,0);lcd.print("F ");
if(i==0){if(millis()-times<500){lcd.print(a[0]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[0]);}
if(i==1){if(millis()-times<500){lcd.print(a[1]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[1]);}
lcd.print(".");
if(i==2){if(millis()-times<500){lcd.print(a[2]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[2]);}
if(i==3){if(millis()-times<500){lcd.print(a[3]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[3]);}
if(i==4){if(millis()-times<500){lcd.print(a[4]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[4]);}
lcd.print(".");
if(i==5){if(millis()-times<500){lcd.print(a[5]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[5]);}
if(i==6){if(millis()-times<500){lcd.print(a[6]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[6]);}
if(i==7){if(millis()-times<500){lcd.print(a[7]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[7]);}
lcd.print(",");
if(i==8){if(millis()-times<500){lcd.print(a[8]);}if(millis()-times>=500){lcd.print(" ");}if(millis()-times>1000){times=millis();}}else{lcd.print(a[8]);}
f=a[0]*pow(10,7)+a[1]*pow(10,6)+a[2]*pow(10,5)+a[3]*pow(10,4)+a[4]*pow(10,3)+a[5]*pow(10,2)+a[6]*10+a[7]+float(a[8]*0.1);
lcd.print("Hz");
if(on==0){f=0;}
if(w==1){ad();
EEPROM.update(0, a[0]);EEPROM.update(1, a[1]);EEPROM.update(2, a[2]);EEPROM.update(3, a[3]);EEPROM.update(9, form);
EEPROM.update(4, a[4]);EEPROM.update(5, a[5]);EEPROM.update(6, a[6]);EEPROM.update(7, a[7]);EEPROM.update(8, a[8]);
lcd.setCursor(11,1);
switch(form){
case 0: lcd.print("MEANDR");WriteAD9833(0x2028);break;
case 1: lcd.print("SINUS ");WriteAD9833(0x2000);break;
case 2: lcd.print("TRIAQ ");WriteAD9833(0x2002);break;
}
w=0;}
}// loop
// void WriteAD9833(uint16_t Data){
// SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV2, MSBFIRST, SPI_MODE2));
// digitalWrite(SS, LOW);
// delayMicroseconds(1);
// SPI.transfer16(Data);
// digitalWrite(SS, HIGH);
// SPI.endTransaction();
}
//void ad(){
// b = f*pow(2,28)/f25;
// if(b<16383){l_bit = b + 0x4000 ;h_bit = 0x4000;}
// else{h_bit = (b>>14) + 0x4000;l_bit = b - (h_bit<<14) + 0x4000;}
// SPI.begin();
//WriteAD9833(0x2100);// 0010 0001 0000 0000 - Reset + DB28
// WriteAD9833(l_bit); // 0100 0000 0000 0000 - Freq0 LSB
// WriteAD9833(h_bit); // 0100 0000 0000 0000 - Freq0 MSB
// WriteAD9833(0xC000);// 1100 0000 0000 0000 - Phase0
// WriteAD9833(0x2000);// 0010 0000 0000 0000 - Exit Reset
// }
//void to_Timer(){newPosition = myEnc.read()/4;}
Ваш проект попробую позже, надо схему перебирать. И я так понял частотомер меряет
сигнал генератора AD9833? И конечно тут информативней был бы 1604 или 2004 дисплей.