ラベル AVR の投稿を表示しています。 すべての投稿を表示
ラベル AVR の投稿を表示しています。 すべての投稿を表示

2013/04/24

[電子工作]Attiny13AのPCINTで外部ピン変化割り込み

,
 Attiny13Aを使ってちょっと遊んでいます。で、Attiny13Aにはピン変化(0→1、1→0とか)で割り込みを発生させる機能があります。割り込みにはINT0を使ったもの、PCINT[5..0]を使ったものの2種類が存在します。これらの違いは、使えるポートの数、割り込みに立ち上がり/立下りなどの制限をかけられるか、などなのですが、詳しい解説は以下のページを見てください。

AVR/ペリフェラル/外部割り込み - プロえく http://bit.ly/11L2QXi

 INT0を使ったものは便利なのですが、PB1しか使えず、今回既にLEDのための出力に使ってしまっているので、PCINTによる割り込みを使ってみることにしました。

 回路図は以下のような感じです。
fig.1 schematic
PB2にLED出力、PB4がスイッチ入力の単純な回路ですね。
 割り込みのためにプッシュスイッチを使ったのですが、チャタリングが発生してしまうため、防止のためにRC積分回路を入れています。時定数をどうするかは経験則だと思ったので、次のページを参考にさせて頂きました。

チャタリング防止回路のCR時定数 http://bit.ly/ZL38Nx

 基板を作ってて、最初はやっぱり動きませんでした。バグの原因は多分、

1)スルーホールだから裏側に配線あたってれば大丈夫だろうと思ってた(スイッチがGND落ちてなかった)
2)入力を見るレジスタを間違えていた(PORTBではなくPINB)
3)見るポートを間違えてた(2ではなく4)

だと思われます…今後のために置いておきます…


コードはこんな感じです。

#include <avr/io.h> 
#include <avr/interrupt.h>

//外部ピン変化の割り込み
ISR(PCINT0_vect){
   //自分でピンが立ってるかどうかチェックしなければいけない
   if(bit_is_set(PINB, PORTB4)){
      PORTB ^= (1 << PORTB2); //PB2を反転
   }  
}
 
//ピンの変化による割り込みを許可する
void initIOInterrupt(){
   //割り込みを有効にする
   GIMSK |= (1 << PCIE);

   //割り込み許可するポートを選ぶ
   PCMSK = 0b00010000; //PB4

   //全割り込みを許可
   sei();
}
 
void main(){
   //PORTBの入出力の方向を設定(PB4が入力、PB2が出力)
   DDRB |= (0 << DDB4) | (1 << DDB2);

   //PORTBの出力値を設定
   PORTB = 0b00010100;

   initIOInterrupt();

   while(true)
   {
      //TODO:: Please write your application code
   }
}

 ISR(PCINT0_vect)が、割り込んだ時に呼ばれる関数です。設定はinitIOInterrut()で設定しています。といってもやることは少なく、

1)GIMSKレジスタのPCIEにフラグ(1)を立て、PCINT割り込みを許可すること
2)PCMSKレジスタで割り込みに使うピンのところにフラグを立てること

の2つだけです。

 PCINTでは、割り込みが立ち上がりによるものなのか、立下りによるものなのかはユーザーが調べないといけません。なので、PINBを見ることで入力値を求めています。bit_is_set(A, B)は<avr/io.h>で読み込まれる?<avr/str_defs.h>でdefineされたマクロで、AのBビット目が1ならtrueになる…のかな。
 
 また、PCINT割り込みはポート変化が出力でも割り込みは発生するらしい(有志の方による日本語翻訳版データシートならp.31)。なので、関係ないポートは出力値を変えてもいいように、PCMSKを0にしておきます。

 INT0を使った割り込みは、次のBlogさんがとてもわかりやすい解説を書いてくださっているので、ぜひそちらを…
 
AVR入門(3) ピン入力と割り込み | stastaka's Blog http://bit.ly/11L86dz


 さて、AVRをちょっとは便利な道具として扱えるようになって来ました。後はADCとシリアル通信、RESETピンのI/Oポートとしての使用、が課題です…
Read more →

2013/04/23

[IDE]AVRISPmkIIをWindows8で使う

,
 PCを新調してWindows8にしたので、IDEも入れ直しです。AVR使いたくなったのでAVRISPmkIIのドライバを入れるお話です。

 何のことはなく、ググって見つけたこのpdfの通りにやるだけで動きました。
How to: Atmel AVRISP mkII programmer with Atmel Studio 6 in Windows 8 http://bit.ly/11FhdfV 

 こんな感じで使えます。

 どちらかというと、AVRISPmkIIはターゲットへの電源供給がないのを知らなくて、後使えなくなった電池をつないでたりして時間ロスしました…

 参考までに、AtmelStudioの画面はこんな感じなんです。Intellisenseもちゃんと効きます。VS使ってたこともあって、めっちゃ便利に感じます。

 AtmelStudioこんなに使いやすいのに、なんでPICの方が人口多そうなんですかね。
Read more →

2011/12/04

擬似乱数、rand()もどき

,
Cで乱数を発生させる場合、特に精度を求めなければ、普通はrand() (<stdlib.h>)を使うことになります。が、もっと簡単なのでいい、という場合もあります。探してたら見つかったのでメモです。

これ:PICを使い乱数を発生させてLEDをランダムに光らせたいのですがプログラムがよくわ... - Yahoo!知恵袋

ちなみに、Attiny13Aでstdlib.hのrand()だと780byte程だったのが、上で紹介されてたrand()にしたら400byte弱になりましたとさ。ただまあ、まだ試してはいない←
Read more →

[電子工作]AVRの逆アセンブラ、avr-objdump.exeを使う

,
 AVRの逆アセンブラ、avr-objdumpの話です。

 WinAVRでプログラムを書いていて、「どうしてこんなメモリを喰うんだろう?」と思う時がありました。Cのコードを少し変えただけなのに、です。こんな時は、コンパイル結果である機械語のコードが全く違っていたりするので、確認のためにアセンブリのソースも見ないといけません。となると、逆アセンブラの出番になります。

 …前置きが長いですが、AVRの逆アセンブラ、「avr-objdump.exe」についてのメモです。
 この実行ファイルのオプションを知るには、avr-objdump.exeのmanを見て頂くのが早いです。一応、コマンドラインでただavr-objdumpと入力しても、オプション一覧が出ると思います。下にオプション一覧の画面を貼ってきます。

avr-objdump.exeのオプション一覧

 逆アセンブラを吐き出すためには、一旦C/C++で作成したプロジェクトをMake Allし、できたファイルのうちのオブジェクトファイル(拡張子は.o、大抵main.oとか)が必要です。コマンドラインで、avr-objdump -S main.o とすれば、逆アセンブラのリストがずらーっと並びます。テキストファイルなどにしたい場合は、avr-objdump -S main.o > dump.txtなどとすれば、そのディレクトリの中にdump.txtが作成され、以下のように逆アセンブラが出力されます。

逆アセンブラした結果(サクラエディタで閲覧)

 ちなみに私の場合、_delay_ms()がメモリを消費していたみたいです。直接の原因かは分かりませんが、公式には「The maximal possible delay is 262.14 ms / F_CPU in MHz.」と書かれているので、あまり大きな引数(400とか)にするのは考えものですね… 
Read more →