Quantcast
Channel: JH7UBCブログ
Viewing all 440 articles
Browse latest View live

Si5351Aその7

$
0
0
 Si5351Aを使ったVFOを作りたいと思い、この2週間ほど、Si5351の説明書を読んだり、Webサイトを参考にしたりして、実験をしていました。

 参考にしたWebサイトは、



 そして、ML仲間のJA2GQP局のブログ 「JA2GQP's BLOG」 です。

 JA2GQP局のブログのスケッチでは、Hans Summers氏作のヘッダーファイルが使われています。

 任意の周波数を発生させるには、どのようにPLLレジスタとMultiSynthレジスタを設定したらよいのでしょうか。

 計算式を再度掲載します。
 イメージ 1
 
 さて、問題は、希望の周波数foutに対して、上記のa,b,cをどのような値にしたらよいかです。

 混乱しやすいのですが、実は、PLL周波数設定用のa,b,cと出力分周器設定用のa,b,cは別物なのです。

 そこで、分周器設定用のa,b,cをd,e,fとして、各値(a~f)の計算方法は、次のようになります。

イメージ 1

 JA2GQP's ブログで使われているスケッチでは、c の最大値 c=denom=1048757が、使われています。

PLLの周波数を設定するa,b,c,d(mult,num,denom,divider)とパラメータP1,P2,P3を計算するスケッチは、次のようになります。(Hans Summers氏作です)
(uint32_t は、符号なし32ビットで、unsigned longと同じです。uint8 は符号なし8ビットで、byteと同じです。)

  uint32_t P1;
  uint32_t P2;
  uint32_t P3;
  uint32_t pllFreq;
  uint32_t l;
  float f;
  uint8_t mult;
  uint32_t num;
  uint32_t denom;
  uint32_t divider;
  divider = 900000000 / frequency;
  if (divider % 2) divider--;
  pllFreq = divider * frequency;
  mult = pllFreq / xtalFreq;
  l = pllFreq % xtalFreq;
  f = l;
  f *= 1048575;
  f /= xtalFreq;
  num = f;
  denom = 1048575;
 
  P1 = (uint32_t)(128 * ((float)num /(float)denom));
  P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
  P2 = (uint32_t)(128 * ((float)num / (float)denom));
  P2 = (uint32_t)(128 * num -denom * P2);
  P3=denom;

このパラメータをPLLAにセットアップするスケッチです。
(MSNA_ADDRは、PLLAパラメータセットアドレスの先頭アドレス26です)

 Si5351_write(MSNA_ADDR + 0,(P3 & 0x0000FF00) >> 8);
  Si5351_write(MSNA_ADDR + 1,(P3 & 0x000000FF));
  Si5351_write(MSNA_ADDR + 2,(P1 & 0x00030000) >> 16);
  Si5351_write(MSNA_ADDR + 3,(P1 & 0x0000FF00) >> 8);
  Si5351_write(MSNA_ADDR + 4,(P1 & 0x000000FF));
  Si5351_write(MSNA_ADDR + 5,((P3 & 0x000F0000) >> 12) | ((P2 & 0X000F0000) >> 16));
  Si5351_write(MSNA_ADDR + 6,(P2 & 0x0000FF00) >> 8);
  Si5351_write(MSNA_ADDR + 7,(P2 & 0x000000FF));

分周器MS0のパラメータの計算は、
d=divider  e=0   f=1 として、上記のPLL周波数の計算とレジスタセットと同様に行います。
MS0の先頭アドレスは、42です。

なお、スケッチ全体は、VFOができた時点で掲載します。


Si5351Aその8

$
0
0
 Si5351Aのコントロールの実験をしています。

 これまでは、PLLAとMS0を使い、1チャンネルのみの実験でした。

 Si5351Aは、2つのPLLと3つのMultSynth(分周器)を持ち、3チャンネルの出力が可能です。

 マルチチャンネル化について考えてみます。

 まず、Si5351Aの内部構造と関係するレジスタを下図に示します。

イメージ 1

PLLAを使うのかPLLBを使うのかは、Register16~18のビット5で設定します。

bit5=0 でPLLA bit5=1でPLLBが選択されます。(デフォルトは、0 つまりPLLA)

R0~R2は、各チャンネルのOutput Dividerで、Register44,52,60のbit6~bit4で設定します。

分周比は000~111で1/1~1/128です。必要によって設定しますが、通常はデフォルトの000=1/1です。

更に、出力をコントロールするドライバーは、Redister16~18のbit1,0で設定します。

00: 2mA~11: 8mAの4段階で制御できます。

これらのレジスタとPLLA,,PLLB,MS0,MS1,MS2を適宜に設定することにより、独立した2つの周波数とPLLAまたはPLLBどちらかをソースにして、MultiSynthの設定により、3つ目の周波数を発生させることができます。

Si5351Aその9

$
0
0
 Si5351Aで3チャンネル出力の実験をしました。

 上がPLLA MS0の組み合わせで CLK0=1MHz
 中がPLLB MS1の組み合わせで CLK1=10MHz
 下がPLLB MS2の組み合わせで CLK2=5MHzの設定です。

イメージ 1

 CLK0,CLK1,CLK2をPLLA,PLLBどちらに接続するかは、レジスタ16,17,18のビット5で設定します。

 ビット5=0 で PLLAに、 1でPLLBも接続されます。

 テストしたスケッチです。スケッチサイズは、約4KBです。(まだ中途半端ですが、参考までに)

#include <Wire.h>
#define  Si5351A_ADDR  0x60
#define MSNA_ADDR   26
#define MSNB_ADDR   34
#define MS0_ADDR    42
#define MS1_ADDR    50
#define MS2_ADDR    58
#define CLK0_CTRL   16
#define CLK1_CTRL   17
#define CLK2_CTRL   18
#define OUTPUT_CTRL  3
#define XTAL_LOAD_C 183
#define PLL_RESET  177
uint32_t frequency;
const uint32_t XtalFreq = 25000000;
uint32_t P1;
uint32_t P2;
uint32_t P3;
uint32_t PllFreq;
uint32_t l;
float f;
uint8_t mult;
uint32_t num;
uint32_t denom;
uint32_t divider;
char  PLL;
uint8_t PLL_ADDR;
uint8_t MS_ADDR;

void setup(){
  Wire.begin();       // Arduino is Master
  Si5351_init();      //Si5351Aの初期化
 
//PLLA=900MHz,CLK0=1MHz
  frequency = 1000000;
  divider = 900000000 / frequency;
  if (divider % 2) divider--;
  PLL_Set('A',frequency,divider);
  Si5351_write(CLK0_CTRL,0x4F); //CLK0 Sorce PLLA
  MS_Set(0,divider);
//PLLB=900MHz
  frequency = 10000000;
  divider = 900000000 / frequency;
  if (divider % 2) divider--;
  PLL_Set('B',frequency,divider);
//CLK1=10MHz
  Si5351_write(CLK1_CTRL,0x6F); //CLK1 Sorce PLLB
  MS_Set(1,divider);
//CLK2=5MHz
  Si5351_write(CLK2_CTRL,0x6F); //CLK2 Sorce PLLB
  divider=divider*2;
  MS_Set(2,divider);
}
void loop(){
}

//Si5351のレジスタに1バイトデータを書き込む。
void Si5351_write(byte Reg , byte Data)
{
  Wire.beginTransmission(Si5351A_ADDR);
  Wire.write(Reg);
  Wire.write(Data);
  Wire.endTransmission();
}

//Si5351Aの初期化
void Si5351_init(){
  Si5351_write(OUTPUT_CTRL,0xFF);   //Disable Output
  Si5351_write(CLK0_CTRL,0x80);     //CLOCK0 Power down
  Si5351_write(CLK1_CTRL,0x80);     //CLOCK1 Power down
  Si5351_write(CLK2_CTRL,0x80);     //CLOCK2 Power down
  Si5351_write(XTAL_LOAD_C,0x80);   //Crystal Load Capasitance=8pF
  Si5351_write(PLL_RESET,0xA0);     //Reset PLLA and PLLB
  Si5351_write(CLK0_CTRL,0x4F);     //CLOCK0 Power up
  Si5351_write(CLK1_CTRL,0x4F);     //CLOCK0 Power up
  Si5351_write(CLK2_CTRL,0x4F);     //CLOCK0 Power up 
  Si5351_write(OUTPUT_CTRL,0xF8);   //Enable CLOCK0,CLOCK1,CLOCK2
}

//PLLの設定
void PLL_Set(char Pll,uint32_t Freq,uint32_t Div){
  PllFreq = Div * Freq;
  mult = PllFreq / XtalFreq;
  l = PllFreq % XtalFreq;
  f = l;
  f *= 1048575;
  f /= XtalFreq;
  num = f;
  denom = 1048575;
 
  P1 = (uint32_t)(128 * ((float)num /(float)denom));
  P1 = (uint32_t)(128 * (uint32_t)(mult) + P1 - 512);
  P2 = (uint32_t)(128 * ((float)num / (float)denom));
  P2 = (uint32_t)(128 * num -denom * P2);
  P3=denom;
  if (Pll == 'A')
  {
    PLL_ADDR = MSNA_ADDR;
  }else
  {
    PLL_ADDR = MSNB_ADDR;
  }
  Parameter_write(PLL_ADDR,P1,P2,P3);
 }
//MultiSynth(分周器)のセット
void MS_Set(uint8_t MS_No,uint32_t Div){
  P1 = 128 * Div - 512;
  P2 = 0;
  P3 = 1;
  switch(MS_No){
    case 0:
      MS_ADDR = MS0_ADDR;
    break;
    case 1:
      MS_ADDR = MS1_ADDR;
    break;
    case 2:
      MS_ADDR = MS2_ADDR;
      break;
    default:
      MS_ADDR = MS0_ADDR;
  }
  Parameter_write(MS_ADDR,P1,P2,P3); 
}
//レジスタにパラメータP1,P2,P3を書き込む。
 void Parameter_write(uint8_t REG_ADDR,uint32_t Pa1,uint32_t Pa2,uint32_t Pa3)
{
  Si5351_write(REG_ADDR + 0,(Pa3 & 0x0000FF00) >> 8);
  Si5351_write(REG_ADDR + 1,(Pa3 & 0x000000FF));
  Si5351_write(REG_ADDR + 2,(Pa1 & 0x00030000) >> 16);
  Si5351_write(REG_ADDR + 3,(Pa1 & 0x0000FF00) >> 8);
  Si5351_write(REG_ADDR + 4,(Pa1 & 0x000000FF));
  Si5351_write(REG_ADDR + 5,((Pa3 & 0x000F0000) >> 12) | ((Pa2 & 0X000F0000) >> 16));
  Si5351_write(REG_ADDR + 6,(Pa2 & 0x0000FF00) >> 8);
  Si5351_write(REG_ADDR + 7,(Pa2 & 0x000000FF)); 
}

Si5351Aその10

$
0
0
 今朝起きると、今季初の本格的な雪で積雪は約30cmになりました。

 除雪をしてから、今日は少しだけSi5351Aの実験をしました。

 まず、出力反転の実験。

 レジスタ16,17,18のビット4を1にすることによって、CLK0,1,2それぞれの信号を反転させることができます。

 1MHzをCLK0からnot inverted出力、CLK1からinverted出力した時の波形です。

イメージ 1

 次に、CLKの出力をON/OFFする実験。

 レジスタ3(Output Enable Control)のビット0,1,2で、出力をON/OFFします。

 0で出力ON、1で出力OFFです。

 CLK0に1MHzを発生させ、100msごとにON/OFFしてみました。

イメージ 2

なぜか、スパイクが目立ちますが、きれいにON/OFFされます。

トランシーバを製作するときなどにこの機能を使うことになります。


Si5351Aその11

$
0
0
 3チャンネルクロックジェネレータSi5351Aの勉強も位相関係などを除き、コントロールできるようになりました。

 いよいよ、VFOを作ってみます。とりあえず、7MHz用のVFOを試作してみました。

イメージ 1
Arduino NANOを使い、表示は、NOKIA5110です。

回路図は下のとおりです。

イメージ 2

スケッチの基本はJA2GQP局のブログに掲載されているスケッチを今回の勉強で作成したスケッチで書き直しています。

今、7MHzのVFOとしてテストしていますが、様々な応用が可能です。

スケッチが完成しましたら、JH7UBCホームページに掲載したいと思います。

Si5351Aの記事UP

$
0
0
 ここ1か月ほどかけて、のんびりと勉強してきたSi5351Aについての記事をまとめて、JH7UBCホームページに掲載しました。

 とりあえず、Lチカに相当する部分で、10MHzの信号を発生させるまでを、Arduino UNOで実験した記事です。

 ブログでは、Si5351Aその1~その5までの部分です。

 この後、任意の周波数を発生させる方法、VFO化などについて掲載予定です。

HFのコンディションBF

$
0
0
 毎週水曜日21時からFCWA(福島CW愛好会)のCWの交信会を行っています。

 私がキー局を担当し、3.520MHz付近で、

 CP FCWA CP FCWA DE JH7UBC JH7UBC PSE K
 
 と送信して、FCWA各局が応答するという形式で交信会をします。

 しかし、このところHF帯のコンディションが悪く、21時過ぎには3.5MHzでは、近距離、場合によっては、国内さえ聞こえません。

 今夜も21時から5分間、CP FCWAを出し続けましたが、応答はありませんでした。(正確には聞こえませんでした)

 Space Wheather Servicesというサイトを見るとF2層の反射が2MHzと厳しい状況でした。

イメージ 1

 今日は、冬至ということもありますが、太陽活動が不活発な時期が続くと、しばらくの間はこんな状況が続くのではないかと心配しています。

Arduino レシプロカル式カウンタ(7セグメントLED表示)

$
0
0
 Si5351Aの勉強が一段落しましたので、今年の課題のうち、簡単そうなものを一つ片付けました。

 以前に製作したAreduinoレシプロカル式周波数カウンタを7セグメントLED表示にする実験をしました。

 レシプロカル式とは、逆数式という意味で、信号の周期Tを測定して、その逆数を計算することによって、周波数fを得る方式です。つまりf = 1/T の式を使います。

 7セグメントLEDは、秋月電子で販売している超高輝度4桁7セグメントLED(OSL-40562-LRA)を使います。

 約5mAで十分な輝度が得られると書いてあります。予備実験をしました。

イメージ 1

 5Vの電圧のとき、電流制限抵抗が、680Ωの時、電流は4.5mAで、十分な輝度が得られました。

 ということは、7セグメントすべて点灯(8のとき)したとの電流が最大で、31.5mAとなり、Arduinoのデジタルポートで、ドライブできます。

 7セグメントLEDは、ダイナミック点灯です。

 周期の測定は、外部割り込みattachInterrupt(interrupt,function,mode)を利用し、割り込み番号は0(ピン2)、トリガは立ち上がり(RISING)とします。

 回路図です。

イメージ 2

ブレッドボードです。

イメージ 3

スケッチです。

/*
 *レシプロカル式周波数カウンタ
 *7セグメントLEDダイナミック点灯
 * 2016.12.29
 * JH7UBC Keiji Hata
 *
 *   D2   INPUT
 *   D3   7segLED A
 *   D4   7segLED B
 *   D5   7segLED C
 *   D6   7segLED D
 *   D7   7segLED E
 *   D8   7segLED F
 *   D9   7segLED G
 *   D10  7segLED #1
 *   D11  7segLED #2
 *   D12  7segLED #3
 *   D13  7segLED #4
 */

volatile unsigned long duration=0;
volatile unsigned long prevMicros=0;
unsigned int frequency;
int ZeroFlag;    //ゼロフラッグ
int N[4];        //表示する数字(4桁)
int Nx;
//LED レイアウト定義 A,B,C,D,E,F,Gセグメントの順
boolean Num_Array[11][7]={
  {1,1,1,1,1,1,0}, //0
  {0,1,1,0,0,0,0}, //1
  {1,1,0,1,1,0,1}, //2
  {1,1,1,1,0,0,1}, //3
  {0,1,1,0,0,1,1}, //4
  {1,0,1,1,0,1,1}, //5
  {1,0,1,1,1,1,1}, //6
  {1,1,1,0,0,1,0}, //7
  {1,1,1,1,1,1,1}, //8
  {1,1,1,1,0,1,1}, //9
  {0,0,0,0,0,0,0}  //space
  };
//LED配列 
boolean Led_Array[4][4]={
  {0,1,1,1},  //LED1
  {1,0,1,1},  //LED2
  {1,1,0,1},  //LED3
  {1,1,1,0}   //LED4
};

void setup()
{
  attachInterrupt(0, periodIrq, RISING);
  for (int i=3;i<=13;i++)   //pin2~13を出力に設定
  {
    pinMode(i,OUTPUT);
  }
}
void loop()
{
  frequency = 1000000 / duration; //f=1/T
  Num_set(frequency);             //周波数の値をN[0]~N[3]にセット
  int var = 0;
  while(var < 20){                   //20の値は、要調節
   for(int i=0;i<4;i++){
      LedActive(i);
      NumPrint(N[i]);
      delay(6);
      NumPrint(10);     //一旦表示を消す
  }
  var++;
  }
}
void periodIrq() // interrupt handler
{
  unsigned long currentMicros = micros();
  duration = currentMicros - prevMicros;
  prevMicros = currentMicros;
}
//数字表示
void NumPrint(int Number){
  for (int w=0; w<=6; w++){
  digitalWrite(w+3,Num_Array[Number][w]);
  }
}
//LED点灯
void LedActive(int Number){
  for (int w=0; w<=3; w++){
    digitalWrite(w+10,Led_Array[Number][w]);
  }
}
//数字の分解(1000の位、100の位、10の位、1の位)とセット
void Num_set(int X){
  ZeroFlag=1;
  N[0] = X / 1000;
  if (N[0] == 0){
    N[0]=10;        //10=space
  }else{
    ZeroFlag=0;
  }
  Nx = X % 1000;
  N[1] = Nx / 100;
  if (N[1] == 0 & ZeroFlag == 1){
    N[1]=10;
  }else{
    ZeroFlag = 0;
  }
 
  Nx = X % 100;
  N[2] = Nx / 10;
  if (N[2] == 0 & ZeroFlag ==1){
    N[2]=10;
   }
  N[3] = X % 10;
}

このスケッチで10Hz~5000Hzまで、OKです。

こんな低い周波数しか測れないカウンタが、どうして必要なのかと言いますと、普通の周波数カウンタは、1秒ごとにしか周波数を測定すりことができません。(0.1秒の場合もあります)レシプロカル式は、1周期の時間があれば良いので、極端なことを言えば、1000Hzは1/1000秒=1msecあれば周波数を測定することができます。

つまり、短い時間で周波数を測定したい時に有効なカウンタなのです。

使い方としては、楽器のチューニングやドップラー効果の測定などが考えられます。


第8回FQP結果発表

$
0
0
 今年初めての記事です。今年もよろしくお願いします。

 昨年12月3日(土)に開催された第8回FCWA CW QSOパーティの結果をFCWAのホームページに掲載しました。

 一般部門75局、QRP部門14局、計89局からログが提出されました。ありがとうございます。

イメージ 1


 今年は、コンディションが悪く、特にハイバンドは全然だめでした。したがって、7M以下のローバンドでの交信が中心になりました。

 提出方法は、ほとんどメールで1局のみ郵送でいただきました。

イメージ 2

 ログの種類は、CTESTWINが最も多く、次がlogsheetform、HLTSTの順でした。

イメージ 3

 参加局のエリアは1エリア、7エリア、4エリア、3エリアの順でした。

イメージ 4

 出力は50Wが最も多く、次に100W、QRP(5W以下)、200W、10Wの順でした。

イメージ 5

 コンディションが悪かったのですが、各局それぞれ楽しんでいただいたようです。

 次回のパーティもご参加よろしくお願いします。

 FCWA CW QSOパーティ マネージャー JH7UBC 畠 惠治

Aeduino レシプロカル式周波数カウンタその2

$
0
0
 先日試作したArduino レシプロカル式周波数カウンタをArduino NANOを使い基板に組みました。

 エレクトレットコンデンサマイクにLM358オペアンプ(増幅率100倍)で増幅してArduinoに入力しています。

 電源は、006Pを使い、78L05で5Vに落としています。電流は約40mAです。

イメージ 1

回路図です。

イメージ 3


自作のファンクションジェネレータで約1000Hzを発生させてスピーカーから音を出し、マイクでひろってカウントしてみました。

イメージ 2

±1Hz程度で表示します。

 感度はそれほど高くありませんが、雑音に反応しないので、ちょうど良いかもしれません。

 スケッチは、前回の記事とほぼ同じです。

 周波数表示のレスポンスが良いので、受信時のCWのトーン周波数の測定などに、とりあえず使ってみましょう。

 基板は、アルミ板に固定しただけです。実際のケーシングは後ほど行います。

PIC16F628A 883周波数カウンタの製作その1

$
0
0
 このところの大雪で毎日除雪に汗を流しています。どうも年のせいか若干疲れ気味です。

 昨年夏に7セグメントLED表示のPIC16F883周波数カウンタを試作しました。記事はこちら

 このカウンタは、LEDをダイナミック点灯させるために、1秒のゲート時間を作る場合と16ビットカウンタのオーバーフロー時に割り込みを利用しています。

 割り込みがかち合うことがあるせいか、特定の周波数を測定したときに測定誤差が大きくなりました。

 そこで、周波数測定部と表示部を分けて、周波数測定部はPIC16F628Aを表示部には、PIC16F883を使った周波数カウンタを製作しました。

イメージ 2

イメージ 3


イメージ 1

 周波数測定部は、以前に製作したPIC16F648A周波数カウンタのプログラムを流用しました。

 PIC16F628AとPIC16F648Aの違いは、メモリ、SRAM、EEPROMのサイズの違いで、今回は、PIC16F628Aで十分です。
 周波数表示部は、LEDをダイナミック点灯するために、入出力が多いPIC16F883を使いました。

 周波数測定部で測定した周波数データは、シリアル通信(19200bps)で周波数表示部に送ります。

 PIC16F883は、周波数をダイナミック点灯で表示します。データを受信したとき割り込みが発生し、表示データが更新されます。

 今回の周波数カウンタでは、各周波数を問題なく測定できました。電源は5Vで電流は約30mAです。

 ケースとしては、タカチのYM-150を考えています。ケースに入れて常用のカウンタにしたいと思います。

 次回は、周波数測定部の詳細について説明します。

 

PIC16F628A 883周波数カウンタの製作その2

$
0
0
 PIC16F628A 883周波数カウンタの周波数測定部の説明をします。基本的には「電子工作etc」といいうWebサイトに掲載されエイル周波数カウンタV7のアルゴリズムを使わせていただいています。

 PIC16F628Aには、外部クロックTCXO(温度補償型水晶発振器)12.8MHzを供給します。

 ゲートタイムは、TMR2を使い1秒を作り出します。詳しくは私のホームページ「JH7UBCホームページ」のPIC16F883周波数カウンタの試作の記事を参照してください。

 PIC16F628AのTMR2は、8ビットカウンタですが、プリスケーラとポストスケーラを持っています。T2CONで、プリスケーラ1:16、ポストスケーラ1:1にセットします。

 TMR2は8ビットカウンタですので、プリスケーラと組み合わさりクロック16×256個ごとにオーバーフローが発生します。この時、TMR2オーバーフロー割り込みが発生しますので、この割り込み回数をカウントして(実際にはカウントダウンして)1秒を作ります。

 周波数カウンタ本体は、TMR1(16ビットカウンタ)を使います。TMR1だけで、65535Hzまで測定可能ですが、TMR1のオーバーフローをカウントすることにより、より高い周波数までカウントすることができます。

 オーバーフローの回数は、例えば入力周波数が65.536MHzなら1000回と1msに1回となり、割り込みを使わなくともプログラムの中で処理ができます。具体的には、

;===== 測定 =====
FREQ
  BTFSS T2CON,TMR2ON ;TMR2ON=1ならスキップ
  GOTO MSTOP   ;TMR2ON=0なら測定終了
  BTFSS PIR1,TMR1IF  ;TIMER1がオーバーフローしたらスキップ
  GOTO FREQ
  BCF  PIR1,TMR1IF  ;TMR1IFクリア
  INCFSZ BYTE2   ;BYTE2+1 0ならスキップ
  GOTO FREQ
  INCF BYTE3   ;BYTE3+1
  GOTO FREQ

という具合に測定ルーチンの中で処理しています。

 測定が終わるとバイナリーBCD変換でTMR1(BYTE0+BYTE1)+BYTE2+BYTE3の32ビット(4バイト)の2進数を4バイトのBCD(10進化2進)に変換します。

 このBCDコードを上位から4ビットずつアスキーコードにして全8バイト+CRコード(0Dh)をシリアル通信で表示部に送信しまうす。

 アスキーコードで送信するのは、周波数測定部のチェックをするときにパソコンの通信ソフト(TerraTermを使っています)で容易に確認できるからです。

 シリアル通信は、PIC16F628AのUSARTを使いボーレートは、19200bpsとしました。

 USARTの設定はTXSTAとRCSTA、SPBRGで次のように行います。

 ;=== USARTの初期化 ===
  BANKSEL TXSTA
  MOVLW 0x24  ;非同期モード、高速通信モード
  MOVWF TXSTA  ;set TX mode
  MOVLW d'41'  ;12.8MHz, 19200bps
  MOVWF SPBRG  ;ボーレートセット
  BANKSEL RCSTA
  MOVLW 90h   ;RB1,RB2をシリアルポートに
  MOVWF RCSTA

 以上、勘所のみ説明をしました。アセンブラのソースリストは後程JH7UBCブログに掲載します。

 最後に回路図です。

イメージ 1

 次回は、周波数表示部について説明します。

PIC16F628A 883周波数カウンタの製作その3

$
0
0
 PIC16F628A 883周波数カウンタの表示部について説明します。

 表示部は、PIC16F883を使用しています。8桁の7セグメントLEDを動かすためには、8+7=15のポートが必要です。このため、24個のI/Oを持つこのPICにしました。

 7セグメントLED(秋月電子のOSL-40562-LB)は、ダイナミック点灯としています。

 プログラムのメインループは、ダイナミック点灯に使い、データをシリアル通信でデータを受信したときに発生する割り込みにより、表示データを更新します。 通信速度は、19200bpsです。

 カソードコモンのLEDはデジタルトランジスタDTC114でドライブしています。これにより抵抗を8本省略できます。

 PIC16F883は、内部子ロック8MHzで動作させています。

 周波数測定部からは、周波数データがASCIIコードで送られてきますので、ASCIIコード一旦BCDに変換し、それをLED表示用のデータに変換しています。

 ASCIIコードのスペース(20h)は、00hに変換することにより、LEDが消灯されます。

; ------------------------------------------------
; BCD4ビットを7セグメントLED表示用に変換するサブルーチン
;-------------------------------------------------
BCD2LED
 ADDWF PCL,F
 RETLW 03Fh ;0
 RETLW 006h ;1
 RETLW 05Bh ;2
 RETLW 04Fh ;3
 RETLW 066h ;4
 RETLW 06Dh ;5
 RETLW 07Dh ;6
 RETLW 007h ;7
 RETLW 07Fh ;8
 RETLW 06Fh ;9
 RETLW 040h ;a
 RETLW 040h ;b
 RETLW 040h ;c
 RETLW 040h ;d
 RETLW 040h ;e
 RETLW 040h ;f

回路図です。

イメージ 1

 1桁当たりの表示時間を当初3msとしましたが、ちらつきを感じましたので、約1.6msとしました。

イメージ 2


PIC16F628A/648A動かない?

$
0
0
 PIC16F628A PIC16F883周波数カウンタのプログラミングが終わりましたが、もう少しPICで遊んでみようと思います。
 一昨年、AD9834DDSをPIC16F883のSPIでコントロールしようと思ってやったのですが、うまくいかず、結局Arduinoでコントロールすることになりました。このVFOは、7MHz用のアカギスタンダードに使用しました。

 もう一度PICでのAD9834DDSのコントロールに挑戦してみようと思います。

 PICは、カウンタにも使用したPIC16F628Aを使ってみましょう。

 PIC16F628Aの様々なテストをするために、電池(3V)駆動で、簡単なプログラムを組んでみましたが、動きません。
 プログラムのチェック、配線のチェックをしても、うんともすんとも言いません。

 うーーーん。

 ひょっとして、電源か、と思い、5Vの電源をつないだら、動きました!

 Webで調べてみるとPIC16F628A/648Aでは、ブラウンアウトリセットがON(有効)になって入ると4.5V以下では動作しないんだそうです。ふーーんそうなんだ。

 __CONFIG で _BROREN_OFFとしてみたら、電池3Vでちゃんと動きました。

 PICも気が付かないところに落とし穴があるものですね。

AD9834DDSをPICで制御する実験

$
0
0
 AD9834DDSをPICで制御する実験は、一昨年、PIC16F883のMSSPモジュールを使って行いました。

 しかし、上手くいかずに中断して、Arduinoでの制御に切り替えて動作させました。

 Arduino(あちゃんでいいの)で制御したAD9834DDSを使ったVFOは、7MHz用のアカギスタンダードに搭載して実際の交信に使っています。

 今回は、PIC16F628AでAD9834DDSを制御する実験を行い、うまくいきましたので、記事を掲載したいと思います。

 今更とも思うのですが、PICを使ったAD0934DDS制御の例はWeb上には少なく、アセンブラで記述された例はほとんど見ません。


 この記事とArduinoでの制御スケッチを見て気づいたのですが、AD9834を制御するSPI信号のシリアルタイミングに問題があって、動かなかったようです。

 そこで、再度AD9834DDSの説明書(日本語版)を見ると、シリアルタイミングは次のようになっています。

イメージ 1
まず、FSYNCをLOWにしてから、SDATAを有効にして、クロックSCLKの立下りで、DDSにデータが読み込まれます。

次のようなアセンブラプログラム(サブルーチン)を作って試してみました。
D1,D0にDDSに送るデータ(8+8=16ビット)を入れておきます。

SPI_SEND
    MOVLW d'16'  ;送信ビット数
    MOVWF DCNT  ;カウンタにセット
    BCF  SPI_FS  ;FSYNC=LOW SPI start
SPI_LOOP
    BCF  STATUS,C ;Cクリア
    RLF  D0,F  ;左に1ビットシフト
    RLF  D1,F
    BTFSC STATUS,C ;C=0ならスキップSDATA=0
    GOTO DATA1  ;C=1ならSDATA=1
    BCF  SPI_DA
    GOTO NEXT
DATA1
    BSF  SPI_DA
NEXT
    BCF  SPI_CK  ;SCLK=LOW
    BSF  SPI_CK  ;SCLK=HIGH
    DECFSZ DCNT  ;DCNT=0ならスキップ
    GOTO SPI_LOOP
    BSF  SPI_FS  ;FSYNC=HIGH SPI end
    RETURN

 MPLAB IDEのロジックアナライザでシミュレーションしてみると次のようになります。

イメージ 2

 一見、説明書の図とは違って見えますが、タイミングは指定どおりです。

 PIC16F628Aは、内部クロック4MHzで動作させますので、1サイクルは1usです。従ってSCLKのパルス幅は、1usです。

 実験回路の回路図です。

イメージ 3

 AD9834DDSの制御方法については、私のホームページ(JH7UBCホームページ)の記事をご覧ください。

 今回は、1MHzを発生させるプログラムを作りました。

 ブレッドボードと周波数カウンタの様子です。

イメージ 4

 なお、プログラムの詳細は、次回掲載します。

 これにディスプレイとロータリーエンコーダを加えて、VFOに仕上げてみたいと思っています。

AD9834DDSをPICで制御する実験その2

$
0
0
 前の記事では、主にAD9834DDSを制御するSPI(Serial Peripheral Intrerface)について書きました。

 今回は、周波数データ(バイナリ)からDDSに送るデータをどのように生成するかを書きます。

 周波数データ f(Hz) は、4バイト(32ビット)とし、F3,F2,F1,F0に格納します。

 DDSは、f = ΔPhase ×fmclk / 2^28 という関係式で目的の周波数 f を生成します。

 ここで、ΔPhaseがDDS用のデータで、fmclkは、DDSのマスタークロックです。

 DDS用のマスタークロックは、今回 67.108864MHz=2^26Hzを使っていますので、この値をfmclkに代入すると

 f = Δphase × 2^26 / 2^28 = ΔPhase / 2^2 となります。

 従って、DDS用データは、ΔPhase = f × 2^2 となり、周波数データを4倍すれば良いことになります。

 周波数データを4倍するのは簡単で、fのデータ(F3,F2,F1,F0)を全体的に左に2ビットシフトすれば良いのです。

 周波数データは、表示などにも使いますので、一旦DDS用のデータを格納するP3,P2,P1,P0に移して、下位から、つまりP0から左に1ビットシフトします。更に1ビットシフトを繰り返し、全体的に2ビット左にシフトします。

 アセンブラでは、

 SHIFT_L2
      BCF STATUS,C ;C=0
      RLF P0,F
      RLF P1,F
      RLF P2,F
      RLF P3,F
      BCF STATUS,C ;C=0
      RLF P0,F
      RLF P1,F
      RLF P2,F
      RLF P3,F
      RETURN

 レジスタを左にシフトした場合最上位ビットがキャリーCに入ります、前のCの値は再開ビットに入ります。
 最初にキャリーCをクリアしておいて、最下位バイトから左シフトを繰り返せば、全体的に左に1ビットシフトできます。これを2回繰り返します。

 例えば、1MHz=1000000Hz=0x00 0F 42 40 ですので、左に2ビットシフトすると0x00 3D 09 00となり、これがDDSに送るデータになります。(実際のDDSデータは28ビットですから、このデータの下位から28ビットがデータになります)

 AD9834DDSでは、制御データや周波数データは、16ビットずつMSB(最上位ビット)FirstでSPI通信で送ります。

 この送り方のパターンはいくつかあるのですが、典型的なケースについて説明します。

 最初にコントロールワード(16ビット)を送ります。上位1ビットD15,D14を00にすれば、コントロールデータになります。
 D13が、周波数データをどのように送るかを指定するビットで、1にすると28ビットの周波数データを下位、上位の順に2回送ることを指示することになります。

 D12~D0は、全て0として、コントロールワードは、0x20とし、最上位ビットから16ビットをSPIでDDSに送ります。

 次に、周波数データの下位14ビットに、レジスタをしてするビットD15,D14を加えて送信します。D15=0.D14=1でFREQレジスタ0を指定します。(FREQレジスタは、独立して0と1があります。)

 DDS用データP3,P2,P1,P0のP1,P0から下位から14ビットを送信用データD1,D0に移し、上位2ビットに01を加えてSPIでDDSに送信します。

 次に、P3,P2,P1,P0を全体的に2ビット左にシフトし、P3,P2の下位14ビットをD1,D0に移し、上位2ビットに01を加えて、送信します。

 以上で、目的周波数のデータがDDSにセットされ、目的周波数が発生します。

 けっこう回りくどいですが、何かの参考になれば幸いです。
 

2016 6m & down comntest賞状

$
0
0
 本日、JARLから2016年の6m and downコンテストの賞状が届きました。

イメージ 1

 スコアは、伸びなかったのですが。何とか東北地区1位を獲得できました。

 さて、今年もまた50M CWで頑張ってみたいと思います。

喜多方そばフェスタ

$
0
0
 今年も蔵のまち喜多方冬まつりの季節になりました。

 今日と明日は「喜多方そばフェスタ」です。

 さっそく、午前10時オープンの直後、そばフェスタ会場の喜多方プラザ東の仮設テントに入場しました。

 オープン直後なのに会場には既にたくさんの人が。

イメージ 1

 まずは、私の地元喜多方市熱塩加納町の「ひめさゆりそば」をいただきました。

イメージ 2

 暖かいそば(かけそば+てんぷら)、冷たいそば(もりそば)どちらも、おいしかったです。

 さらに別なそばも食べました。

 毎年、この季節の楽しみです。

 なお、そばフェスタは、明日まで開催されています。皆さんもいかがですか。

 そばフェスタに出店しているのは、喜多方市内の以下の7つのグループです。

 雄国そば
 ひめさゆりそば
 会津駒形そば
 たかさと雷神そば
 塩川そば
 岩月そば
 会津山都そば

大雪になりました

$
0
0
  今回の今季最強寒波で、毎日雪が降り続いています。

 10日20cm、11日30cm、今日12日50cmと毎日降雪量が増えています。

 積雪深は約1mで、家の前は写真のとおり

イメージ 1

 道路は除雪されていますが、路側には、雪の壁ができています。塀の上の雪は一日で積もった分です。

 家の周りを毎日スノーダンプで除雪しています。

 もう雪のやり場がなくなりました。

 それに、体力的にもきついです。

 そろそろ止んでほしいものです。

ラズベリーパイ始めます。

$
0
0
 雪が多かった2月が、あっという間に終わり、今日から3月。

 以前から考えていた新しいマイコンへの取り組みを始めます。

 Raspberry Pi(ラズベリーパイ)です。かわいらしいニックネームがついていますが、手のひらに乗るりっぱなコンピュータです。

 最近発売されたRaspberry Pi3 Complete Starters Kit をAmazonから買いました。(8400円)

イメージ 1

120×95×65mmのこじんまりとした箱を開けると

イメージ 2

ケースに入ったRaspberry Pi3 MODELB本体。

ヒートシンク(大小)

5V 3,0Aのスイッチング電源(スイッチ付き)

microSDカード(16GB) RASPBIAN書き込み済み

説明書等

OSが既にプリインストールされていますので、ディスプレイ、キーボード、マウスを接続すれば、即ラズベリーパイを楽しむことのできる完全キットです。

しばらく、このラズパイで楽しめそうです。

思い起こせば、1977年に歴史的なマイコンボードNECのTK80を購入して、アセンブラでプログラムを組んで、マイコンの勉強をしました。

あれから40年,1.2GHzのCPUのコンピュータが手のひらに乗る時代になりました。

イメージ 3

これで、何ができるのか、TK80を買ったころと同じようなワクワク感があります。

勉強の進捗状況は、このブログとJH7UBCホームページに掲載し、足跡を残していきます。

これから始めようと思われる方、お暇な方、ご覧ください。



Viewing all 440 articles
Browse latest View live