dsPIC33FJ64GP802 - PSN SSB ジェネレータ に使用する目的でDDS AD9850 VFOを自作50MHz SSB CWトランシーバー以外にも使用できるように改造しましたが使えませんでした。VFO出力コネクタをSMAコネクタに変更しAD9850出力をBPFフイルタを通さずSMAコネクタに直接接続できるようにしました(ケーブルとBPF基板の差替えで目的のBPFフイルタを入れることができる)プログラムを変更することにより50MHz (規格40MHz)まで周波数設定変更ができます。
回路図
50MHz SSB CW トランシーバー
シャーシは2代目にも流用
オシロスコープ VFO 14MHz 出力波形
秋月電子
・SUPER AKI-80
・AE-DDS
プログラム Arduino Nano VFO出力 14MHz
#include <Rotary.h> // Rotary encoder: https://github.com/brianlow/Rotary
#include <Arduino.h>
#include <LiquidCrystal_I2C.h>
#include <EF_AD9850.h>
// EF_AD9850(CLK,FQ_UP,RESET,DATA)
EF_AD9850 AD9850(9, 10, 11, 8);
//アドレス0x27 16文字2行の液晶
LiquidCrystal_I2C lcd(0x27, 16, 2);
Rotary r = Rotary(2, 3); // Rotary encoder for frequency connects to interrupt pins
//#define A0
//#define A1
//#define A2
#define HoldSW A3
#define StepSW 4
#define RitSW 5
#define OFF 0
#define ON 1
long push = 0;
int Rit = OFF;
int Step = OFF;
int Hold = OFF;
//long unsigned int freq = 1000; // Set initial frequency.
long start_freq = 14000000; //VFO
long end_freq = 14040000;
long freq = 14000000;
long disp_offset = 0;
int offset = 0 ; //dds_frequency offset
//long unsigned int freqOld = freq;
long freqOld = freq;
char disp_buf[16];
char disp_buf2[16];
long stepf = 100; //1Hz 10Hz 100Hz
long ritf = 0;
long ritfOld = 0;
int wr = 0 ; //ad9850 write
void updateDisplay() {
if (freq+disp_offset < 1000) {
sprintf(disp_buf, "%10ld", freq+disp_offset);
}
else if (freq+disp_offset < 1000000) {
int freqL = (freq+disp_offset) % 1000;
int freqM = (freq+disp_offset) / 1000;
sprintf(disp_buf, "%6d,%03d", freqM, freqL);
}
else {
int freqL = (freq+disp_offset) % 1000;
int freqM = ((freq+disp_offset) / 1000) % 1000;
int freqH = (freq+disp_offset) / 1000000;
sprintf(disp_buf, "%2d,%03d,%03d", freqH, freqM, freqL);
}
lcd.setCursor(3, 1);
lcd.print(disp_buf);
lcd.print("Hz");
}
ISR(PCINT2_vect) { //encoder interrupt
if (Rit == OFF && Hold == OFF ){ //rit off ,rx holdsw_off
unsigned char result = r.process();
if (result) {
if (result == DIR_CW) {
if ((freq + stepf) <= end_freq) freq += stepf;
} else {
if ((freq - stepf) >= start_freq) freq -= stepf;
}
if (freq <= 1) freq = 1;
if (freq >= end_freq) freq = end_freq;
}
}
if (digitalRead(RitSW) == HIGH && Rit == ON ){ //rit on
unsigned char result = r.process();
if (result) {
if (result == DIR_CW) {
if ((ritf + stepf) <= 1000) ritf += stepf;
} else {
if ((ritf - stepf) >= -1000) ritf -= stepf;
}
if (ritf >= 10000) ritf = 10000;
if (ritf <= -10000) ritf = -10000;
}
}
}
void setup() {
pinMode(2, INPUT); // Pins for interrupt-driven rotary encoder and push buttons
pinMode(3, INPUT);
pinMode(RitSW, INPUT);
pinMode(StepSW, INPUT);
pinMode(HoldSW, INPUT);
// Configure interrupt and enable for rotary encoder.
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("AD9850");
lcd.setCursor(0, 1);
lcd.print("DDS VFO");
delay(2000);
lcd.clear();
// Initialise the AD9850 module.
AD9850.init();
AD9850.reset();
AD9850.wr_serial(0x00, freq+offset);
updateDisplay();
lcd.setCursor (10, 0);
lcd.print(" _"); //10hz
}
void loop() {
if (digitalRead(StepSW) == LOW ) {
push++;
if (push > 50 ){
Step = !Step;
push = 0;
}
if (Step == ON ){
stepf = 100;
lcd.setCursor (10, 0);
lcd.print("_ ");
}
else{
stepf = 10;
lcd.setCursor (10, 0);
lcd.print(" _");
}
}
if (digitalRead(HoldSW) == LOW ) {
push++;
if (push > 400 ){
Hold = !Hold;
push = 0;
if (Hold == ON ){
lcd.setCursor (15, 1);
lcd.print("H");
}
else{
lcd.setCursor (15, 1);
lcd.print(" ");
}
}
}
if (digitalRead(RitSW) == LOW ) {
push++;
if (push > 500 ){
Rit = !Rit;
push = 0;
if (Rit == ON ){
lcd.setCursor (13, 0);
lcd.print("RIT");
}
else{
lcd.setCursor (13, 0);
lcd.print(" ");
}
}
}
if (digitalRead(RitSW) == HIGH && Rit == ON ){ //rx rit_on
stepf = 1; //1HZ
while(digitalRead(RitSW) == HIGH ){
if (ritfOld != ritf) {
AD9850.wr_serial(0x00, freq+offset+ritf);
ritfOld=ritf;
lcd.setCursor (3, 0);
sprintf(disp_buf2, "%10ld", ritf);
lcd.print(disp_buf2);
lcd.print("RIT");
}
if(wr=10000) { //ad9850 write 1/10000
AD9850.wr_serial(0x00, freq+offset+ritf);
wr=0;
}
wr=wr+1;
lcd.setCursor (3, 0);
sprintf(disp_buf2, "%10ld", ritf);
lcd.print(disp_buf2);
lcd.print("RIT");
}
ritf = ritfOld;
ritfOld = ritfOld;
freq = freqOld;
freqOld = freqOld;
lcd.setCursor (9, 0);
lcd.print(" _ "); //step
stepf = 10;
Rit = OFF;
}
if (freqOld != freq) {
AD9850.wr_serial(0x00, freq+offset);
updateDisplay();
freqOld = freq;
}
if(wr=10000) { //ad9850 write 1/10000
AD9850.wr_serial(0x00, freq+offset);
wr=0;
}
wr=wr+1;
}

.png)
0 件のコメント:
コメントを投稿