スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Windows7でAVRISP markII

Windows7 64bitでAVRISPmarkIIを使おうとしたところ、「このINFのサービスインストールセクションは無効です」と表示されドライバのインストールが上手くいかなかったのですが、下記のサイトに解決策が載っていました。

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=82994

このサイトではJTAGICE mkII についてですが、AVRISP markIIでも同様の方法で解決するようです。

上記サイトは英語なので、手順をざっくりと訳しておこうとおもいます。

1.コントロールパネルのデバイスマネージャを開き、<<コンピュータ名>>を右クリックし、「レガシーハードウェアの追加」を選ぶ

2.「次へ」をクリック

3.「一覧から選択したハードウェアをインストールする」を選び、「次へ」進む

4.「全てのデバイスを表示」し、「次へ」。

5.「ディスクの使用」をクリック。 「参照」で「"C:\Program Files (x86)\Atmel\AVR Tools\usb64\windrvr6.inf"」を選ぶ。

6.WinDriverを選び、「次へ」を何度か押して最後に「インストール」。

7.これで使えるようになってるよ。
スポンサーサイト

Visual C++ でDirectInputを使ってジョイパッドを弄る為の色々

USBジョイパッド入力について調べてみたところ、C++とDirectInputを使うのが
一番楽そうだったので、その方法を覚書。以下32bit Window XPについてです。
Vistaとか7とかでも多分同じ方法でできるかな。
LinuxやMacについてはわからないです。

まずはMicrosoftのサイトからVisual C++ Express EditionとMicrosoft DirectX
SDKをダウンロード&インストール。


Visual C++ でプロジェクトを作成し、メニューの
プロジェクト->(プロジェクト名)のプロパティ->構成プロパティ
の中の、以下の3箇所を変更します。
まず、リンカ->全般
の追加のライブラリディレクトリにDirectX SDKをインストールしたフォルダの
中にあるLib->x86を追加。CPUによってはx86でなく、x64の方を追加する必要が
あるかもしれません。

次に、リンカ->入力
まで辿り、 追加の依存ファイルにdinput8.libとdxguid.libを追加します。

最後に、
C/C++->全般
の追加のインクルードディレクトリに、DirectX SDKをインストールしたフォルダ内のIncludeを追加します。


これでDirect Inputが使えるようになります。

実際の使い方は後々書こうかと思います。

尚、昔のDirectInputで使われていた関数joyGetPosではアナログスティックは3軸までしか対応していませんでしたが、新しいjoyGetPosEx関数を使えば6軸まで対応しているようです。

avr、ATTiny2313の外部割込み(改訂版)

以前avrの割り込みの記事を書きましたが、検索でここにたどり着いている方はその記事が目的のことが多いようです。
その記事を読み返して見たのですが、あまり解りやすい記事では無いと感じたので今日はそれを書き直します。

ということで今日はいつも見てくださっている方にはあまり面白くない内容となっています。ごめんなさいね。



説明は丁寧に、というよりかなりしつこく書いています。解っているところは読み飛ばしてください。

では本文、avr、ATtiny2313の割込み。今回はPB0~7で利用できる、PCINT0~7(PinChangeINTerrupt)の使い方とついでに8ビットタイマの簡単な使い方の説明です。こういうのはプログラムを実際見て弄ってみうるのが最善だと思いますので、早速プログラムからです。
サンプルプログラムはPB7~4に繋いだスイッチのON/OFFが変わるとそれをPB3~0に反映するというプログラム。「そのままスイッチにつなげば良いじゃん」とか言わないで。あくまでサンプルなんだから。
入力ピンが浮いてるとLEDが灯いたと等の電流の変化で入力値が変化して意図しない割り込みがかかってしまうことがります。入力になっているピンは必ず電源電圧かグランドに繋ぐようにしよう。おにーさんとの約束だ。

#include <avr/io.h>
#include <avr/interrupt.h>//半角の<>はhtmlタグとして認識されてしまうようなので全角になっています。コピペして使うなら半角に直してください。

#define DELAYTIME 240

void initialize(){
DDRB=0b00001111; //PB7~4を入力、PB3~0を出力
PORTB=0b00000000; //PB7~4は0出力、PB3~0はハイインピーダンス入力
GIMSK=0b00100000; //PCINTを有効に
PCMSK=0b11110000; //PCINT7~4のみ有効
TCCR0B=0b00000101; //タイマ、クロックを1024分周
TIMSK=0b00000000; //タイマ割り込み無効
sei();       //割り込み全体許可
}

int main (void) {
initialize();
while(1){}
}

ISR(PCINT_vect){ //外部割込みが発生するとこの関数が呼ばれる
GIMSK=0b0000000;  //PCINT無効
TCNT0=DELAYTIME; //タイマの現在の値をDELAYTIMEに。
TIMSK=0b00000010; //タイマ割り込み有効
}

ISR(TIMER0_OVF_vect){   //タイマのオーバーフロー割り込みが発生するとこの関数が呼ばれる
TIMSK=0b00000000; //タイマ割り込み無効
GIMSK=0b00100000; //PCINT有効
PORTB=(0b11110000&PORTB)|(0b00001111&(PINB>>4));
              //PB7~4の状態をPB3~0にコピー。ビット演算です。
}

実際に使用するなら、電源、RESET、グランド端子を繋ぎ、PB7~4にスイッチ、PB3~0に抵抗をはさんでLEDを繋ぎます。

プログラムの流れを追うと、まず電源が入ると各種初期化を行い、無限ループに入って待機。
PB7~4に変化があると、タイマをセット、タイマ割り込みを許可。少し時間が経つとタイマのオーバーフロー割り込みがかかるので、その時にPB3~0の値を変更。再び無限ループに戻り待機。


さて、先ずは基本から。avrには様々な機能がありますが、それらを使用するためには多くの場合、機能の設定→実際に使用する命令、という手順を踏むことになります。機能の設定は特定のレジスタに値を書き込むことによって行われます。具体的に何処に書き込むのかというと、データシートを見るとDDRBだとかPCMSKだとか、様々なレジスタが説明されていますのでそこに書き込みます。WinAVRを用いるならばavr/io.hやavr/interrupt.h等のヘッダをインクルードし、DDRB=0b000111;のように代入することによって行うことができます。
それらのレジスタは基本的にビットが1で有効、0で無効です。使わない機能については何もしなければデフォルトで0が代入されています。


次はPCINTを使うときに変更する必要のあるレジスタの説明です。簡単に説明するだけなので、詳しいことはデータシートを見てください。また、以下の説明でレジスタの一部のビットに触れていないときでも大抵なんらかの機能が割り当てられています。特に意図が無ければ説明されていないビットは0にしておきましょう。それらのビットについて知りたければデータシートを見てください。
以下、8ビット中一番左端を第7ビット、右端を第0ビットと呼びます。
それでは、レジスタの説明に入ります。

SREG:第7ビットが1であれば割り込み全体の許可。sei()、cli()はこのレジスタを設定する関数。第7ビットはsei()でHi、cli()でLoになる。

DDRB:PB0~7を、入力にするか出力にするか決定する。Hiにしたビットと対応するピンが出力、Loにすると入力。
PORTB:ピンが入力と出力どちらになっているかで少し動作が違う。これもDDRBと同様、ビットとピンが一対一対応している。
   ピンが入力の時、Hiであればプルアップ抵抗付き入力、Loであればハイインピーダンス入力。
   ピンが出力の時、Hiであれば5V(というか電源電圧)出力、Loであれば0V出力。
PCMSK:これもビットとピンが一対一対応。Hiにしたビットと対応するピンのみPCINTが有効になる。
GIMSK:第5ビットがHiならPCINT有効、Loなら無効。
PINB:PCINTの使用前に変更するレジスタでは無いですが、ついでに。ピンの現在の状態を読み取る。DDRB等と同様ビットとピンが一対一対応。

次に8ビットタイマを使用するためのレジスタの説明です。
TCCR0B:第2、1、0ビットがタイマのクロック分周比を決定する。
   000でタイマの動作停止、001で分周比1、010で8分周、011で64分周、100で256分周、101で1024分周。
TIMSK:第1ビットが1であればタイマのオーバーフロー割り込み有効。
TCNT0:カウンタの現在の値です。TCNT0に値を代入することによって値を書き換えることも可能です。


割り込みが起こった時に実行する関数ですが、ISR(割り込みハンドラ名)という関数が割り込み原因に応じて実行されます。
PCINTとタイマ0のオーバーフローの割り込みハンドラ名はそれぞれPCINT_vectとTIMER0_OVF_vectです。それ以外の割り込みハンドラ名は
C:\WinAVR-********\doc\avr-libc\avr-libc-user-manual\group_avr_interrupts.html
(********は20081205等。日付と思われます)
を見て調べましょう。


ここで少しチャタリングについて説明しておきます。
チャタリングとは、(以下、wikipediaより)
リレーやスイッチの接点が切り替わった際に、微細で非常に速い機械的振動によって、電気信号が断続を繰り返す現象である。非常に短時間で消失する現象であるが、電子回路の誤動作の一因とされ、通常は電子回路を工夫することなどで予め対策が取られる。
(ここまでwikipediaより)
というものであり、ここではタイマを使ってチャタリングが収まった頃にピンの値を読み取ることによって対策を行います。
チャタリングは普通長くて10ms程度と言われているので、余裕を持って時間を取り、外部割込みがかかってから約16ms後にピンを読み取ります。
クロックは1MHz、分周比1024なのでタイマは約1msで1カウント、したがってタイマを240からカウントさせれば約16ms後に256(オーバーフロー)となり、タイマによる割り込みがかかります。
PINBからの読み取り処理はタイマ割り込みの中で行います。


とりあえずは以上です。何処が解り難かっただとか、もっと説明が欲しいとかあればコメントを頂ければ出来る限り修正したいと思います。

avr、ATtiny2313の外部割込み

たまには役に立つ記事でも書いてみよう。

ATtiny2313の外部割込みについて。さっき色々やって成功したばかりなので正確ではない部分が幾らかあると思われます。


ATTiny2313以外のavrについてはデータシート等を参考にしてください。
WinAVRを使用している方はこのサイトも役立つかもしれません。
http://www11.ocn.ne.jp/~akibow/avr-libc-user-manual-1.4.3/group__avr__interrupts.html

追記(09/06/05):現在見れなくなっているようです。同じ内容のhtmlファイルは
C:\WinAVR-********\doc\avr-libc\avr-libc-user-manual\group_avr_interrupts.html
(********は20081205等。日付と思われます)に置かれているようです。


ATtiny2313ではportB(12~19番ピン)とportDの2,3番(6,7番ピン)で外部割込みが可能です。このうちportBはピンチェンジインタラプトのみ、portDの2,3番はピンチェンジインタラプト、posedge、negaedge、lolevelに対応しています。


まずは手っ取り早く使い方から。
portBのピンチェンジインタラプトを使用するにはGIMSKの5bit目(PCIE)をHiにする必要があります。
これがportBのピンチェンジインタラプト全体のエネーブルとなります。


つぎにPCMSKを設定します。portBのピンのうち、PCMSKのHiになっているビットに対応するピンのみがピンチェンジインタラプトを発行します。


最後にSREGの最上位ビットを立てる必要があります。これはタイマー割り込み等も含めた全ての割り込みの許可となります。


割り込み時に実行されるコードはWinAVRを用いてCで書くならば
SIGNAL(/*割り込みの種類*/){
 //ここに処理を記述
}
のようになります。portBの割り込みならばPCINT_vect,他の割り込みは
http://www11.ocn.ne.jp/~akibow/avr-libc-user-manual-1.4.3/group__avr__interrupts.html
を見て調べましょう。

追記(09/06/05):現在は割り込みに使う関数は"SIGNAL"ではなく"ISR"が推奨されているようです。


アセンブラで書くならば割り込みベクタを用いるとかの話ですがその辺はあまり知らないので割愛。



WinAVRを用いてCでコードを書くならば初期化等の部分は以下のようになります。
init_port,init_intをmain関数あたりで呼びましょう。SIGNALは割り込みがかかると勝手に呼ばれます。

init_port(){
 PORTB=0x00;//ポートB初期化。入力は0でハイインピーダンス、1でプルアップ。
 DDRB=0xf0;//ポートBの入出力設定。0で入力、1で出力。
         //PORTB,DDRBの値はどのピンを入力にするか等によって変えましょう。
}
init_int(){
 GIMSK=0x20;//ピンチェンジインタラプト許可
 PCMSK=0x0f;//PORTBの0~3のインタラプト許可。値は割り込みに使うピンによって変えましょう。
 sei();//インタラプト全体の許可。
}
SIGNAL(PCINT_vect){
 //割り込み時の処理
}


ピンチェンジインタラプトは入力ピンだけでなく出力ピンに対しても使用できるようです。その場合は内部の処理によりそのピンの出力が変化したとき割り込みがかかります。



PORTDの2,3番ピンの割り込みはMUCURを使って割り込みの種類を設定したりできるんだけど疲れたからまた今度にしよう。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。