2011年4月26日火曜日

FPGA FMトランスミッタ: やっぱり Hello world

お約束のHello worldを表示させてみました。




EZ-LCDで文字列を表示させる方法がわからなかったので、ネットで拾ってきたlcd_put_str()をコピペ。一応表示できました。ポインタを使っているようですが、何がどうやって動いているのか理解できていないでいます。

以下、ソースです。Blogシステムの都合で、<avr/io.h>と<util/delay.h>のinclude表示が削除されてしまっているので適宜読み替えて下さい。
なおTLC5925()はバーグラフLEDを光らせるための関数で、この例では0.5秒ごとにぴょこぴょことバーグラフ表示が増えていきます。


#define F_CPU 8.000E6  // マスタクロック8MHz、内蔵オシレータ
#include
#include


void init_mcu(void) {
// ポート設定 0:入力, 1:出力
DDRA = 0xFF;
DDRB = 0xBE;
DDRC = 0xF0;
DDRD = 0x3C;


// 出力ポート初期化
// 入力ポート、1:プルアップ
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x0F;
PORTD = 0xC0;
}


void TLC5925(uint8_t LEVEL) {
uint16_t k;
int8_t n;


switch(LEVEL){
case 0 : k=0b0000000000000000; break;
case 1 : k=0b0000000100000000; break;
case 2 : k=0b0000001100000000; break;
case 3 : k=0b0000001110000000; break;
case 4 : k=0b0000001111000000; break;
case 5 : k=0b0000001111100000; break;
case 6 : k=0b0000001111110000; break;
case 7 : k=0b0000001111111000; break;
case 8 : k=0b0000001111111100; break;
case 9 : k=0b0000001111111110; break;
case 10 : k=0b0000001111111111; break;
default : k=0b0000000000000000; break;
}


PORTD &= ~_BV(PD3); // CLK -> 0
PORTD |= _BV(PD5); // OE -> 1
PORTD &= ~_BV(PD4); // LE -> 0
PORTD &= ~_BV(PD2); // SDI -> 0


for (n = 15; n >= 0; n--) {


// SDI write
if(k & _BV(n))
PORTD |= _BV(PD2);
else
PORTD &= ~_BV(PD2);


// CLK write
PORTD |= _BV(PD3); // CLK -> 1
PORTD &= ~_BV(PD3); // CLK -> 0


}


// LE write
PORTD |= _BV(PD4); // LE -> 1
PORTD &= ~_BV(PD4); // LE -> 0
// OE write
PORTD &= ~_BV(PD5); // OE -> 0
}




void wait_ms(uint16_t t) {
while (t--) _delay_ms(1); //1ms
}




void lcd_put_str (char *str)
{
while(*str != 0) {
lcd_putc(*str);
str++;
}
}




int main(void) {
static uint8_t n=0;
uint8_t c;


init_mcu();
lcd_init(); // LCDモジュールの初期化


lcd_cursor('CSR_UNDER');
lcd_put_str("Hello world!\nHello world!");
lcd_locate(0,12);


for(;;) {
if (n==11) n=0;
TLC5925(n);
n++;
wait_ms(500);
}
}

FPGA FMトランスミッタ: やっと液晶が動いた

ようやく液晶が動いてくれました。
ATmega324のJTAGヒューズビットが有効になっていたことに気がつかず2日間をムダに浪費しました。しかも液晶のコントラストボリュームの位置が悪くて表示が極端に薄くなって動いていたのにわからなかった。
ソフトウエアはChaNさんのEZ-LCDを使ってみました。液晶を使うのは初めてですが、優れたライブラリがあると、とってもラクチンです。ChaNさん、ありがとう!

2011年4月17日日曜日

NS73M FMトランスミッタ: 組み立て

回路設計が終わっていたので、朝から基板のアートワーク~プリント基板作り~組み立てまで1日で一気に仕上げました。回路もシンプルだし、専用ICはラクで良いです。
基板作りはMinimal Board Editorを駆使して、ベタアースを描いてみました。簡単操作でそれらしい基板ができあがりました。ただ、ベタアースと他のランドとの離隔(Gap)を0.3mmなどと目一杯狭くしてしまったため、ショートしてしまわないよう半田付けに注意が必要でした。特に2012チップコンのピン間にもベタアースが出来てしまっていて実体顕微鏡で何度も確認しました。たぶん大丈夫と思っていますが実際に動かすまで正直なところ不安です。






2011年4月16日土曜日

FPGA FMトランスミッタ: スイッチング電源のノイズ、PSRR

部品を実装しました。両面基板と言っても部品実装穴は開いていても部品面とはんだ面の接続は自分でやらなくてはいけないのでとっても面倒です。





写真では、作業用にスペーサを取り付けています。銅箔に触らないよう手袋をはめて作業しているほか、酸化防止のため銅パターン部分に無洗浄タイプのフラックスを塗っています。ただ無洗浄タイプとはいえ酸化防止目的に使うのは良くないと思っています。

実装しながら、AtmelのATtiny85のサイズが想定とは違うことに気がつきました。SOIC8なのでOPA2353と同じサイズと思っていたところ、ATtiny85の方が幅が広いです。これは確認不足ですね。幸い、実装時に工夫してそれほど無理なく取り付けできました。

もう1点、変更点があります。オペアンプとオーディオコーデックのアナログ系に5V電源を供給するラインにLDOレギュレータNJM2845DL1-05を追加しています。当初は、スイッチング電源モジュールの5V出力をそのまま供給する前提でしたが、ノイズが多く適切ではないだろうと気がついたからです。
NJM2845は、LDOとはいえ入出力の電圧差が0.18V必要です。そこで、スイッチング電源モジュールをイーター電機工業のBNS05SA-Uに変更しました。このモデルは、出力電圧を5.5Vまで可変できます。

ところで、BNS05SA-Uのノイズは仕様書によると80mVp-pでスイッチング周波数は66kHzとあります。ノイズについてはよく知りませんが、66kHzを基本波として広帯域でノイズが出ていて電源ラインを揺さぶられていることになるのかなと想像しています。
オペアンプ等には、電源電圧がノイズで変動しても出力電圧を保つ機能があり、その性能を電源電圧変動除去比(PSRR; Power Supply Rejection Ratio)で表します。

まずLDOのPSRRは、次のグラフの通り負荷電流によっても変わりますが66kHzで50dB以上の性能を持っています。LDOでノイズは80mVp-p×(-50dB)=0.25mVp-pに低減されます。


次に、MPXコンポジット信号出力部のオペアンプOPA2353に着目します。PSRR特性は次のグラフのようになっていて66kHzでは約73dBです。ノイズ電圧は0.25mVp-p×(-73dB)×増幅率(2.0/1.6)=0.07uVp-pとなります。コンポジット信号のレベルは2Vp-pですから、ノイズとのレベル差は149dBです。S/N比は実効値で測定するので正確ではありませんが、概算値としてみても問題にならないと考えます。


続いて、オーディオコーデックCS4270についてです。データシートには、1kHzでのみ規定があり55dBとなっています。66kHzの特性は不明ですが、仮に30dBとすると電源のノイズは、オーディオコーデックの出力端子で0.25mVp-p×(-30dB)=7.9uVp-pとなります。出力端子での信号レベルは1.6Vp-pですから両者のレベル差は106dBとなり、問題にならないと考えます。

2011年4月12日火曜日

FPGA FMトランスミッタ: はじめての自作両面基板

意外にうまくいきました。表裏の穴位置は微妙にずれていますが、使えないほどではありませんでした。




両面の位置ズレを防ぐため、2枚のマスクフィルムがずれないようにホチキスで止めてから、フィルムの間に基板を差し込んで露光しました。



露光に使った機材は今まで通り、TooのOHPフィルム、クイックポジ感光基板、バキュームクランプ、ちびライトBOX-1の組み合わせです。バキュームクランプの表面はフィルムで裏面はガラス板でできています。露光時間は同じでいいのかな、と思いましたが結果的には同じ露光時間で大丈夫でした。
今回は100×150ミリサイズの基板も使いました。ちびライトBOX-1でこのサイズの露光を行う場合、それより小さいサイズの基板とは別の露光プロファイルにより長めの露光時間が指定されています。しかし、経験上基板の端の方は露光不足になることが多く失敗がちになります。
そんなところ、O-familyさんの掲示板の記事で3回に分けて露光してちょうど良いという情報を見かけて、参考にしてみました。私の場合は、まずは2回に分けて(露光時間は小サイズ基板用のプロファイル通り)試したところ上記のように良い感じにできました。なお、O-familyさんは感光基板作りに造詣が深く、掲示板にノウハウを投稿されていて必見です。参考にさせて頂いています。


ところで、賞味期限切れの感光基板を使って見事に失敗しました。2009年9月に賞味期限が切れたものですが、2倍の露光時間で綺麗に現像できたんですが、エッチングするとご覧の通り不要なパターンが残ってしまいました。どうやら露光不足のようです。もし、次回賞味期限切れの基板を使うときは、もっと長めに露光してみます。




エッチング不良でしたが、エッチング状態が比較的ましなところもあったので補正してなんとか使います。

2011年4月8日金曜日

FPGA FMトランスミッタ: メインボード基板の回路

回路図を清書しました。
メインボードでは、S/PDIF入力に対応させるためデジタルオーディオインターフェースレシーバDIR9001とサンプルレートコンバータAD1895を使用します。また測定用のアナログ入出力のため、24bitオーディオコーデックCS4270を選びました。このコーデックは、安い割にA/D, D/Aとも192kHzまでのサンプリングレートに対応します。D/Aコンバータでコンポジット信号とパイロット信号を出力します。
心臓部となるFPGA基板は、デザインウェーブマガジン誌2007年7月号付録のものです。(マルツパーツが同じ基板を復刻しています)

FM変調信号の生成には、前作同様DDS compilerを使うので、FPGAに外付けで14bit 165Msps D/Aコンバータ AD9744を使います。システムクロックには、位相雑音特性が良いとされるSi570を選びましたが、手持ちのものは出力形式がLVDSです。Spartan3EならLVDSを直接接続できるのでCMOS入力のAD9744にはFPGAを経由してクロックを供給するつもりでした。ところが、FPGAを通すとジッタがかなり増えるという話を聞きましたので、いったんLVDSレシーバADN4662で受けて、FPGAとD/Aコンバータに分配することにしました。



2011年4月3日日曜日

FPGA FMトランスミッタ: メインボード基板のアートワーク

はじめて両面基板に挑戦します。感光基板で作るので部品面とハンダ面の位置が合わないことを想定して、部品面はベタアース主体として細かなパターンは極力避けました。
また、ベタアースをデジタル/アナログ回路毎に明示的に分け、一点アースのような効果を狙っています。
基板の製作そのものはこれからです。うまく出来ればよいのですが。

両面重ね合わせ(ベタアース非表示)


両面重ね合わせ(ベタアース表示)


部品面


ハンダ面