開発に使用したボードである。LCDは、20x4のI2C。DDSボートは、公開済みのAD9850 DUALシールドである。
回路図である。AD9850 Moduleを2枚使っているが、1枚のみでも動作する。ただ、1枚のみの使用ではキャリア発振(BFO機能)がない事を我慢しなければならない。
パラメータ
EEPにアプリケーション固有部を持たせる事で、汎用性を高めた。パラメータ変更は通常動作時に変更可能。基本的にSW長押しをした後、希望内容を選択し、SW長押しで復帰する様にしてある。
1.EEP初期化
何らかの理由で初期化が必要な場合、CH SWを3秒程長押しするとEEPの再初期化が出来る。(初めて使う場合は、プログラムで初期化しているので、必要ない。)
2.IFとVFO動作モード設定
IF画面。
ENT SWを3秒程長押しすると左画面が現れる。ロータリエンコーダで希望値に変更し、ENT SWを押す。(ENT SWを押すことで、EEPに書き込まれる。)
VFO設定画面。
VFO動作モードの画面が現れる。RIT SWを押しVFO動作モードを選択する。
RIT SWを押すとVFO設定モードが循環。
Roff -> TR -> R+IF -> TR+IF -> Roffと循環。
Roff TX=VFO、RX=0(出力停止)
TR TX=VFO、RX=VFO
R+IF TX=VFO、RX=VFO+IF
TR+IF TX=VFO+IF、RX=VFO+IF
ENT SWを押すとIF画面に戻る。ENT SWを3秒程長押し、復帰する。
3.BFO周波数設定
BFO設定画面。
MODE SWを3秒程長押しすると左画面が現れる。ロータリエンコーダで希望値に変更し、MODE SWを押す。(MODE SWを押すことで、EEPに書き込まれる。)
MODE SWを押すとMODE設定モードが循環。
LSB -> USB -> CW -> SUB -> LSBと循環。(予備用SUB。)
MODE SWを操作し、LSBにした後、MODE SWを3秒程長押し、復帰する。
Program
今回、表示のチラツキ、リアル表示など細かな所まで改造した為、冗長な所が有るかも知れない。Arduino IDE 1.6.Xでもコンパイルしたが、表示に関するBug回避が出来なかった。この為、IDE 1.0.6とヘッダーに書き入れた。
RITとSPLIT機能は、双方向動作が出来る様にした。例えば、RIT中周波数をSPLIT SWを押すことで、送信周波数のシフトにできる。当然、その逆も可能。
Sメータは、MARLANUが追加したもので、ピークホールドがあり、優れもの。
/////////////////////////////////////////////////////////////////////
// Copyright©2014-2016.JA2GQP.All rights reserved.
// Ver 1.01
// AD9850 DUAL DDS VFO(Arduino IDE 1.0.6)
//
// 2016/5/2
// JA2GQP
//--------------------------------------------------------------------
// Function
// 1.RIT Operation(-50kHZ to 50kHZ)
// 2.STEP(1M,100k,10k,1k,100,10)
// 3.Memory Operation is Push ENT
// 4.Protection Operation At The Time Of Transmission
// 5.Channel Memory Ch0-ch9(10ch)
// 6.Split Operation(-50kHZ to 50kHZ)
// 7.Parameter(BFO,IF,IF mode)
//--------------------------------------------------------------------
// Library
// http://www.buxtronix...e-properly.html
//
//--------------------------------------------------------------------
// Additional S-meter function
// Editat de MARLANU, 08 februarie 2015 - 12:36
//
//--------------------------------------------------------------------
// Bug
// 2016/7/6 IF mode bug fixed.
//////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <rotary.h>
#include <EEPROM.h>
//---------- LCD Pin Assign -------------------------------
LiquidCrystal_I2C lcd(0x27,20,4); // address 0x27,LCD 20 x 4
//---------- Define Constant Value -----------------------
////////////////////////////////
// I/O assign
////////////////////////////////
const byte ENC_A = 2; // Encorder A
const byte ENC_B = 3; // Encoeder B
const byte SW_STEP = 4; // STEP SW
const byte SW_RIT = 5; // RIT SW
const byte SW_SPLIT = 6; // SPLIT SW
const byte C_DATA = 7; // DIO7
const byte C_UD = 8; // DIO8
const byte C_CLK = 9; // DIO9
const byte V_DATA = 10; // DIO10
const byte V_UD = 11; // DIO11
const byte V_CLK = 12; // DIO12
const byte SW_TX = 13; // TX SW
const byte SW_ENT = 15; // ENT SW
const byte SW_MODE = 16; // MODE SW
const byte SW_CH = 17; // CH SW
////////////////////////////////
// default value
////////////////////////////////
const long DEF_IF = 10700000L; // IF
const long DEF_LSB = 10701500L; // Career LSB
const long DEF_USB = 10698500L; // USB
const long DEF_CW = 10699400L; // CW
const long DEF_SUB = 0L; // SUB
const long DEF_VFO = 3; // Vfo Mode(TR+IF)
const long DEF_FRQ = 7050000L; // Init Frequency
const long DEF_STP = 1000L; // Init STEP
////////////////////////////////
// Limited range
////////////////////////////////
const long LW_FRQ = 0L; // Frequency Lower Limit
const long HI_FRQ = 30000000L; // Upper Limit
const long LW_VFO80 = 3500000L; // 3.5MHz Lower Limit
const long HI_VFO80 = 3575000L; // Upper Limit
const long LW_VFO40 = 7000000L; // 7MHz Lower Limit
const long HI_VFO40 = 7200000L; // Upper Limit
const long LW_VFO20 = 14000000L; // 14MHz Lower Limit
const long HI_VFO20 = 14350000L; // Upper Limit
const long LW_VFO15 = 21000000L; // 21MHz Lower Limit
const long HI_VFO15 = 21450000L; // Upper Limit
const long LW_VFO10 = 28000000L; // 28MHz Lower Limit
const long HI_VFO10 = 29700000L; // Upper Limit
const long LW_RIT = -50000L; // RIT Lower Limit
const long HI_RIT = 50000L; // RIT Upper Limit
////////////////////////////////
// DDS parameter
////////////////////////////////
const unsigned long DDS_CLK = 125000000L; // AD9850 Clock
const unsigned long TWO_E32 = 4294967295L;// 2^32
const byte DDS_CMD = B00000000; // AD9850 Command
////////////////////////////////
// etc
////////////////////////////////
const byte Max_Chn = 10; // Max Channel(10ch)
const byte Int_End = 73; // Initial end code
const char *CALL = " JA2GQP "; // Display Call sign
const byte IN_LEFT = A0; // analog input for left channel
const byte T_REFRESH = 100; // msec bar refresh rate
const byte T_PEAKHOLD = 3*T_REFRESH; // msec peak hold time before return
//---------- EEPROM Memory Address -----------------------
const byte Frq_Eep = 0x00; // Frequency(4byte*10)
const byte Stp_Eep = 0x30; // STEP(4byte*10)
const byte Mode_Eep = 0x60; // Mode(1byte*10)
const byte Care_Eep = 0x70; // DDS Career(4byte* 4)
const byte If_Eep = 0x80; // IF(4byte*1)
const byte Chn_Eep = 0x90; // Channel(1byte*1)
const byte Vfo_Eep = 0x92; // Vfo mode(1byte*1)
const byte Eep_Int = 0x9e; // Eep Init(1byte*1)
//---------- Encorder Pin Assign(INT) ---------------------
Rotary r = Rotary(ENC_A,ENC_B); // 2 = ENC_A,3 = ENC_B
//---------- Memory Assign --------------------------------
long Vfo_Dat; // VFO Data
long Vfo_Datb; // VFO Old Data
long Vfo_Save; // VFO Backup Data
long RX_Dat; // RX DDS Out Data
long TX_Dat; // TX DDS Out Data
long Car_Dat; // Careea DDS Out Data
long Rit_Dat; // RIT Data
long Rit_Datb; // RIT Data Old
long Enc_Stp; // STEP
long Lng_Wk1; // Long Work1
long Lng_Wk2; // Long Work2
long Vfo_If; // VFO IF
char *Lcd_Dat = " "; // Lcd Display Buffer
byte Byt_Chn; // Channel SW
byte Byt_Chnb; // Channel SW Old
byte Flg_Rit; // RIT Flag
byte Flg_Ritb; // RIT Flag Old
byte Flg_Tx; // TX Flag
byte Flg_Spl; // SPLIT Flag
byte Flg_Mode; // Mode Flag
byte Byt_Mode; // Mode SW
char Byt_Modeb; // Mode SW Old
byte Flg_LSB; // LSB Flag
byte Flg_USB; // USB Flag
byte Flg_CW; // CW Flag
byte Flg_SUB; // SUB Flag
byte Flg_Over; // Over Flag
byte Flg_Ent; // ENT Flag
byte Byt_Ent; // ENT Mode
byte Flg_If; // IF Flag
byte Flg_Vfo; // DDS Flag
byte Byt_Vfo; // VFO Mode
byte fill[6]={ 0x20,0x00,0x01,0x02,0x03,0xFF }; // character used to fill (0=empty 5=full)
byte peak[7]={ 0x20,0x00,0x04,0x05,0x06,0x07,0x20 }; // character used to peak indicator
int lmax[2]; // level max memory
int dly[2]; // delay & speed for peak return
////////////////////////////////
// Special character definition
////////////////////////////////
byte block[8][8]=
{
{ 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 }, // define character for fill the bar
{ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 },
{ 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C },
{ 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E },
{ 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08 }, // define character for peak level
{ 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 },
{ 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 },
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },
};
//---------- Initialization Program ----------------------
void setup(){
lcd.init(); // initialize the lcd
lcd.backlight();
for( int i=0 ; i<8 ; i++ )
lcd.createChar( i,block[i] );
pinMode(SW_STEP,INPUT_PULLUP);
pinMode(SW_ENT,INPUT_PULLUP);
pinMode(SW_RIT,INPUT_PULLUP);
pinMode(SW_SPLIT,INPUT_PULLUP);
pinMode(SW_TX,INPUT_PULLUP);
pinMode(SW_CH,INPUT_PULLUP);
pinMode(SW_MODE,INPUT_PULLUP);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei(); // INT Enable
pinMode(C_UD,OUTPUT);
pinMode(C_CLK,OUTPUT);
pinMode(C_DATA,OUTPUT);
pinMode(V_UD,OUTPUT);
pinMode(V_CLK,OUTPUT);
pinMode(V_DATA,OUTPUT);
Flg_Tx = 0;
Flg_Rit = 0;
Flg_Spl = 0;
lcd.clear();
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;
Car_Dat = Fnc_Eep_Lod4(Care_Eep+Byt_Mode*4);
Fnc_Eep_Rd(); // EEPROM Read
}
//---------- Main program ---------------------------------
void loop() {
// sqrt to have non linear scale (better was log)
int anL = map( sqrt( analogRead( IN_LEFT )*20 ),0,128,0,80 );
bar( 2,anL ); // set the cursor 0,2
lcd.setCursor(0, 3);
delay(80);
lcd.print("S1_3_5_7_9_+10_+40db"); // Print a message to the LCD.
if(Flg_Tx == 0){ // Tx off?
if(digitalRead(SW_STEP) == LOW) // STEP Sw On?
Fnc_Stp();
if(digitalRead(SW_ENT) == LOW) // ENT SW On?
Fnc_Ent();
if(Flg_Mode == 0){
if(digitalRead(SW_RIT) == LOW) // RIT Sw On?
Fnc_Rit();
if(Flg_Vfo == 0){
if(digitalRead(SW_SPLIT) == LOW) // SPLIT Sw On?
Fnc_Spl();
if((digitalRead(SW_CH) == LOW)) // CH SW On?
Fnc_Chsw();
}
}
if((digitalRead(SW_MODE) == LOW)) // MODE SW On?
Fnc_Mode();
if(Byt_Chnb != Byt_Chn){ // CH SW OLD != NEW?
Fnc_Eep_Wt(Byt_Chnb);
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd();
Flg_Rit = 0;
Flg_Spl = 0;
}
if(Flg_Ent == 1) // ENT proc.?
Fnc_Prm();
}
if(digitalRead(SW_TX) == LOW) // Tx On?
Flg_Tx = 1;
else
Flg_Tx = 0;
if(Flg_Mode == 1)
Fnc_Care();
else{
Fnc_Band(Vfo_Dat+Rit_Dat); // Range check
Fnc_If(Byt_Vfo);
if(Flg_Tx == 0)
Fnc_Dds(RX_Dat,V_DATA,V_CLK,V_UD); // AD9850 DDS RX set
else
if(Flg_Over == 0) // Frequency not range over?
Fnc_Dds(TX_Dat,V_DATA,V_CLK,V_UD); // AD9850 DDS TX set
else
Fnc_Dds(0L,V_DATA,V_CLK,V_UD); // DDS 0Hz
}
Fnc_Dds(Car_Dat,C_DATA,C_CLK,C_UD); // Career DDS set
Fnc_Lcd(); // LCD Display
}
//---------- Encorder procedure(INT) ----------------------
ISR(PCINT2_vect) {
unsigned char result = r.process();
if(Flg_Tx == 0){
if(result) {
if(result == DIR_CW){
Lng_Wk1 = Vfo_Dat + Enc_Stp;
Lng_Wk2 = Rit_Dat + Enc_Stp;
}
else{
Lng_Wk1 = Vfo_Dat - Enc_Stp;
Lng_Wk2 = Rit_Dat - Enc_Stp;
}
if((Flg_Rit == 1) || (Flg_Spl == 1))
Rit_Dat = Lng_Wk2;
else{
Vfo_Dat = Lng_Wk1;
Rit_Dat = 0;
}
Vfo_Dat = constrain(Vfo_Dat,LW_FRQ,HI_FRQ); // VFO range check
Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT); // RIT range check
}
}
}
//---------- Function DDS set -----------------------------
void Fnc_Dds(double frquency,byte dat,byte clk,byte ud){
unsigned long wrk = frquency * TWO_E32 / DDS_CLK;
digitalWrite(ud,LOW);
shiftOut(dat,clk,LSBFIRST,wrk);
shiftOut(dat,clk,LSBFIRST,(wrk >> 8));
shiftOut(dat,clk,LSBFIRST,(wrk >> 16));
shiftOut(dat,clk,LSBFIRST,(wrk >> 24));
shiftOut(dat,clk,LSBFIRST,DDS_CMD); // AD9850 command
digitalWrite(ud,HIGH);
}
//---------- LCD Bar Display PROC. ------------------------
void bar(int row,int lev){
lcd.setCursor( 0,row );
lcd.write( row ? 'R' : 'L' );
for( int i=1 ; i<20 ; i++ ){
int f=constrain( lev -i*5,0,5 );
int p=constrain( lmax[row]-i*5,0,6 );
if( f )
lcd.write( fill[ f ] );
else
lcd.write( peak[ p ] );
}
if( lev>lmax[row] ){
lmax[row] = lev;
dly[row] = -(T_PEAKHOLD)/T_REFRESH; // Starting delay value. Negative=peak don't move
}
else{
if( dly[row]>0 )
lmax[row] -= dly[row];
if( lmax[row]<0 )
lmax[row]=0;
else
dly[row]++;
}
}
//---------- Function Encorder STEP -----------------------
void Fnc_Stp(){
if(Enc_Stp == 10) // Step = 10Hz ?
Enc_Stp = 1000000; // Yes,1Mhz set
else
Enc_Stp = Enc_Stp / 10; // Step down 1 digit
Fnc_Step_Disp();
while(digitalRead(SW_STEP) == LOW)
;
}
//---------- Function STEP Display ------------------------
void Fnc_Step_Disp(){
lcd.setCursor(0,1);
switch(Enc_Stp){
case 10:
lcd.print("10 ");
break;
case 100:
lcd.print("100 ");
break;
case 1000:
lcd.print("1k ");
break;
case 10000:
lcd.print("10k ");
break;
case 100000:
lcd.print("100k");
break;
case 1000000:
lcd.print("1M ");
break;
default:
lcd.print("1k ");
Enc_Stp = 1000;
break;
}
}
//---------- Function String Dot Edit ---------------------
char *Fnc_Dot_Edit(char *str,long n){
int i = 0; // Write the number
char *p = str;
unsigned long u = abs(n);
do{
*p++ = "0123456789"[u % 10];
u = u / 10;
i++;
if((0 != u) && (0 == (i % 3)))
*p++ = ',';
}
while( 0 != u )
;
if ( n < 0 )
*p++ = '-';
*p = '\0';
Fnc_Revr( str );
return str;
}
//---------- Function String Reverse ----------------------
void Fnc_Revr(char *str){
int i,n;
char c;
n=strlen(str);
for(i = 0;i < n / 2;i++){
c=str[i];
str[i]=str[n - i - 1];
str[n - i - 1]=c;
}
}
//---------- 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 LCD Display -------------------------
void Fnc_Lcd(){
lcd.setCursor(0,0);
if(Flg_Tx == 1)
lcd.write('T');
else if(Flg_Mode == 1)
lcd.write('C');
else if(Flg_Ent == 1)
lcd.write('P');
else
lcd.print(Byt_Chn);
Fnc_Step_Disp();
if(Flg_Over == 0){
lcd.setCursor(16,1);
lcd.print(" ");
}
if(Flg_Rit == 1){ // Rit display
lcd.setCursor(5,1);
if(Rit_Dat != Rit_Datb){
lcd.print("R ");
Rit_Datb = Rit_Dat;
}
lcd.setCursor(6,1);
if(Rit_Dat >=0)
lcd.write('+');
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.print(Lcd_Dat);
lcd.print("Hz");
}
if(Flg_Spl == 1){ // Split display
lcd.setCursor(5,1);
if(Rit_Dat != Rit_Datb){
lcd.print("T ");
Rit_Datb = Rit_Dat;
}
lcd.setCursor(6,1);
if(Rit_Dat >=0)
lcd.write('+');
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.print(Lcd_Dat);
lcd.print("Hz");
}
if((Flg_Rit == 0) && (Flg_Spl == 0)){
Fnc_Fdsp(Vfo_Dat);
Fnc_Mdisp();
if((Flg_Mode == 0) && (Flg_Ent == 0)){
lcd.setCursor(5,1);
lcd.print(CALL);
}
}
}
//---------- Function Frequency Display -------------------
void Fnc_Fdsp(long f_disp){
Fnc_Dot_Edit(Lcd_Dat,f_disp);
lcd.setCursor(1,0);
if(f_disp != Vfo_Datb){
lcd.write(':');
lcd.print(" ");
Vfo_Datb = f_disp;
}
lcd.setCursor(3,0);
lcd.print(Lcd_Dat);
lcd.print("Hz");
}
//---------- Function Rit ---------------------------------
void Fnc_Rit(){
if(Flg_Vfo == 0){
if(Flg_Rit == 0){
if(Flg_Spl == 1)
Flg_Spl = 0;
Flg_Rit = 1;
lcd.setCursor(5,1);
lcd.print("R ");
if(Rit_Dat >=0){
lcd.setCursor(6,1);
lcd.write('+');
lcd.write('0');
lcd.print("Hz");
}
}
else{
lcd.setCursor(5,1);
lcd.print(CALL);
Flg_Rit = 0;
Rit_Dat = 0;
}
}
else
Byt_Vfo++;
while(digitalRead(SW_RIT) == LOW)
;
}
//---------- Function Channel SW Check --------------------
void Fnc_Chsw(){
byte cnt = 0;
Byt_Chn++;
while(digitalRead(SW_CH) == LOW){
delay(500);
cnt++;
if(6 <= cnt){ // Eep Initial start(3sec)?
Fnc_Eep_Int();
Byt_Chn = EEPROM.read(Chn_Eep); // Channel
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd(); // EEPROM Read
lcd.setCursor(0,0); // LCD display
lcd.print(Byt_Chn);
Fnc_Fdsp(Vfo_Dat);
lcd.setCursor(5,1);
lcd.print("Init End ");
}
}
}
//---------- Function Eeprom Initialization -----------------
void Fnc_Eep_Int(){
int i;
for (i=0;i<160;i++) // 0 clear(160byte)
EEPROM.write(i, 0);
for(i=0;i<Max_Chn;i++){
Fnc_Eep_Sav4(DEF_FRQ,Frq_Eep+i*4); // Frequency(7.05MHz)
Fnc_Eep_Sav4(DEF_STP,Stp_Eep+i*4); // Step(1kHz)
}
Fnc_Eep_Sav4(DEF_IF,If_Eep); // IF(10.7MHz)
Fnc_Eep_Sav4(DEF_LSB,Care_Eep+0); // Career LSB
Fnc_Eep_Sav4(DEF_USB,Care_Eep+4); // USB
Fnc_Eep_Sav4(DEF_CW,Care_Eep+8); // CW
Fnc_Eep_Sav4(DEF_SUB,Care_Eep+12); // SUB
EEPROM.write(Vfo_Eep,DEF_VFO); // Vfo 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))
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep+Byt_Chn*4);
else{
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep+0*4);
Byt_Chn = 0;
}
if((0 <= Byt_Chn) && (Byt_Chn < Max_Chn))
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep+Byt_Chn*4);
else
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep+0*4);
Vfo_If = Fnc_Eep_Lod4(If_Eep); // 2016/7/6
Byt_Mode = EEPROM.read(Mode_Eep+Byt_Chn);
Byt_Vfo = EEPROM.read(Vfo_Eep);
}
//---------- Function EEPROM Write -----------------------
void Fnc_Eep_Wt(byte chn){
if((0 <= chn) && (chn < Max_Chn)){
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep+chn*4);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep+chn*4);
}
EEPROM.write(Chn_Eep,Byt_Chn);
EEPROM.write(Mode_Eep+chn,Byt_Mode);
}
//---------- Function Split ------------------------------
void Fnc_Spl(){
if(Flg_Spl == 0){
if(Flg_Rit == 1)
Flg_Rit = 0;
Flg_Spl = 1;
lcd.setCursor(5,1);
lcd.print("T ");
if(Rit_Dat >=0){
lcd.setCursor(6,1);
lcd.write('+');
lcd.write('0');
lcd.print("Hz");
}
}
else{
lcd.setCursor(5,1);
lcd.print(CALL);
Flg_Spl = 0;
Rit_Dat = 0;
}
while(digitalRead(SW_SPLIT) == LOW)
;
}
//---------- Function Mode -------------------------------
void Fnc_Mode(){
byte cnt = 0;
Byt_Mode++;
if(Flg_Mode == 0){
while(digitalRead(SW_MODE) == LOW){
delay(500);
cnt++;
if(6 <= cnt){ // Change MODE(3sec)
lcd.setCursor(0,0);
lcd.write('C');
Byt_Mode = 0; // LSB set
Flg_LSB = 0;
Flg_Spl = 0;
Flg_Rit = 0;
Vfo_Save = Vfo_Dat;
Car_Dat = Fnc_Eep_Lod4(Care_Eep+0);
Fnc_Fdsp(Car_Dat);
lcd.setCursor(5,1);
lcd.print("Career DDS ");
Flg_Mode = 1;
}
}
}
else{
while(digitalRead(SW_MODE) == LOW){
delay(500);
cnt++;
if((6 <= cnt) && (Byt_Mode == 1)){ // Exit MODE(3sec) and LSB
Vfo_Dat = Vfo_Save;
Fnc_Fdsp(Vfo_Dat);
lcd.setCursor(5,1);
lcd.print(CALL);
if(Flg_Over == 1){
lcd.setCursor(16,1);
lcd.print("Over");
}
Flg_Mode = 0;
Byt_Mode = 0; // LSB set
lcd.setCursor(0,0);
lcd.print(Byt_Chn);
}
}
}
}
//---------- Function Career PROC ------------------------
void Fnc_Care(){
switch(Byt_Mode){
case 0: // LSB
if(Flg_LSB == 0){
Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+0);
Flg_LSB = 1;
}
break;
case 1: // USB
if(Flg_LSB == 1){
Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+0);
Flg_LSB = 0;
}
if(Flg_USB == 0){
Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+4);
Flg_USB = 1;
}
break;
case 2: // CW
if(Flg_USB == 1){
Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+4);
Flg_USB = 0;
}
if(Flg_CW == 0){
Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+8);
Flg_CW = 1;
}
break;
case 3: // SUB
if(Flg_CW == 1){
Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+8);
Flg_CW = 0;
}
if(Flg_SUB == 0){
Vfo_Dat = Fnc_Eep_Lod4(Care_Eep+12);
Flg_SUB = 1;
}
break;
default:
if(Flg_SUB == 1){
Fnc_Eep_Sav4(Vfo_Dat,Care_Eep+12);
Flg_SUB = 0;
}
Byt_Mode = 0;
break;
}
Car_Dat = Vfo_Dat;
}
//---------- Function Mode Display -----------------------
void Fnc_Mdisp(){
lcd.setCursor(17,0);
switch(Byt_Mode){
case 0: // LSB
lcd.print("LSB");
break;
case 1: // USB
lcd.print("USB");
break;
case 2: // CW
lcd.print("CW ");
break;
case 3: // SUB
lcd.print("SUB");
break;
default:
Byt_Mode = 0;
lcd.print("LSB");
break;
}
Car_Dat = Fnc_Eep_Lod4(Care_Eep+Byt_Mode*4);
EEPROM.write(Mode_Eep+Byt_Chn,Byt_Mode);
}
//---------- Function Band -------------------------------
void Fnc_Band(long vfo){
if((Flg_Mode == 0) && (Flg_Ent == 0)){
if((vfo >= LW_VFO80) && (vfo <= HI_VFO80))
Flg_Over = 0;
else if((vfo >= LW_VFO40) && (vfo <= HI_VFO40))
Flg_Over = 0;
else if((vfo >= LW_VFO20) && (vfo <= HI_VFO20))
Flg_Over = 0;
else if((vfo >= LW_VFO15) && (vfo <= HI_VFO15))
Flg_Over = 0;
else if((vfo >= LW_VFO10) && (vfo <= HI_VFO10))
Flg_Over = 0;
else{
lcd.setCursor(16,1);
lcd.print("Over");
Flg_Over = 1;
}
}
else
Flg_Over = 0;
}
//---------- Function ENT --------------------------------
void Fnc_Ent(){
byte cnt = 0;
if(Flg_Ent == 0){
Fnc_Eep_Wt(Byt_Chn);
while(digitalRead(SW_ENT) == LOW){
delay(500);
cnt++;
if(6 <= cnt){ // Parameter change mode(3sec)
lcd.setCursor(0,0);
lcd.print("P");
Flg_Ent = 1;
Flg_Rit = 0;
Flg_Spl = 0;
Byt_Ent = 0;
if(Flg_If == 0){
Vfo_Save = Vfo_Dat;
Vfo_Dat = Fnc_Eep_Lod4(If_Eep);
Flg_If = 1;
}
Fnc_Fdsp(Vfo_Dat);
lcd.setCursor(5,1);
lcd.print("IF ");
}
}
}
else{
while(digitalRead(SW_ENT) == LOW){
delay(500);
cnt++;
if(6 <= cnt){ // Return Parameter cahne mode(3sec)
lcd.setCursor(0,0);
lcd.print(Byt_Chn);
Flg_Ent = 0;
Flg_Vfo = 0;
Flg_If = 0;
Vfo_Dat = Vfo_Save;
Fnc_Fdsp(Vfo_Dat);
lcd.setCursor(5,1);
lcd.print(CALL);
EEPROM.write(Vfo_Eep,Byt_Vfo);
}
else
Byt_Ent++;
}
}
}
//---------- Function Prameter PROC ----------------------
void Fnc_Prm(){
lcd.setCursor(5,1);
switch(Byt_Ent){
case 0: // IF Set
if(Flg_If == 0){
Vfo_Dat = Fnc_Eep_Lod4(If_Eep);
Flg_If = 1;
}
lcd.setCursor(5,1);
lcd.print("IF ");
break;
case 1: // VFO Mode Set
if(Flg_If == 1){
Fnc_Eep_Sav4(Vfo_Dat,If_Eep);
Vfo_If = Vfo_Dat;
Flg_If = 0;
}
if(Flg_Vfo == 0){
Byt_Vfo = EEPROM.read(Vfo_Eep); // Vfo Mode data
if(Byt_Vfo < 0)
Byt_Vfo = 0;
Flg_Vfo = 1;
}
lcd.setCursor(10,1);
switch(Byt_Vfo){
case 0:
lcd.print("Roff "); // TX=VFO RX=0
break;
case 1:
lcd.print("TR "); // TX=VFO RX=VFO
break;
case 2:
lcd.print("R+IF "); // TX=VFO RX=VFO+IF
break;
case 3:
lcd.print("TR+IF "); // TX=VFO+IF RX=VFO+IF
break;
default:
Byt_Vfo = 0;
lcd.print("Roff ");
break;
}
lcd.setCursor(5,1);
lcd.print("VFO ");
break;
default:
if(Flg_Vfo == 1){
EEPROM.write(Vfo_Eep,Byt_Vfo);
Flg_Vfo = 0;
}
lcd.setCursor(5,1);
lcd.print("IF ");
Byt_Ent = 0;
break;
}
}
//---------- Function IF Proc. ---------------------------
void Fnc_If(byte if_mode){
switch(if_mode){
case 0: // Roff
RX_Dat = 0L; // RX = off
TX_Dat = Vfo_Dat; // TX = VFO
break;
case 1: // TR
RX_Dat = Vfo_Dat; // RX = VFO
TX_Dat = Vfo_Dat; // TX = VFO
break;
case 2: // R+IF
RX_Dat = Vfo_Dat + Vfo_If; // RX = VFO + IF
TX_Dat = Vfo_Dat; // TX = VFO
break;
case 3: // TR+IF
RX_Dat = Vfo_Dat + Vfo_If; // RX = VFO + IF
TX_Dat = Vfo_Dat + Vfo_If; // TX = VFO + IF
break;
default:
RX_Dat = 0L; // RX = off
TX_Dat = Vfo_Dat; // TX = VFO
break;
}
if((RX_Dat != 0) && (Flg_Rit == 1))
RX_Dat = RX_Dat + Rit_Dat;
if(Flg_Spl == 1)
TX_Dat = TX_Dat + Rit_Dat;
}
4 件のコメント:
EEPROMからIF周波数を読み取る所に不具合が有った為、改修した。
古い記事に質問することをお許しください。
回路図を見るとAD9850 moduleのD2がGNDに落としてありますが、スケッチを読み間違えているのかも知れませんが、そのpinをGNDに落とす理由が分かりません。
恐れ入りますがお教えいただけると助かります。
AD9850をシリアルモードで使う為の設定です。
詳しくはAD9850データシートのp12を見てください。
ありがとうございます
この質問をした後でデータシートを見ていたら、シリアル・パラレルデータ転送の件が書かれていて分かりました。
調べる前に質問をしてしまい申し訳ありませんでした。
コメントを投稿