[TopPage] [FMTOWNS] [Hardware] [Freesoft] [怪飲料] [CHAT兼掲示板] [LINK・etc] [About] |
_ ■ AVRの外部データバスを使う ■ | ||||||||||||||||||
AVRは単体でもさまざまな制御が出来ますが、難しいインターフェイスの場合は専用ICを繋いで制御を任せます。今回は、ポート数が多く外部SRAMが使用可能なAT90S8515を例に、AVRの外部バスにデバイスをぶらさげます。 AT90S8515は40pinのAVRで、PORT-A〜Dの各8本、計32本のI/Oポートを持っています。また、外部SRAMをサポートしており、内蔵SRAMと同様の扱いが出来ます。また、SRAMと同じくパラレルなバスでデバイスを接続することが出来ます。外部SRAMを繋ぐ場合は、PORT-Aがアドレス下位8bitと8bitデータバスのマルチプレックスバスとして、PORT-Dがアドレス上位8bitとして動作します。よって、任意アドレス幅のSRAMでデータ8bitバス幅のデバイスを直接繋げられます。 | ||||||||||||||||||
_ ■ USBN9603の接続例 ■ | ||||||||||||||||||
USBノードコントローラ USBN9603 を例にとって接続してみます。 USBN9603は、National Semiconductor社製のUSB 1.1規格準拠のUSBノードコントローラです。これを使用してUSBデバイスを作ることが出来ます。今なら入手も容易です。マイコンとの接続インターフェイスとしては、 ・non-multiplex mode ・multiplex mode ・MICROWIRE/PLUS mode の3つのモードをサポートしています。AT90S8515の外部バスには、multiplexモードを使用します。この場合、通常のSRAMアクセスと同じ感覚で、USBN9603の内部レジスタにアクセスすることが出来ます(これが重要です(^_^))。 なお、MICROWIRE/PLUSモードは3信号線式の全二重転送方式で、AVRのSPI機能を使うことで接続することが出来ますが、ISPと使用ピン同じなのでスイッチで切り替えでもしないとISP出来ないため、デバッグ効率が落ちてしまいます。I/Oポート数が限られている場合は有効でしょう。PICでも上位機種はMICROWIREインターフェイスを持っています。 USBN9603とAT90S8515間のピン接続例を以下に示します。アドレスは最上位にマップします。
※#CSとA15間にはnot(74HC14など)を入れます。 接続した上位アドレス線はA15ですので、AVR側からはメモリアドレス0x8000〜にマップされたことになります。A8〜A14までは繋いでいませんので、0x80**〜0xFF**までは同じアドレスへのアクセスになります(^^; 他に繋ぎたいものがあれば、アドレス線に手を加えてデータバスを繋げば良いだけです。後を考えれば、NOTよりもNANDとかのほうが良いかもしれません。 問題なのは、アドレス線+データ線用に必ず16pin使うことです。ちょっともったいないですね。他にたくさん繋げる場合はいいんですが。 | ||||||||||||||||||
_ ■ AVRASMによるアクセス ■ | ||||||||||||||||||
AVRの標準アセンブラによるアクセスは簡単です。はじめに手順は必要ですが、ほぼ通常の内蔵SRAMアクセスと同じ感覚でアクセスできます。 外部SRAMを有効にするには、 「MCUCR の SRE ビットに 1 を書くだけ」 です。これで、内蔵SRAMと同じくアクセス可能になり、データバス・アドレスバスの管理がハードウェア側で行われるようになります。 アセンブラで書くと以下のようになります。 ResetEntry: LDI r16,0xff OUT PORTB,r16 OUT PORTD,r16 OUT DDRA,r16 OUT DDRB,r16 OUT DDRC,r16 OUT DDRD,r16 ; SRAM ENABLE IN r16,MCUCR ORI r16,(1<<SRE) OUT MCUCR,r16 LDI r16,(1<<2) STS 0x8000,r16 この例では、USBN9603のMCTRLレジスタのビット2(VGE)をHにしています。USBN9603のVREG端子から3.3Vが出ていれば、成功です。 なお、普通のSRAMを繋ぐ場合はスタックを外部SRAM領域に置くことが出来ますが、アクセスにウェイトがかかってしまいます。 | ||||||||||||||||||
_ ■ AVR-GCCによるアクセス ■ | ||||||||||||||||||
AVR-GCCでは、AVRASMと同じく外部SRAMを有効にして、絶対番地アクセスします。 ソースを書くと以下のようになります。 unsigned char *p; outp( inp(MCUCR)|(1<<SRE) , MCUCR ); p = (unsigned char *)0x8000; *p = (1<<2); この例ではAVRASMの場合と同じく、USBN9603のMCTRLレジスタのビット2(VGE)をHにしています。USBN9603のVREG端子から3.3Vが出ていれば、成功です。 なお、普通のSRAMを繋ぐ場合は変数やスタックを外部SRAM領域に置くことが出来ますが、GCCに自動でそれを使用させるには、makefileやローダスクリプトの変更が必要です。 | ||||||||||||||||||
_ ■ アクセスウェイト ■ | ||||||||||||||||||
上記の例では、アドレス0x8000にマップされたUSBN9603のアドレス0x0000レジスタにデータを書きこみました。読み込みも正しく動いているか確認してみましょう。次の例では、固定値を返すRevision ID レジスタ(RID)0x0003を読んでみます。普通のUSBN9603では、データシートによれば下位4bitに0b0010を返すはずです。 unsigned char *p; unsigned char dat; outp( inp(MCUCR)|(1<<SRE) , MCUCR ); p = (unsigned char *)0x8003; dat = (*p & 0x0F); ちゃんと、datに0b0010=2が返りましたか? 私はダメでした。場合によっては正しい値が返らないことがあるようです。私の場合は、8.0MHzのAT90S8515ではタイミングの関係でしょうか、うまくいきませんでした。一応、8MHzのAT90S8515に対してUSBN9603は内部48MHzで動作していますので、ウェイトは無くても行けそうな気がするのですが、動かない場合はウェイトを追加します。 ウェイトを追加するにはSRAMを有効にするとき、一緒にMCUCRレジスタのSRWビットに1を書きます。 outp( inp(MCUCR)|(1<<SRE)|(1<<SRW) , MCUCR ); 今度はうまくいったと思います。もっと速いAVRの場合はどうなるのか興味あるところです。 | ||||||||||||||||||
_ ■ それでも動かない場合 ■ | ||||||||||||||||||
例として使ったのが USBN9603 なので、もしかしたら動かない場合があるかもしれません。その場合は以下の点を確認してみてください。 ・MODE0,MODE1 ピンは正しくmultiplexモードに設定されていますか? というのは、ただ単に私が今までに気づかず悩んだことがある点です(^^; たぶんこう書いておけば、また自分が忘れたときに思い出すだろうと言うことで(特に3番目は気づかずに1週間くらい悩んだ)。 |