真空管電源用のFETリップルフィルタである。50年程前、LCRにる電源フィルタであったが、今では半導体を使ったリップルフィルタも使われている。現在、主にオーディオAMPの電源部として使われているが、無線機の電源部として使う予定。FETは、手持ちの中から、VDSSの高いものを選んだ。チョークレス構成の為、重量低減とローコスト化を狙える。ただ、トランスと組み合わせた確認試験を行ってないので、性能は定かでない。
回路図である。回路図中の電圧は、無負荷時の計算値。
PCBサイズ 83×58
抵抗は、無理すれば、3Wまでなら実装可能。
無線機の製作記録の全てを公開してます。 https://sites.google.com/view/ja2gqpから必要なファイルをダウンロードできます。 このBlogは、詳細な説明は一切行っておらず、ある程度のスキルが要求されます。 質問に応じますが、カスタマイズは対応しません。尚、コメントは誰でも出来る様に変更しました。
2015年5月25日月曜日
2015年4月16日木曜日
秋月電子DDS(TC170C030) VFO
長い間眠っていた秋月電子のDDSキットを組立て、DDS VFOを作った。今回も、I2CコントロールのLCDを使って、省配線。Aruduinoが安価(中華サイトで$4位)なので、テストするのに助かる。公開済のArduino版ファームウェアを移植したので、機能は問題ない筈だ。また、秋月DDSをVFOとして使う場合、最大出力周波数に注意しなければならない。このキットの場合、データシートから約16MHzである。
回路図である。LPFはシュミレーションにより、カットオフ16MHzで設計。シュミレーションの様子は、Twitterに書き込んである。
//////////////////////////////////////////////////////////////////////
// TC170C030AF001 DDS VFO Premixed type program ver.1.0
//
// Copyright(C)2014-2015.JA2GQP.All rights reserved.
//
// 7.000MHz to 7.200MHz Limitted.
// (Target frequency = IF frquency + frequency)
// 2015/04/14
// JA2GQP
//--------------------------------------------------------------------
// Function
// 1.RIT Operation(-50kHZ to 50kHZ)
// 2.STEP(100k,10k,1k,100,10)
// 3.Memory Operation is Push RIT
// (Frequency and Step)
// 4.Protection Operation At The Time Of Transmission
// 5.Channel Memory.Main Channel(Ch0) + 3 Channel(Ch1,Ch2,Ch3)
// 6.Split Operation(7.00MHz to 7.20MHz Limited!)
//
//////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <rotary.h>
#include <EEPROM.h>
//---------- LCD Pin Assign ------------------
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for
// a 16 chars and 2 line display
//---------- Define Constant Value ----------
const byte ENC_A = 2; // Encorder A
const byte ENC_B = 3; // B
const byte DDT = 4; // TC170C030AF001 DATA
const byte DCK = 5; // SCK
const byte DST = 6; // STB
const byte SW_STEP = 7; // STEP Sw
const byte SW_RIT = 8; // RIT Sw
const byte SW_SPLIT = 9; // SPLIT Sw
const byte SW_CH1 = 10; // Channel 1
const byte SW_CH2 = 11; // 2
const byte SW_CH3 = 12; // 3
const byte SW_TX = 13; // TX Sw
const long IF_FRQ = 5001500L; // IF Frequency
const long LW_FRQ = 7000000L; // Lower Limit
const long HI_FRQ = 7200000L; // Upper Limit
const long DEF_FRQ = 7050000L; // Init Frequency
const long DEF_STP = 1000L; // Init STEP
const long LW_RIT = -50000L; // RIT Lower Limit
const long HI_RIT = 50000L; // Upper Limit
const long LW_VFO = IF_FRQ + LW_FRQ; // Vfo Lower Limit
const long HI_VFO = IF_FRQ + HI_FRQ; // Upper Limit
const long DEF_VFO = IF_FRQ + DEF_FRQ; // Vfo Default Frequency
const unsigned long DDS_CLK = 67108864L; // TC170C030AF001 Clock 67.108864Mhz
const unsigned long TWO_E26 = 67108864L; // 2^26
const byte DDS_CMD1 = B00110011; // CM3=1,CM2=1,CM1=0,CM0=0
// A2=1,A1=1
const byte DDS_CMD2 = B00000001; // A0=1
//---------- EEPROM Memory Address ----------
const byte Frq_Eep0 = 0x00; // Frequency Ch0
const byte Frq_Eep1 = 0x04; // Ch1
const byte Frq_Eep2 = 0x08; // Ch2
const byte Frq_Eep3 = 0x0c; // Ch3
const byte Stp_Eep0 = 0x10; // STEP Ch0
const byte Stp_Eep1 = 0x14; // Ch1
const byte Stp_Eep2 = 0x18; // Ch2
const byte Stp_Eep3 = 0x1c; // Ch3
//---------- Encorder Pin Assign(INT) --------
Rotary r = Rotary(ENC_A,ENC_B); // 2 = ENC_A,3 = ENC_B
//---------- Memory Assign -------------------
long Vfo_Dat = 0; // VFO Data
long Dds_Dat = 0; // DDS Data
long Rit_Dat = 0; // RIT Data
long Rit_Datb = 0; // RIT Data Old
long Enc_Stp = 0; // STEP
long Lng_Wk1 = 0; // Long Work1
long Lng_Wk2 = 0; // Long Work2
char *Lcd_Dat = " "; // Lcd Display Buffer
byte Byt_Chn = 0; // Channel SW
byte Byt_Chnb = 0; // Channel SW Old
byte Flg_Rit = 0; // RIT Flag
byte Flg_Ritb = 0; // RIT Flag Old
byte Flg_Tx = 0; // TX Flag
byte Flg_Spl = 0; // SPLIT Flag
//---------- Initialization Program ---------------
void setup(){
lcd.init(); // initialize the lcd
lcd.backlight(); // LCD backlight on
pinMode(SW_STEP,INPUT_PULLUP);
pinMode(SW_RIT,INPUT_PULLUP);
pinMode(SW_SPLIT,INPUT_PULLUP);
pinMode(SW_TX,INPUT_PULLUP);
pinMode(SW_CH1,INPUT_PULLUP);
pinMode(SW_CH2,INPUT_PULLUP);
pinMode(SW_CH3,INPUT_PULLUP);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei(); // INT Enable
pinMode(DST,OUTPUT);
pinMode(DCK,OUTPUT);
pinMode(DDT,OUTPUT);
Flg_Tx = 0;
Flg_Rit = 0;
Flg_Spl = 0;
lcd.clear();
Fnc_Chsw(); // Channel Sw Read
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd(); // EEPROM Read
}
//---------- Main program ---------------
void loop() {
if(Flg_Tx == 0){ // Tx off?
if(digitalRead(SW_STEP) == LOW){ // STEP Sw On?
Fnc_Stp(); // Yes,STEP proc.
}
if(digitalRead(SW_RIT) == LOW){ // RIT Sw On?
Fnc_Rit(); // Yes,RIT proc.
}
if(digitalRead(SW_SPLIT) == LOW){ // SPLIT Sw On?
Fnc_Spl(); // Yes,SPLIT proc.
}
Fnc_Chsw(); // Channel Sw read
if(Byt_Chnb != Byt_Chn){ // Channnel SW Chenge?
if(Byt_Chnb == 0){ // Channnel 0?
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0); // Yes,Vfo_Dat Save
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0); // Enc_Step Save
Flg_Ritb = Flg_Rit;
Rit_Datb = Rit_Dat;
Flg_Rit = 0;
Flg_Spl = 0;
Rit_Dat = 0;
}
if(Byt_Chnb != 0){ // Other(Ch1-Ch3) Channnel?
Flg_Rit = 0;
Flg_Spl = 0;
if((Byt_Chn == 0) && (Flg_Ritb == 1)){
Flg_Rit = 1;
Rit_Dat = Rit_Datb;
}
}
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd();
}
}
if(digitalRead(SW_TX) == LOW){ // Tx On?
Flg_Tx = 1; // Yes,Flg_Tx Set
}
else{
Flg_Tx = 0; // No,Flg_Tx Reset
}
if(Flg_Rit == 1){ // RIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
if(Flg_Tx == 1){ // Tx?
if(Flg_Spl == 1){ // SPLIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
}
Fnc_Dds(Dds_Dat); // TC170C030AF001 DDS Out
Fnc_Lcd(); // LCD Display
delay(100);
}
//---------- 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_VFO,HI_VFO);
if(Flg_Spl == 1){
Rit_Dat = constrain(Rit_Dat,(LW_VFO - Vfo_Dat),(HI_VFO - Vfo_Dat));
}
else{
Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);
}
}
}
}
//---------- Function DDS set ---------------
void Fnc_Dds(double frquency){
unsigned long wrk = frquency * TWO_E26 / DDS_CLK;
unsigned int wrk1,wrk2;
wrk1 = wrk >> 10;
wrk2 = wrk << 6;
wrk2 = wrk2 & 0xffc0 | DDS_CMD1;
digitalWrite(DDT,DDS_CMD2 & 0x01);
digitalWrite(DCK,HIGH);
digitalWrite(DCK,LOW);
shiftOut(DDT,DCK,LSBFIRST,wrk2);
shiftOut(DDT,DCK,LSBFIRST,(wrk2 >> 8));
shiftOut(DDT,DCK,LSBFIRST,wrk1);
shiftOut(DDT,DCK,LSBFIRST,(wrk1 >> 8));
digitalWrite(DST,LOW);
digitalWrite(DST,HIGH);
}
//---------- Function Encorder STEP ---------
void Fnc_Stp(){
if(Enc_Stp == 10){ // Step = 10Hz ?
Enc_Stp = 100000; // Yes,100khz set
}
else{
Enc_Stp = Enc_Stp / 10; // Step down 1 digit
}
delay(100);
Fnc_Step_Disp();
Fnc_Lcd();
while(digitalRead(SW_STEP) == LOW)
;
delay(250);
}
//---------- 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;
}
}
//---------- 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 2byte ---------
void Fnc_Eep_Sav2(unsigned int value,int address){
address += 1;
for(int i = 0;i < 2;i++){
byte toSave = value & 0xFF;
if(EEPROM.read(address) != toSave){
EEPROM.write(address,toSave);
}
value = value >> 8;
address--;
}
}
//---------- 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 2byte ---------
unsigned int Fnc_Eep_Lod2(int address){
unsigned int value = EEPROM.read(address);
value = value << 8;
return value | EEPROM.read(address + 1);
}
//---------- 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(){
if(Flg_Tx == 1){
lcd.setCursor(0,0);
lcd.print("T");
}
else{
lcd.setCursor(0,0);
lcd.print(Byt_Chn);
}
Fnc_Step_Disp();
if(Flg_Rit == 1){
lcd.setCursor(5,1);
lcd.print("R: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if(Flg_Spl == 1){
lcd.setCursor(5,1);
lcd.print("X: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if((Flg_Rit == 0) && (Flg_Spl == 0)){
Fnc_Dot_Edit(Lcd_Dat,Vfo_Dat - IF_FRQ);
lcd.setCursor(1,0);
lcd.print(": ");
lcd.setCursor(3,0);
lcd.print(Lcd_Dat);
lcd.print("MHz");
lcd.setCursor(5,1);
lcd.print(" JA2GQP");
}
}
//---------- Function Rit ---------
void Fnc_Rit(){
if(Flg_Rit == 0){
Rit_Dat = 0;
Flg_Rit = 1;
Flg_Spl = 0;
switch(Byt_Chn){
case 1:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
break;
case 2:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
break;
case 3:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
break;
default:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
break;
}
}
else{
Flg_Rit = 0;
}
while(digitalRead(SW_RIT) == LOW)
;
delay(250);
}
//---------- Function Channel SW Check ---------
void Fnc_Chsw(){
if(digitalRead(SW_CH1) == LOW){
Byt_Chn = 1;
}
else if(digitalRead(SW_CH2) == LOW){
Byt_Chn = 2;
}
else if(digitalRead(SW_CH3) == LOW){
Byt_Chn = 3;
}
else{
Byt_Chn = 0;
}
}
//---------- Function EEPROM Read ---------
void Fnc_Eep_Rd(){
if(Fnc_Eep_Lod4(Frq_Eep0) <= LW_VFO){
Vfo_Dat = DEF_VFO;
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep1);
break;
case 2:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep2);
break;
case 3:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep3);
break;
default:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep0);
break;
}
}
if(Vfo_Dat <= 0){
Vfo_Dat = DEF_VFO;
}
if(Fnc_Eep_Lod4(Stp_Eep0) <= 0){
Enc_Stp = DEF_STP;
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep1);
break;
case 2:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep2);
break;
case 3:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep3);
break;
default:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep0);
break;
}
}
if(Enc_Stp <= 0){
Enc_Stp = DEF_STP;
}
}
//---------- Function Split ---------
void Fnc_Spl(){
if(Flg_Spl == 0){
Flg_Spl = 1;
Flg_Rit = 0;
Rit_Dat = 0;
}
else{
Flg_Spl = 0;
}
while(digitalRead(SW_SPLIT) == LOW)
;
delay(250);
}
回路図である。LPFはシュミレーションにより、カットオフ16MHzで設計。シュミレーションの様子は、Twitterに書き込んである。
Program
公開済みのArduino版ファームウェアを移植した。デバイス固有の部分は、DDS出力ルーチンである。今までのIF=10MHzとしたプリミックスでアッパーヘテロダインでは、DDS最大出力周波数を超えてしまう。そこでIF=5MHzとした。IFを10MHzとする場合、逆ヘテロダインとなる。何れのソースプログラムもDownload siteにupしてある。//////////////////////////////////////////////////////////////////////
// TC170C030AF001 DDS VFO Premixed type program ver.1.0
//
// Copyright(C)2014-2015.JA2GQP.All rights reserved.
//
// 7.000MHz to 7.200MHz Limitted.
// (Target frequency = IF frquency + frequency)
// 2015/04/14
// JA2GQP
//--------------------------------------------------------------------
// Function
// 1.RIT Operation(-50kHZ to 50kHZ)
// 2.STEP(100k,10k,1k,100,10)
// 3.Memory Operation is Push RIT
// (Frequency and Step)
// 4.Protection Operation At The Time Of Transmission
// 5.Channel Memory.Main Channel(Ch0) + 3 Channel(Ch1,Ch2,Ch3)
// 6.Split Operation(7.00MHz to 7.20MHz Limited!)
//
//////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <rotary.h>
#include <EEPROM.h>
//---------- LCD Pin Assign ------------------
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for
// a 16 chars and 2 line display
//---------- Define Constant Value ----------
const byte ENC_A = 2; // Encorder A
const byte ENC_B = 3; // B
const byte DDT = 4; // TC170C030AF001 DATA
const byte DCK = 5; // SCK
const byte DST = 6; // STB
const byte SW_STEP = 7; // STEP Sw
const byte SW_RIT = 8; // RIT Sw
const byte SW_SPLIT = 9; // SPLIT Sw
const byte SW_CH1 = 10; // Channel 1
const byte SW_CH2 = 11; // 2
const byte SW_CH3 = 12; // 3
const byte SW_TX = 13; // TX Sw
const long IF_FRQ = 5001500L; // IF Frequency
const long LW_FRQ = 7000000L; // Lower Limit
const long HI_FRQ = 7200000L; // Upper Limit
const long DEF_FRQ = 7050000L; // Init Frequency
const long DEF_STP = 1000L; // Init STEP
const long LW_RIT = -50000L; // RIT Lower Limit
const long HI_RIT = 50000L; // Upper Limit
const long LW_VFO = IF_FRQ + LW_FRQ; // Vfo Lower Limit
const long HI_VFO = IF_FRQ + HI_FRQ; // Upper Limit
const long DEF_VFO = IF_FRQ + DEF_FRQ; // Vfo Default Frequency
const unsigned long DDS_CLK = 67108864L; // TC170C030AF001 Clock 67.108864Mhz
const unsigned long TWO_E26 = 67108864L; // 2^26
const byte DDS_CMD1 = B00110011; // CM3=1,CM2=1,CM1=0,CM0=0
// A2=1,A1=1
const byte DDS_CMD2 = B00000001; // A0=1
//---------- EEPROM Memory Address ----------
const byte Frq_Eep0 = 0x00; // Frequency Ch0
const byte Frq_Eep1 = 0x04; // Ch1
const byte Frq_Eep2 = 0x08; // Ch2
const byte Frq_Eep3 = 0x0c; // Ch3
const byte Stp_Eep0 = 0x10; // STEP Ch0
const byte Stp_Eep1 = 0x14; // Ch1
const byte Stp_Eep2 = 0x18; // Ch2
const byte Stp_Eep3 = 0x1c; // Ch3
//---------- Encorder Pin Assign(INT) --------
Rotary r = Rotary(ENC_A,ENC_B); // 2 = ENC_A,3 = ENC_B
//---------- Memory Assign -------------------
long Vfo_Dat = 0; // VFO Data
long Dds_Dat = 0; // DDS Data
long Rit_Dat = 0; // RIT Data
long Rit_Datb = 0; // RIT Data Old
long Enc_Stp = 0; // STEP
long Lng_Wk1 = 0; // Long Work1
long Lng_Wk2 = 0; // Long Work2
char *Lcd_Dat = " "; // Lcd Display Buffer
byte Byt_Chn = 0; // Channel SW
byte Byt_Chnb = 0; // Channel SW Old
byte Flg_Rit = 0; // RIT Flag
byte Flg_Ritb = 0; // RIT Flag Old
byte Flg_Tx = 0; // TX Flag
byte Flg_Spl = 0; // SPLIT Flag
//---------- Initialization Program ---------------
void setup(){
lcd.init(); // initialize the lcd
lcd.backlight(); // LCD backlight on
pinMode(SW_STEP,INPUT_PULLUP);
pinMode(SW_RIT,INPUT_PULLUP);
pinMode(SW_SPLIT,INPUT_PULLUP);
pinMode(SW_TX,INPUT_PULLUP);
pinMode(SW_CH1,INPUT_PULLUP);
pinMode(SW_CH2,INPUT_PULLUP);
pinMode(SW_CH3,INPUT_PULLUP);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei(); // INT Enable
pinMode(DST,OUTPUT);
pinMode(DCK,OUTPUT);
pinMode(DDT,OUTPUT);
Flg_Tx = 0;
Flg_Rit = 0;
Flg_Spl = 0;
lcd.clear();
Fnc_Chsw(); // Channel Sw Read
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd(); // EEPROM Read
}
//---------- Main program ---------------
void loop() {
if(Flg_Tx == 0){ // Tx off?
if(digitalRead(SW_STEP) == LOW){ // STEP Sw On?
Fnc_Stp(); // Yes,STEP proc.
}
if(digitalRead(SW_RIT) == LOW){ // RIT Sw On?
Fnc_Rit(); // Yes,RIT proc.
}
if(digitalRead(SW_SPLIT) == LOW){ // SPLIT Sw On?
Fnc_Spl(); // Yes,SPLIT proc.
}
Fnc_Chsw(); // Channel Sw read
if(Byt_Chnb != Byt_Chn){ // Channnel SW Chenge?
if(Byt_Chnb == 0){ // Channnel 0?
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0); // Yes,Vfo_Dat Save
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0); // Enc_Step Save
Flg_Ritb = Flg_Rit;
Rit_Datb = Rit_Dat;
Flg_Rit = 0;
Flg_Spl = 0;
Rit_Dat = 0;
}
if(Byt_Chnb != 0){ // Other(Ch1-Ch3) Channnel?
Flg_Rit = 0;
Flg_Spl = 0;
if((Byt_Chn == 0) && (Flg_Ritb == 1)){
Flg_Rit = 1;
Rit_Dat = Rit_Datb;
}
}
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd();
}
}
if(digitalRead(SW_TX) == LOW){ // Tx On?
Flg_Tx = 1; // Yes,Flg_Tx Set
}
else{
Flg_Tx = 0; // No,Flg_Tx Reset
}
if(Flg_Rit == 1){ // RIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
if(Flg_Tx == 1){ // Tx?
if(Flg_Spl == 1){ // SPLIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
}
Fnc_Dds(Dds_Dat); // TC170C030AF001 DDS Out
Fnc_Lcd(); // LCD Display
delay(100);
}
//---------- 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_VFO,HI_VFO);
if(Flg_Spl == 1){
Rit_Dat = constrain(Rit_Dat,(LW_VFO - Vfo_Dat),(HI_VFO - Vfo_Dat));
}
else{
Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);
}
}
}
}
//---------- Function DDS set ---------------
void Fnc_Dds(double frquency){
unsigned long wrk = frquency * TWO_E26 / DDS_CLK;
unsigned int wrk1,wrk2;
wrk1 = wrk >> 10;
wrk2 = wrk << 6;
wrk2 = wrk2 & 0xffc0 | DDS_CMD1;
digitalWrite(DDT,DDS_CMD2 & 0x01);
digitalWrite(DCK,HIGH);
digitalWrite(DCK,LOW);
shiftOut(DDT,DCK,LSBFIRST,wrk2);
shiftOut(DDT,DCK,LSBFIRST,(wrk2 >> 8));
shiftOut(DDT,DCK,LSBFIRST,wrk1);
shiftOut(DDT,DCK,LSBFIRST,(wrk1 >> 8));
digitalWrite(DST,LOW);
digitalWrite(DST,HIGH);
}
//---------- Function Encorder STEP ---------
void Fnc_Stp(){
if(Enc_Stp == 10){ // Step = 10Hz ?
Enc_Stp = 100000; // Yes,100khz set
}
else{
Enc_Stp = Enc_Stp / 10; // Step down 1 digit
}
delay(100);
Fnc_Step_Disp();
Fnc_Lcd();
while(digitalRead(SW_STEP) == LOW)
;
delay(250);
}
//---------- 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;
}
}
//---------- 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 2byte ---------
void Fnc_Eep_Sav2(unsigned int value,int address){
address += 1;
for(int i = 0;i < 2;i++){
byte toSave = value & 0xFF;
if(EEPROM.read(address) != toSave){
EEPROM.write(address,toSave);
}
value = value >> 8;
address--;
}
}
//---------- 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 2byte ---------
unsigned int Fnc_Eep_Lod2(int address){
unsigned int value = EEPROM.read(address);
value = value << 8;
return value | EEPROM.read(address + 1);
}
//---------- 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(){
if(Flg_Tx == 1){
lcd.setCursor(0,0);
lcd.print("T");
}
else{
lcd.setCursor(0,0);
lcd.print(Byt_Chn);
}
Fnc_Step_Disp();
if(Flg_Rit == 1){
lcd.setCursor(5,1);
lcd.print("R: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if(Flg_Spl == 1){
lcd.setCursor(5,1);
lcd.print("X: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if((Flg_Rit == 0) && (Flg_Spl == 0)){
Fnc_Dot_Edit(Lcd_Dat,Vfo_Dat - IF_FRQ);
lcd.setCursor(1,0);
lcd.print(": ");
lcd.setCursor(3,0);
lcd.print(Lcd_Dat);
lcd.print("MHz");
lcd.setCursor(5,1);
lcd.print(" JA2GQP");
}
}
//---------- Function Rit ---------
void Fnc_Rit(){
if(Flg_Rit == 0){
Rit_Dat = 0;
Flg_Rit = 1;
Flg_Spl = 0;
switch(Byt_Chn){
case 1:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
break;
case 2:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
break;
case 3:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
break;
default:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
break;
}
}
else{
Flg_Rit = 0;
}
while(digitalRead(SW_RIT) == LOW)
;
delay(250);
}
//---------- Function Channel SW Check ---------
void Fnc_Chsw(){
if(digitalRead(SW_CH1) == LOW){
Byt_Chn = 1;
}
else if(digitalRead(SW_CH2) == LOW){
Byt_Chn = 2;
}
else if(digitalRead(SW_CH3) == LOW){
Byt_Chn = 3;
}
else{
Byt_Chn = 0;
}
}
//---------- Function EEPROM Read ---------
void Fnc_Eep_Rd(){
if(Fnc_Eep_Lod4(Frq_Eep0) <= LW_VFO){
Vfo_Dat = DEF_VFO;
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep1);
break;
case 2:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep2);
break;
case 3:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep3);
break;
default:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep0);
break;
}
}
if(Vfo_Dat <= 0){
Vfo_Dat = DEF_VFO;
}
if(Fnc_Eep_Lod4(Stp_Eep0) <= 0){
Enc_Stp = DEF_STP;
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep1);
break;
case 2:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep2);
break;
case 3:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep3);
break;
default:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep0);
break;
}
}
if(Enc_Stp <= 0){
Enc_Stp = DEF_STP;
}
}
//---------- Function Split ---------
void Fnc_Spl(){
if(Flg_Spl == 0){
Flg_Spl = 1;
Flg_Rit = 0;
Rit_Dat = 0;
}
else{
Flg_Spl = 0;
}
while(digitalRead(SW_SPLIT) == LOW)
;
delay(250);
}
2015年3月4日水曜日
FM PiPi ラジオ
今年の製作講習会のテーマは、FM PiPi専用ラジオである。既に公開のコミュニティラジオその物であるが、回路の見直しと定数変更した。最終的な形としてトロイダルコア版とFCZコイル版の2タイプを試験した。同じ機能の物をコイルタイプの違いで作った例が殆ど見当らない。両タイプをPCB化し、比較した。
トロイダルコアを使った回路図である。同調周波数は、シュミレーションで定数を決めたが、インダクタのズレと、トリマーの最少容量(10p程度)による誤差で、トリマが殆ど抜けた状態で同調。ピークに合わせられるので、定数変更は行わない。
公開済みのPCBにデカップリングを追加したのみ。 PCBサイズ 62x48。
FCZコイル版
FCZタイプのコアを使う方が安定動作を期待出来る。ただ、FCZ純正品は生産が終了している。ジャンクコイル(TOKOなどのFCZタイプ)またはコアキットを使って手巻き、もしくは、FCZ純正タイプ3rdパーティ製使用の選択肢がある。ただ、費用を抑えるのであれば、手巻きのみ。 10.7Mhzコイルは、市販品。それ以外、手巻した。
FCZタイプを使った回路図である。コイルの巻き数は、FCZ144相当。また、2ピンにデカップリングを入れてないが、何ら問題は起きてない。
PCBサイズ 62x48。ただ、部品を実装した高さが、トロイダルコア版より高い。
結果
局発に水晶発振子を使う限り、性能差はないが、自励発振(LC発振)の場合、トロイダルコアの方が安定(対電圧)していた。また、コイルの手巻きは、FCZタイプより、トロイダルコアの方が有利であろう。100MHzh以下であれば、トロイダルコアでも実用的な物ができると思う。技術講習会であれば、トロイダルコア。入門者向け講習会であれば、3rdパーティのFCZタイプを利用するのが良いと思う。
トロイダルコアを使った回路図である。同調周波数は、シュミレーションで定数を決めたが、インダクタのズレと、トリマーの最少容量(10p程度)による誤差で、トリマが殆ど抜けた状態で同調。ピークに合わせられるので、定数変更は行わない。
公開済みのPCBにデカップリングを追加したのみ。 PCBサイズ 62x48。
FCZコイル版
FCZタイプのコアを使う方が安定動作を期待出来る。ただ、FCZ純正品は生産が終了している。ジャンクコイル(TOKOなどのFCZタイプ)またはコアキットを使って手巻き、もしくは、FCZ純正タイプ3rdパーティ製使用の選択肢がある。ただ、費用を抑えるのであれば、手巻きのみ。 10.7Mhzコイルは、市販品。それ以外、手巻した。
FCZタイプを使った回路図である。コイルの巻き数は、FCZ144相当。また、2ピンにデカップリングを入れてないが、何ら問題は起きてない。
PCBサイズ 62x48。ただ、部品を実装した高さが、トロイダルコア版より高い。
結果
局発に水晶発振子を使う限り、性能差はないが、自励発振(LC発振)の場合、トロイダルコアの方が安定(対電圧)していた。また、コイルの手巻きは、FCZタイプより、トロイダルコアの方が有利であろう。100MHzh以下であれば、トロイダルコアでも実用的な物ができると思う。技術講習会であれば、トロイダルコア。入門者向け講習会であれば、3rdパーティのFCZタイプを利用するのが良いと思う。
2015年2月28日土曜日
SPAM Speaker
SPAMの空き缶をスピーカのエンクロージャに使った。ユニットは、aitendoで販売している5cmの物で、適度に低音も出ており、抜けもこのサイズにしては良い。ユニットをホットボンドで固定したので、見栄えが悪い。構造的にバスレフ(適当に隙間があるので)。肝心な音は、無線機で使うには、十分。ラジオ用としては、実用レベル。
正面は、綺麗でない。 見栄え重視で作れば、良いものが出来るであろう。内部側面に、吸音材を入れている。背面側は、聞いた感じで、吸音材なしにした。
背面は端子がある。SPAM缶は、アルミニューム製の為、色々なケーシングに使いたい。
正面は、綺麗でない。 見栄え重視で作れば、良いものが出来るであろう。内部側面に、吸音材を入れている。背面側は、聞いた感じで、吸音材なしにした。
背面は端子がある。SPAM缶は、アルミニューム製の為、色々なケーシングに使いたい。
2015年2月5日木曜日
コミニュティFMラジオ2
部品を実装したPCB。(ケースに収納した物と別基板)
2015年2月1日日曜日
コミニュティFMラジオ
アナログ防災無線に代わり、コミニュティFMラジオにより地域情報が流れている。この為、専用のFMラジオを作った。回路構成は、TA7792P+TA7368Pで、LOに水晶を使用。FCZコイルを使わず、T37-6で統一。水晶は、価格の安いもの使い、基本波の4高調波を使っている。コイルのQが高い為、感度も良い。
回路図である。LOは、当初、複同調で4倍波を取り出したが、単同調でも実使用で大差が無かった。トロイダルコアは、2次コイルを巻かず、コンデンサ結合。
回路図である。LOは、当初、複同調で4倍波を取り出したが、単同調でも実使用で大差が無かった。トロイダルコアは、2次コイルを巻かず、コンデンサ結合。
2015年1月20日火曜日
Arduino AD9851 DDS VFO
AD9851を使ったDDS VFOである。Arduino版AD9834 DDS VFO同様、LCD表示にI2Cを用い、I/O割り付けも同じにした。AD9851基準クロックは、32MHz(手持ち品流用)としたため、60Mhz位まで使えるであろう。従って、LPFカットオフ 60MHzで設計した。
回路図。
出力回路は、抵抗で終端したが、1対1のトランスにすると出力(現在、160uW at 17.05MHz)が6dB増える。ミキサー回路に使うのであれば、このままでも良いかも知れない。
Filter DesignによるLPFシュミレーション結果。
(基準クロック 6倍のパラメータ)
//////////////////////////////////////////////////////////////////////
// AD9851 DDS VFO Premixed type program ver.1.0
//
// Copyright(C)2014-2015.JA2GQP.All rights reserved.
//
// 7.000MHz to 7.200MHz Limitted.
// (Target frequency = IF frquency + frequency)
// 2015/1/20
// JA2GQP
//--------------------------------------------------------------------
// Function
// 1.Upper Heterodyne(Target Frequency = IF Frequency + Frequency)
// 2.RIT Operation(-50kHZ to 50kHZ)
// 3.STEP(100k,10k,1k,100,10)
// 4.Memory Operation is Push RIT
// (Frequency and Step)
// 5.Protection Operation At The Time Of Transmission
// 6.Channel Memory.Main Channel(Ch0) + 3 Channel(Ch1,Ch2,Ch3)
// 7.Split Operation(7.00MHz to 7.20MHz Limited!)
//--------------------------------------------------------------------
// Library
// http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
//
//////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <rotary.h>
#include <EEPROM.h>
//---------- LCD Pin Assign ------------------
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for
// a 16 chars and 2 line display
//---------- Define Constant Value ----------
const byte ENC_A = 2; // Encorder A
const byte ENC_B = 3; // Encoeder B
const byte DATA = 4; // DIO4
const byte W_CLK = 5; // DIO5
const byte FQ_UD = 6; // DIO6
const byte SW_STEP = 7; // STEP Sw
const byte SW_RIT = 8; // RIT Sw
const byte SW_SPLIT = 9; // SPLIT Sw
const byte SW_CH1 = 10; // Channel 1
const byte SW_CH2 = 11; // 2
const byte SW_CH3 = 12; // 3
const byte SW_TX = 13; // TX Sw
const long IF_FRQ = 9996500L; // IF Frequency
const long LW_FRQ = 7000000L; // Lower Limit
const long HI_FRQ = 7200000L; // Upper Limit
const long DEF_FRQ = 7050000L; // Init Frequency
const long DEF_STP = 1000L; // Init STEP
const long LW_RIT = -50000L; // RIT Lower Limit
const long HI_RIT = 50000L; // RIT Upper Limit
const long LW_VFO = IF_FRQ + LW_FRQ; // Vfo Lower Limit
const long HI_VFO = IF_FRQ + HI_FRQ; // Vfo Upper Limit
const long DEF_VFO = IF_FRQ + DEF_FRQ; // Vfo Default Frequency
const unsigned long DDS_CLK = 192000000L; // AD9851 Clock(32MHz * 6)
const unsigned long TWO_E32 = 4294967295L;// 2^32
const byte DDS_CMD = B00000001; // AD9851 Command
//---------- EEPROM Memory Address ----------
const byte Frq_Eep0 = 0x00; // Frequency Ch0
const byte Frq_Eep1 = 0x04; // Ch1
const byte Frq_Eep2 = 0x08; // Ch2
const byte Frq_Eep3 = 0x0c; // Ch3
const byte Stp_Eep0 = 0x10; // STEP Ch0
const byte Stp_Eep1 = 0x14; // Ch1
const byte Stp_Eep2 = 0x18; // Ch2
const byte Stp_Eep3 = 0x1c; // Ch3
//---------- Encorder Pin Assign(INT) --------
Rotary r = Rotary(ENC_A,ENC_B); // 2 = ENC_A,3 = ENC_B
//---------- Memory Assign -------------------
long Vfo_Dat = 0; // VFO Data
long Dds_Dat = 0; // DDS Data
long Rit_Dat = 0; // RIT Data
long Rit_Datb = 0; // RIT Data Old
long Enc_Stp = 0; // STEP
long Lng_Wk1 = 0; // Long Work1
long Lng_Wk2 = 0; // Long Work2
char *Lcd_Dat = " "; // Lcd Display Buffer
byte Byt_Chn = 0; // Channel SW
byte Byt_Chnb = 0; // Channel SW Old
byte Flg_Rit = 0; // RIT Flag
byte Flg_Ritb = 0; // RIT Flag Old
byte Flg_Tx = 0; // TX Flag
byte Flg_Spl = 0; // SPLIT Flag
//---------- Initialization Program ---------------
void setup(){
lcd.init(); // initialize the lcd
lcd.backlight(); // LCD backlight on
pinMode(SW_STEP,INPUT_PULLUP);
pinMode(SW_RIT,INPUT_PULLUP);
pinMode(SW_SPLIT,INPUT_PULLUP);
pinMode(SW_TX,INPUT_PULLUP);
pinMode(SW_CH1,INPUT_PULLUP);
pinMode(SW_CH2,INPUT_PULLUP);
pinMode(SW_CH3,INPUT_PULLUP);
lcd.begin(16, 2); // LCD 16*2
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei(); // INT Enable
pinMode(FQ_UD,OUTPUT);
pinMode(W_CLK,OUTPUT);
pinMode(DATA,OUTPUT);
Flg_Tx = 0;
Flg_Rit = 0;
Flg_Spl = 0;
lcd.clear();
Fnc_Chsw(); // Channel Sw Read
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd(); // EEPROM Read
}
//---------- Main program ---------------
void loop() {
if(Flg_Tx == 0){ // Tx off?
if(digitalRead(SW_STEP) == LOW){ // STEP Sw On?
Fnc_Stp(); // Yes,STEP proc.
}
if(digitalRead(SW_RIT) == LOW){ // RIT Sw On?
Fnc_Rit(); // Yes,RIT proc.
}
if(digitalRead(SW_SPLIT) == LOW){ // SPLIT Sw On?
Fnc_Spl(); // Yes,SPLIT proc.
}
Fnc_Chsw(); // Channel Sw read
if(Byt_Chnb != Byt_Chn){ // Channnel SW Chenge?
if(Byt_Chnb == 0){ // Channnel 0?
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0); // Yes,Vfo_Dat Save
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0); // Enc_Step Save
Flg_Ritb = Flg_Rit;
Rit_Datb = Rit_Dat;
Flg_Rit = 0;
Flg_Spl = 0;
Rit_Dat = 0;
}
if(Byt_Chnb != 0){ // Other(Ch1-Ch3) Channnel?
Flg_Rit = 0;
Flg_Spl = 0;
if((Byt_Chn == 0) && (Flg_Ritb == 1)){
Flg_Rit = 1;
Rit_Dat = Rit_Datb;
}
}
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd();
}
}
if(digitalRead(SW_TX) == LOW){ // Tx On?
Flg_Tx = 1; // Yes,Flg_Tx Set
}
else{
Flg_Tx = 0; // No,Flg_Tx Reset
}
if(Flg_Rit == 1){ // RIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
if(Flg_Tx == 1){ // Tx?
if(Flg_Spl == 1){ // SPLIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
}
Fnc_Dds(Dds_Dat); // AD9850 DDS Out
Fnc_Lcd(); // LCD Display
delay(100);
}
//---------- 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_VFO,HI_VFO);
if(Flg_Spl == 1){
Rit_Dat = constrain(Rit_Dat,(LW_VFO - Vfo_Dat),(HI_VFO - Vfo_Dat));
}
else{
Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);
}
}
}
}
//---------- Function DDS set ---------------
void Fnc_Dds(double frquency){
unsigned long wrk = frquency * TWO_E32 / DDS_CLK;
digitalWrite(FQ_UD,LOW);
shiftOut(DATA,W_CLK,LSBFIRST,wrk);
shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 8));
shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 16));
shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 24));
shiftOut(DATA,W_CLK,LSBFIRST,DDS_CMD); // AD9851 command
digitalWrite(FQ_UD,HIGH);
}
//---------- Function Encorder STEP ---------
void Fnc_Stp(){
if(Enc_Stp == 10){ // Step = 10Hz ?
Enc_Stp = 100000; // Yes,100khz set
}
else{
Enc_Stp = Enc_Stp / 10; // Step down 1 digit
}
// delay(250);
Fnc_Step_Disp();
// Fnc_Lcd();
while(digitalRead(SW_STEP) == LOW)
;
delay(250);
}
//---------- Function STEP Display ----------
void Fnc_Step_Disp(){
lcd.setCursor(0,1);
lcd.print(" "); // Clear step display
lcd.setCursor(0,1);
if(1 <= (Enc_Stp / 1000)){ // kiro?
lcd.print(Enc_Stp / 1000); // Yes,Convert kiro
lcd.print("k");
}
else{
lcd.print(Enc_Stp);
}
}
//---------- 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 2byte ---------
void Fnc_Eep_Sav2(unsigned int value,int address){
address += 1;
for(int i = 0;i < 2;i++){
byte toSave = value & 0xFF;
if(EEPROM.read(address) != toSave){
EEPROM.write(address,toSave);
}
value = value >> 8;
address--;
}
}
//---------- 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 2byte ---------
unsigned int Fnc_Eep_Lod2(int address){
unsigned int value = EEPROM.read(address);
value = value << 8;
return value | EEPROM.read(address + 1);
}
//---------- 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(){
if(Flg_Tx == 1){
lcd.setCursor(0,0);
lcd.print("T");
}
else{
lcd.setCursor(0,0);
lcd.print(Byt_Chn);
}
Fnc_Step_Disp();
if(Flg_Rit == 1){
lcd.setCursor(5,1);
lcd.print("R: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if(Flg_Spl == 1){
lcd.setCursor(5,1);
lcd.print("X: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if((Flg_Rit == 0) && (Flg_Spl == 0)){
Fnc_Dot_Edit(Lcd_Dat,Vfo_Dat - IF_FRQ);
lcd.setCursor(1,0);
lcd.print(": ");
lcd.setCursor(3,0);
lcd.print(Lcd_Dat);
lcd.print("MHz");
lcd.setCursor(5,1);
lcd.print(" JA2GQP");
}
}
//---------- Function Rit ---------
void Fnc_Rit(){
if(Flg_Rit == 0){
Rit_Dat = 0;
Flg_Rit = 1;
Flg_Spl = 0;
switch(Byt_Chn){
case 1:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
break;
case 2:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
break;
case 3:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
break;
default:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
break;
}
}
else{
Flg_Rit = 0;
}
while(digitalRead(SW_RIT) == LOW)
;
delay(250);
}
//---------- Function Channel SW Check ---------
void Fnc_Chsw(){
if(digitalRead(SW_CH1) == LOW){
Byt_Chn = 1;
}
else if(digitalRead(SW_CH2) == LOW){
Byt_Chn = 2;
}
else if(digitalRead(SW_CH3) == LOW){
Byt_Chn = 3;
}
else{
Byt_Chn = 0;
}
}
//---------- Function EEPROM Read ---------
void Fnc_Eep_Rd(){
if(Fnc_Eep_Lod4(Frq_Eep0) <= LW_VFO){
Vfo_Dat = DEF_VFO;
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep1);
break;
case 2:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep2);
break;
case 3:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep3);
break;
default:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep0);
break;
}
}
if(Vfo_Dat <= 0){
Vfo_Dat = DEF_VFO;
}
if(Fnc_Eep_Lod4(Stp_Eep0) <= 0){
Enc_Stp = DEF_STP;
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep1);
break;
case 2:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep2);
break;
case 3:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep3);
break;
default:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep0);
break;
}
}
if(Enc_Stp <= 0){
Enc_Stp = DEF_STP;
}
}
//---------- Function Split ---------
void Fnc_Spl(){
if(Flg_Spl == 0){
Flg_Spl = 1;
Flg_Rit = 0;
Rit_Dat = 0;
}
else{
Flg_Spl = 0;
}
while(digitalRead(SW_SPLIT) == LOW)
;
delay(250);
}
回路図。
出力回路は、抵抗で終端したが、1対1のトランスにすると出力(現在、160uW at 17.05MHz)が6dB増える。ミキサー回路に使うのであれば、このままでも良いかも知れない。
Filter DesignによるLPFシュミレーション結果。
program
AD9851とAD9850の違いは、DDS_CLK = 192000000LとDDS_CMD = B00000001の2行である。(基準クロック 6倍のパラメータ)
//////////////////////////////////////////////////////////////////////
// AD9851 DDS VFO Premixed type program ver.1.0
//
// Copyright(C)2014-2015.JA2GQP.All rights reserved.
//
// 7.000MHz to 7.200MHz Limitted.
// (Target frequency = IF frquency + frequency)
// 2015/1/20
// JA2GQP
//--------------------------------------------------------------------
// Function
// 1.Upper Heterodyne(Target Frequency = IF Frequency + Frequency)
// 2.RIT Operation(-50kHZ to 50kHZ)
// 3.STEP(100k,10k,1k,100,10)
// 4.Memory Operation is Push RIT
// (Frequency and Step)
// 5.Protection Operation At The Time Of Transmission
// 6.Channel Memory.Main Channel(Ch0) + 3 Channel(Ch1,Ch2,Ch3)
// 7.Split Operation(7.00MHz to 7.20MHz Limited!)
//--------------------------------------------------------------------
// Library
// http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
//
//////////////////////////////////////////////////////////////////////
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <rotary.h>
#include <EEPROM.h>
//---------- LCD Pin Assign ------------------
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for
// a 16 chars and 2 line display
//---------- Define Constant Value ----------
const byte ENC_A = 2; // Encorder A
const byte ENC_B = 3; // Encoeder B
const byte DATA = 4; // DIO4
const byte W_CLK = 5; // DIO5
const byte FQ_UD = 6; // DIO6
const byte SW_STEP = 7; // STEP Sw
const byte SW_RIT = 8; // RIT Sw
const byte SW_SPLIT = 9; // SPLIT Sw
const byte SW_CH1 = 10; // Channel 1
const byte SW_CH2 = 11; // 2
const byte SW_CH3 = 12; // 3
const byte SW_TX = 13; // TX Sw
const long IF_FRQ = 9996500L; // IF Frequency
const long LW_FRQ = 7000000L; // Lower Limit
const long HI_FRQ = 7200000L; // Upper Limit
const long DEF_FRQ = 7050000L; // Init Frequency
const long DEF_STP = 1000L; // Init STEP
const long LW_RIT = -50000L; // RIT Lower Limit
const long HI_RIT = 50000L; // RIT Upper Limit
const long LW_VFO = IF_FRQ + LW_FRQ; // Vfo Lower Limit
const long HI_VFO = IF_FRQ + HI_FRQ; // Vfo Upper Limit
const long DEF_VFO = IF_FRQ + DEF_FRQ; // Vfo Default Frequency
const unsigned long DDS_CLK = 192000000L; // AD9851 Clock(32MHz * 6)
const unsigned long TWO_E32 = 4294967295L;// 2^32
const byte DDS_CMD = B00000001; // AD9851 Command
//---------- EEPROM Memory Address ----------
const byte Frq_Eep0 = 0x00; // Frequency Ch0
const byte Frq_Eep1 = 0x04; // Ch1
const byte Frq_Eep2 = 0x08; // Ch2
const byte Frq_Eep3 = 0x0c; // Ch3
const byte Stp_Eep0 = 0x10; // STEP Ch0
const byte Stp_Eep1 = 0x14; // Ch1
const byte Stp_Eep2 = 0x18; // Ch2
const byte Stp_Eep3 = 0x1c; // Ch3
//---------- Encorder Pin Assign(INT) --------
Rotary r = Rotary(ENC_A,ENC_B); // 2 = ENC_A,3 = ENC_B
//---------- Memory Assign -------------------
long Vfo_Dat = 0; // VFO Data
long Dds_Dat = 0; // DDS Data
long Rit_Dat = 0; // RIT Data
long Rit_Datb = 0; // RIT Data Old
long Enc_Stp = 0; // STEP
long Lng_Wk1 = 0; // Long Work1
long Lng_Wk2 = 0; // Long Work2
char *Lcd_Dat = " "; // Lcd Display Buffer
byte Byt_Chn = 0; // Channel SW
byte Byt_Chnb = 0; // Channel SW Old
byte Flg_Rit = 0; // RIT Flag
byte Flg_Ritb = 0; // RIT Flag Old
byte Flg_Tx = 0; // TX Flag
byte Flg_Spl = 0; // SPLIT Flag
//---------- Initialization Program ---------------
void setup(){
lcd.init(); // initialize the lcd
lcd.backlight(); // LCD backlight on
pinMode(SW_STEP,INPUT_PULLUP);
pinMode(SW_RIT,INPUT_PULLUP);
pinMode(SW_SPLIT,INPUT_PULLUP);
pinMode(SW_TX,INPUT_PULLUP);
pinMode(SW_CH1,INPUT_PULLUP);
pinMode(SW_CH2,INPUT_PULLUP);
pinMode(SW_CH3,INPUT_PULLUP);
lcd.begin(16, 2); // LCD 16*2
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei(); // INT Enable
pinMode(FQ_UD,OUTPUT);
pinMode(W_CLK,OUTPUT);
pinMode(DATA,OUTPUT);
Flg_Tx = 0;
Flg_Rit = 0;
Flg_Spl = 0;
lcd.clear();
Fnc_Chsw(); // Channel Sw Read
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd(); // EEPROM Read
}
//---------- Main program ---------------
void loop() {
if(Flg_Tx == 0){ // Tx off?
if(digitalRead(SW_STEP) == LOW){ // STEP Sw On?
Fnc_Stp(); // Yes,STEP proc.
}
if(digitalRead(SW_RIT) == LOW){ // RIT Sw On?
Fnc_Rit(); // Yes,RIT proc.
}
if(digitalRead(SW_SPLIT) == LOW){ // SPLIT Sw On?
Fnc_Spl(); // Yes,SPLIT proc.
}
Fnc_Chsw(); // Channel Sw read
if(Byt_Chnb != Byt_Chn){ // Channnel SW Chenge?
if(Byt_Chnb == 0){ // Channnel 0?
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0); // Yes,Vfo_Dat Save
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0); // Enc_Step Save
Flg_Ritb = Flg_Rit;
Rit_Datb = Rit_Dat;
Flg_Rit = 0;
Flg_Spl = 0;
Rit_Dat = 0;
}
if(Byt_Chnb != 0){ // Other(Ch1-Ch3) Channnel?
Flg_Rit = 0;
Flg_Spl = 0;
if((Byt_Chn == 0) && (Flg_Ritb == 1)){
Flg_Rit = 1;
Rit_Dat = Rit_Datb;
}
}
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd();
}
}
if(digitalRead(SW_TX) == LOW){ // Tx On?
Flg_Tx = 1; // Yes,Flg_Tx Set
}
else{
Flg_Tx = 0; // No,Flg_Tx Reset
}
if(Flg_Rit == 1){ // RIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
if(Flg_Tx == 1){ // Tx?
if(Flg_Spl == 1){ // SPLIT?
Dds_Dat = Vfo_Dat + Rit_Dat; // Yes,Dds_Dat Set
}
else{
Dds_Dat = Vfo_Dat; // No,Dds_Dat Set
}
}
Fnc_Dds(Dds_Dat); // AD9850 DDS Out
Fnc_Lcd(); // LCD Display
delay(100);
}
//---------- 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_VFO,HI_VFO);
if(Flg_Spl == 1){
Rit_Dat = constrain(Rit_Dat,(LW_VFO - Vfo_Dat),(HI_VFO - Vfo_Dat));
}
else{
Rit_Dat = constrain(Rit_Dat,LW_RIT,HI_RIT);
}
}
}
}
//---------- Function DDS set ---------------
void Fnc_Dds(double frquency){
unsigned long wrk = frquency * TWO_E32 / DDS_CLK;
digitalWrite(FQ_UD,LOW);
shiftOut(DATA,W_CLK,LSBFIRST,wrk);
shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 8));
shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 16));
shiftOut(DATA,W_CLK,LSBFIRST,(wrk >> 24));
shiftOut(DATA,W_CLK,LSBFIRST,DDS_CMD); // AD9851 command
digitalWrite(FQ_UD,HIGH);
}
//---------- Function Encorder STEP ---------
void Fnc_Stp(){
if(Enc_Stp == 10){ // Step = 10Hz ?
Enc_Stp = 100000; // Yes,100khz set
}
else{
Enc_Stp = Enc_Stp / 10; // Step down 1 digit
}
// delay(250);
Fnc_Step_Disp();
// Fnc_Lcd();
while(digitalRead(SW_STEP) == LOW)
;
delay(250);
}
//---------- Function STEP Display ----------
void Fnc_Step_Disp(){
lcd.setCursor(0,1);
lcd.print(" "); // Clear step display
lcd.setCursor(0,1);
if(1 <= (Enc_Stp / 1000)){ // kiro?
lcd.print(Enc_Stp / 1000); // Yes,Convert kiro
lcd.print("k");
}
else{
lcd.print(Enc_Stp);
}
}
//---------- 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 2byte ---------
void Fnc_Eep_Sav2(unsigned int value,int address){
address += 1;
for(int i = 0;i < 2;i++){
byte toSave = value & 0xFF;
if(EEPROM.read(address) != toSave){
EEPROM.write(address,toSave);
}
value = value >> 8;
address--;
}
}
//---------- 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 2byte ---------
unsigned int Fnc_Eep_Lod2(int address){
unsigned int value = EEPROM.read(address);
value = value << 8;
return value | EEPROM.read(address + 1);
}
//---------- 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(){
if(Flg_Tx == 1){
lcd.setCursor(0,0);
lcd.print("T");
}
else{
lcd.setCursor(0,0);
lcd.print(Byt_Chn);
}
Fnc_Step_Disp();
if(Flg_Rit == 1){
lcd.setCursor(5,1);
lcd.print("R: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if(Flg_Spl == 1){
lcd.setCursor(5,1);
lcd.print("X: ");
Fnc_Dot_Edit(Lcd_Dat,Rit_Dat);
lcd.setCursor(7,1);
lcd.print(Lcd_Dat);
if((Rit_Dat >= 1000) || (Rit_Dat <= -1000)){
lcd.print("k");
}
}
if((Flg_Rit == 0) && (Flg_Spl == 0)){
Fnc_Dot_Edit(Lcd_Dat,Vfo_Dat - IF_FRQ);
lcd.setCursor(1,0);
lcd.print(": ");
lcd.setCursor(3,0);
lcd.print(Lcd_Dat);
lcd.print("MHz");
lcd.setCursor(5,1);
lcd.print(" JA2GQP");
}
}
//---------- Function Rit ---------
void Fnc_Rit(){
if(Flg_Rit == 0){
Rit_Dat = 0;
Flg_Rit = 1;
Flg_Spl = 0;
switch(Byt_Chn){
case 1:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
break;
case 2:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
break;
case 3:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
break;
default:
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
break;
}
}
else{
Flg_Rit = 0;
}
while(digitalRead(SW_RIT) == LOW)
;
delay(250);
}
//---------- Function Channel SW Check ---------
void Fnc_Chsw(){
if(digitalRead(SW_CH1) == LOW){
Byt_Chn = 1;
}
else if(digitalRead(SW_CH2) == LOW){
Byt_Chn = 2;
}
else if(digitalRead(SW_CH3) == LOW){
Byt_Chn = 3;
}
else{
Byt_Chn = 0;
}
}
//---------- Function EEPROM Read ---------
void Fnc_Eep_Rd(){
if(Fnc_Eep_Lod4(Frq_Eep0) <= LW_VFO){
Vfo_Dat = DEF_VFO;
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep0);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep1);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep2);
Fnc_Eep_Sav4(Vfo_Dat,Frq_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep1);
break;
case 2:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep2);
break;
case 3:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep3);
break;
default:
Vfo_Dat = Fnc_Eep_Lod4(Frq_Eep0);
break;
}
}
if(Vfo_Dat <= 0){
Vfo_Dat = DEF_VFO;
}
if(Fnc_Eep_Lod4(Stp_Eep0) <= 0){
Enc_Stp = DEF_STP;
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep0);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep1);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep2);
Fnc_Eep_Sav4(Enc_Stp,Stp_Eep3);
}
else{
switch(Byt_Chn){
case 1:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep1);
break;
case 2:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep2);
break;
case 3:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep3);
break;
default:
Enc_Stp = Fnc_Eep_Lod4(Stp_Eep0);
break;
}
}
if(Enc_Stp <= 0){
Enc_Stp = DEF_STP;
}
}
//---------- Function Split ---------
void Fnc_Spl(){
if(Flg_Spl == 0){
Flg_Spl = 1;
Flg_Rit = 0;
Rit_Dat = 0;
}
else{
Flg_Spl = 0;
}
while(digitalRead(SW_SPLIT) == LOW)
;
delay(250);
}
登録:
投稿 (Atom)