AD9850を実装した基板。
部品を実装した基板。0Ω(2本)は、ジャンパー線。
TFT接続用コネクタは、ピンヘッダにソケットをハンダ付けし、TFT取付高さを調整した。
回路図
基板サイズ 70 × 55
Program
/////////////////////////////////////////////////////////////////////////////// DDS VFO Ver2.03
// JA2NKD 2016.07.19
// Aruduino IDE 1.6.5
// Arduino nano only
//
// <Rotary.h> https://github.com/brianlow/Rotary
// <EF_AD9850.h> http://forum.arduino.cc/index.php?topic=77483.0
// "Ucglib.h" https://github.com/olikraus/ucglib
//
//----------------------------------------------------------------------------
// Added EEPROM function 2016/7/31 JA2GQP
//
///////////////////////////////////////////////////////////////////////////////
// Library include
#include <SPI.h>
#include <Rotary.h>
#include <EEPROM.h>
//#include <EF_AD9850.h> // <JA2GQP>
#include "Ucglib.h"
//---------- I/O setting ---------------
/////////////////////
// Hardware SPI Pins:
// Arduino nano sclk=13, data=11
/////////////////////
const byte __CS = 10;
const byte __DC = 9;
const byte __RST = 8;
const byte W_CLK = A0; // DIO7(nano) <JA2GQP>
const byte FQ_UD = A1; // DIO6(nano) <JA2GQP>
const byte DATA = A2; // DIO5(nano) <JA2GQP>
const byte modeout1=7; // A0(nano) <JA2GQP>
const byte modeout2=12; // A1(nano) <JA2GQP>
const byte modesw=6; // A2(nano) <JA2GQP>
const byte stepsw=4; // A3(nano) <JA2GQP>
const byte ritsw=5; // A4(nano) <JA2GQP>
const byte txsw=A3; // A5(nano) <JA2GQP>
const byte s_meter=A5; // A6(nano) <JA2GQP>
const byte t_meter=A4; // A7(nano) <JA2GQP>
///////////////////// <JA2GQP>
// 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
//---------- EEPROM Memory Address ---------- <JA2GQP>
const byte Frq_Eep = 0x00; // Frequency(4byte*4)
const byte Stp_Eep = 0x10; // STEP(4byte*4)
const byte Chn_Eep = 0x20; // Channel(1byte*1)
const byte Mode_Eep = 0x22; // Mode(1byte*1)
const byte Eep_Int = 0x2e; // Eep Init(1byte*1)
const byte Max_Chn = 4; // Max Channel(4ch)
const byte Int_End = 73; // Initial end code
//----------- Default Value -------------------- <JA2GQP>
const long DEF_FRQ = 7100000L; // Init Frequency
const long DEF_STP = 100L; // Init STEP
const byte DEF_Mode = 0; // 0=LSB 1=USB 2=CW 3=AM
//---------- Encorder Pin Assign(INT) --------
Rotary r=Rotary(2,3);
//---------- TFT Ucglib Assign --------
Ucglib_ILI9341_18x240x320_HWSPI ucg(__DC, __CS, __RST);
//---------- Memory Assign --------------------------------
long int freq =DEF_FRQ; // <JA2GQP>
long int freqmax=7200000;
long int freqmin=7000000;
long int freqold=0;
long int freqrit=0;
String freqt=String(freq);
long int ifshift = 0;
long int ifshiftLSB =10698500;
long int ifshiftUSB =10701500;
long int ifshiftCW =10699200;
long int ifshiftAM=10700000;
long int txshiftLSB=10698500;
long int txshiftUSB=10701500;
long int txshiftCW=10700000;
long int txshiftAM=10700000;
long int ddsfreq = 0;
char f100m,f10m,fmega,f100k,f10k,f1k,f100,f10,f1;
int ddsstep=2;
int rit=0;
int fstep=DEF_STP; // <JA2GQP>
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 <JA2GQP>
byte Byt_Chnb; // Channel SW Old <JA2GQP>
//---------- Initialization Program ----------------------
void setup() {
delay(100);
ucg.begin(UCG_FONT_MODE_TRANSPARENT);
//ucg.begin(UCG_FONT_MODE_SOLID);
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();
pinMode(FQ_UD,OUTPUT);
pinMode(W_CLK,OUTPUT);
pinMode(DATA,OUTPUT);
screen01();
if(EEPROM.read(Eep_Int) != Int_End){ // Eep initialaz <JA2GQP>
delay(10);
Fnc_Eep_Int();
}
Byt_Chn = EEPROM.read(Chn_Eep); // Channel <JA2GQP>
Byt_Chnb = Byt_Chn; // <JA2GQP>
Fnc_Eep_Rd(); // EEPROM Read <JA2GQP>
modeset(); // modeset * 4 <JA2GQP>
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);} // <JA2GQP>
if (digitalRead(txsw)==LOW){txset();}
if(Byt_Chnb != Byt_Chn){ // CH SW OLD != NEW? <JA2GQP>
Fnc_Eep_Wt(Byt_Chnb);
Byt_Chnb = Byt_Chn;
Fnc_Eep_Rd();
steplcd();
}
if (flagrit==1){
if (freqrit == fritold){
smeter();
}
if (freqrit!=fritold){
ddswrite();
ritlcd();
fritold=freqrit;
}
}
else{
if (freq == freqold){
smeter();
}
// ddsfreq=freq+ifshift;
ddswrite();
freqt=String(freq);
freqlcd();
freqold=freq;
}
}
//---------- Function Eeprom Initialization ------------ <JA2GQP>
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 --------- <JA2GQP>
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 ------------------- <JA2GQP>
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 -------- <JA2GQP>
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 --------- <JA2GQP>
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 DDS set --------------- <JA2GQP>
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); // AD9850 command
digitalWrite(FQ_UD,HIGH);
}
//---------- S-meter --------------------------
void smeter(){
smeterval1=analogRead(s_meter);
smeterval1=smeterval1/50;
if (smeterval1>15){smeterval1=15;}
int sx1=sx1+(smeterval1*17);
sx1=sx1+41;
int sx2=0;
sx2=sx2+(40+((15-smeterval1)*17));
ucg.setFont(ucg_font_fub35_tr);
ucg.setColor(0,0,0);
ucg.drawBox(sx1,180,sx2,16);
ucg.setPrintPos(40,200);
for(int i=1;i<=smeterval1;i++){
if (i<=9){
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);
ucg.drawBox(41,180,270,16);
tmeterval=analogRead(t_meter);
tmeterval=tmeterval/50;
if (tmeterval>15){tmeterval=15;}
int sx1=sx1+(tmeterval*17);
sx1=sx1+41;
int sx2=0;
sx2=sx2+(40+((15-tmeterval)*17));
ucg.setFont(ucg_font_fub35_tr);
ucg.setColor(0,0,0);
ucg.drawBox(sx1,145,sx2,16);
ucg.setPrintPos(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;
}
}
// ddswrite();
}
}
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(){
noInterrupts();
if (flagmode==0){ddsfreq=freq+txshiftLSB;}
if (flagmode==1){ddsfreq=freq+txshiftUSB;}
if (flagmode==2){ddsfreq=freq+txshiftCW;}
if (flagmode==3){ddsfreq=freq+txshiftAM;}
// AD9850.wr_serial(0x00,ddsfreq);
ucg.setPrintPos(140,140);
ucg.setFont(ucg_font_fub17_tr);
ucg.setColor(255,0,0);
ucg.print("ON AIR");
while(digitalRead(txsw) == LOW){
tmeter();
}
ucg.setColor(0,0,0);
ucg.drawBox(30,120,250,30);
ddswrite();
ucg.drawBox(41,145,270,16);
interrupts();
}
//------------- Mode change(LSB-USB-CW-AM) ------------
void modeset(){
ucg.setFont(ucg_font_fub17_tr);
// if (fmode==0){ // <JA2GQP>
if (fmode==1){ // <JA2GQP>
ifshift=ifshiftUSB;
ucg.setColor(255,255,0);
ucg.setPrintPos(82,82);
ucg.print("USB");
ucg.setPrintPos(12,82);
ucg.setColor(0,0,0);
ucg.print("LSB");
digitalWrite(modeout1,HIGH);
digitalWrite(modeout2,LOW);
}
// if(fmode==1){ // <JA2GQP>
if(fmode==2){ // <JA2GQP>
ifshift=ifshiftCW;
ucg.setPrintPos(12,112);
ucg.setColor(255,255,0);
ucg.print("C W");
ucg.setPrintPos(82,82);
ucg.setColor(0,0,0);
ucg.print("USB");
digitalWrite(modeout1,LOW);
digitalWrite(modeout2,HIGH);
}
// if (fmode==2){ // <JA2GQP>
if (fmode==3){ // <JA2GQP>
ifshift=ifshiftAM;
ucg.setPrintPos(82,112);
ucg.setColor(255,255,0);
ucg.print("A M");
ucg.setColor(0,0,0);
ucg.setPrintPos(12,112);
ucg.print("C W");
digitalWrite(modeout1,HIGH);
digitalWrite(modeout2,HIGH);
}
// if (fmode==3){ // <JA2GQP>
if (fmode==0){ // <JA2GQP>
ifshift=ifshiftLSB;
ucg.setPrintPos(12,82);
ucg.setColor(255,255,0);
ucg.print("LSB");
ucg.setPrintPos(82,112);
ucg.setColor(0,0,0);
ucg.print("A M");
digitalWrite(modeout1,LOW);
digitalWrite(modeout2,LOW);
}
fmode=fmode+1;
Byt_Chn++; // <JA2GQP>
if(Byt_Chn > 3)
Byt_Chn = 0;
if (fmode==4){fmode=0;}
ddswrite();
while(digitalRead(modesw) == LOW);
}
//------------ Rit SET ------------------------------
void setrit(){
if(flagrit==0){
flagrit=1;
ucg.setFont(ucg_font_fub11_tr);
ucg.setPrintPos(190,110);
ucg.setColor(255,0,0);
ucg.print("RIT");
// freqrit=0;
ritlcd();
}
else {
flagrit=0;
ddsfreq=freq+ifshift;
// AD9850.wr_serial(0x00,ddsfreq); // <JA2GQP>
Fnc_Dds(ddsfreq); // DDS Out <JA2GQP>
freqt=String(freq);
ucg.setFont(ucg_font_fub11_tr);
ucg.setPrintPos(190,110);
ucg.setColor(255,255,255);
ucg.print("RIT");
ucg.setColor(0,0,0);
ucg.drawRBox(222,92,91,21,3);
freqrit=0;
}
while(digitalRead(ritsw) == LOW);
}
//----------- Rit screen ----------------------
void ritlcd(){
noInterrupts();
ucg.setColor(0,0,0);
ucg.drawBox(222,92,91,21);
ucg.setFont(ucg_font_fub17_tr);
ucg.setColor(255,255,255);
ucg.setPrintPos(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);
ucg.drawRBox(221,61,93,23,3);
ucg.setFont(ucg_font_fub17_tr);
ucg.setColor(255,255,255);
ucg.setPrintPos(220,80);
if (fstep==10){ucg.print(" 10Hz");}
if (fstep==100){ucg.print(" 100Hz");}
if (fstep==1000){ucg.print(" 1KHz");}
if (fstep==10000){ucg.print(" 10KHz");}
}
//----------- Main frequency screen -------------------
void freqlcd(){
ucg.setFont(ucg_font_fub35_tn);
int mojisuu=(freqt.length());
/*
ucg.setPrintPos(19,45);
if(freq>=100000000){
if(f100m !=(freqt.charAt(0))){
ucg.setColor(0,0,0);
ucg.drawBox(19,9,28,36);
ucg .setPrintPos(19,45);
ucg.setColor(0,255,0);
ucg.print(freqt.charAt(0));
f100m = (freqt.charAt(0));
}
}
if(freq<100000000){
ucg.setColor(0,0,0);
ucg.drawBox(19,9,28,36);
}
if (f10m !=(freqt.charAt(mojisuu-8))){
ucg.setColor(0,0,0);
ucg.drawBox(47,9,28,36);
ucg .setPrintPos(47,45);
ucg.setColor(0,255,0);
ucg.print(freqt.charAt(mojisuu-8));
f10m = (freqt.charAt(mojisuu-8));
}
if(freq<10000000){
ucg.setColor(0,0,0);
ucg.drawBox(47,9,28,36);
}
if(fmega !=(freqt.charAt(mojisuu-7))){
ucg.setColor(0,0,0);
ucg.drawBox(75,9,28,36);
ucg .setPrintPos(75,45);
ucg.setColor(0,255,0);
ucg.print(freqt.charAt(mojisuu-7));
fmega = (freqt.charAt(mojisuu-7));
}
if(freq>=1000000){
ucg.setPrintPos(103,45);
ucg.setColor(0,255,0);
ucg.print(".");
}
*/
if(freq<1000000){
ucg.setColor(0,0,0);
ucg.drawBox(103,9,15,36);
}
if(f100k !=(freqt.charAt(mojisuu-6))){
ucg.setColor(0,0,0);
ucg.drawBox(118,9,28,36);
ucg.setPrintPos(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(118,9,28,36);
}
if(f10k !=(freqt.charAt(mojisuu-5))){
ucg.setColor(0,0,0);
ucg.drawBox(146,9,28,36);
ucg.setPrintPos(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(146,9,28,36);
}
if(f1k !=(freqt.charAt(mojisuu-4))){
ucg.setColor(0,0,0);
ucg.drawBox(174,9,28,36);
ucg.setPrintPos(174,45);
ucg.setColor(0,255,0);
ucg.print(freqt.charAt(mojisuu-4));
f1k = (freqt.charAt(mojisuu-4));
}
if(freq>=1000){
ucg.setPrintPos(202,45);
ucg.setColor(0,255,0);
ucg.print(".");
}
if(freq<1000){
ucg.setColor(0,0,0);
ucg.drawBox(202,9,15,36);
}
if(f100 !=(freqt.charAt(mojisuu-3))){
ucg.setColor(0,0,0);
ucg.drawBox(217,9,28,36);
ucg.setPrintPos(217,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(217,9,28,36);
}
if(f10 !=(freqt.charAt(mojisuu-2))){
ucg.setColor(0,0,0);
ucg.drawBox(245,9,28,36);
ucg.setPrintPos(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,320,55,5);
ucg.drawRFrame(1,1,318,53,5);
ucg.setColor(50,50,50);
ucg.drawRBox(5,60,60,25,3);
ucg.drawRBox(75,60,60,25,3);
ucg.drawRBox(5,90,60,25,3);
ucg.drawRBox(75,90,60,25,3);
ucg.setFont(ucg_font_fub17_tr);
ucg.setPrintPos(12,82);
ucg.setColor(0,0,0);
ucg.print("LSB");
ucg.setPrintPos(82,82);
ucg.print("USB");
ucg.setPrintPos(12,112);
ucg.print("C W");
ucg.setPrintPos(82,112);
ucg.print("A M");
ucg.setColor(255,255,255);
ucg.drawRFrame(220,60,95,25,3);
ucg.drawRFrame(220,90,95,25,3);
ucg.setColor(100,100,100);
ucg.setPrintPos(15,200);
ucg.print("S:");
ucg.setPrintPos(15,165);
ucg.print("P:");
ucg.setFont(ucg_font_fub11_tr);
ucg.setColor(255,255,255);
ucg.setPrintPos(175,80);
ucg.print("STEP");
ucg.setPrintPos(190,110);
ucg.setColor(255,255,255);
ucg.print("RIT");
ucg.setColor(100,100,100);
ucg.setPrintPos(40,210);
ucg.print("1-----3-------6-------9---Over--------");
ucg.setPrintPos(40,175);
ucg.print("1-----3----5------------10--------------");
ucg.setPrintPos(10,230);
ucg.setColor(235,0,200);
// ucg.print(" Home Blew DDS-VFO Ver2.0 JA2NKD"); // <JA2GQP>
ucg.print ("Sketch of JA2NKD.JA2GQP added."); // <JA2GQP>
ucg.setFont(ucg_font_fub35_tr);
ucg .setPrintPos(75,45);
ucg.setColor(0,255,0);
ucg.print("7");
ucg.setPrintPos(103,45);
ucg.print(".");
ucg.setPrintPos(273,45);
ucg.print("0");
}
//--------------- DDS Write -------------------------------
void ddswrite(){
// if (flagmode==0){(ifshift=ifshiftLSB);}
// if (flagmode==1){(ifshift=ifshiftCW);}
if (flagrit==0){
ddsfreq=freq+ifshift;
// AD9850.wr_serial(0x00,ddsfreq); // <JA2GQP>
Fnc_Dds(ddsfreq); // DDS out <JA2GQP>
}
if(flagrit==1){
ddsfreq=freq+ifshift+freqrit;
// AD9850.wr_serial(0x00,ddsfreq); // <JA2GQP>
Fnc_Dds(ddsfreq); // DDS out <JA2GQP>
}
}
AD9834への移植、完成する事を祈ります。K3NG Arduino Antenna Tunerのスケッチを少し見ましたが、ライブラリが多いですね。多分、メモリ消費も多いので、IDE1.6.xを使わなければコンパイル出来ないかも知れません。
返信削除EEPROMのメモリ配置がLCD16x2と異なるので、EEPROMをクリアしてください。
返信削除他に原因が有るかも判りません。