真夜中の工作室 midnight craftcenter

電子工作とカメラ、写真の趣味のブログ

タイマ割り込みでCLK OUT(暫定)

CLKを自在に出したい。
という欲求は、組み込みなら必ずあると思う。
とりあえず、現状は数十KHzなら出せるようになったが、数MHzは出せず、課題が多く残った。
現状のsketchは、下記。
4kHzを出力している。
圧電ブザー鳴らすぐらいならこれでも十分。
#define F_DIV
long TCNT1_B
の2箇所の値を変えれば任意のCLKが出せると思う。
ハードが8MHzか16MHzかにも注意。

/* 
  Atmega168 timer1CLKOUT
  暫定版
*/

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

// CLKOUT [kHz] 出力したいCLKの周波数
// F_CPU 16000000 (Arduino Diecimila )
//分周比 1  FDIV = 1
//分周比 8  FDIV = 2
//分周比 64  FDIV = 3
//分周比 256  FDIV = 4
//分周比 1024  FDIV = 5

#define F_DIV  5  //使いたい分周比をセット

// TCNT1_BOTTOM (65536-(F_CPU*(1/CLKOUT[kHz]/2)/(F_DIV*1000))

#define TCNT1_BOTTOM 65534 //割り込み周期をセット 4kHz

boolean I_FLAG = false;

int B_CLK=12;
boolean out=false;

void setup(){

  TIMSK1 = (1<<TOIE1); //タイマ/カウンタ1割り込み使用
  TCCR1A = 0;//タイマ使用
  TCCR1B = F_DIV; //分周数
  TCNT1 = 0;//タイマ/カウンタ1初期化
  sei(); // 全割り込み許可
  
  pinMode(B_CLK,OUTPUT);
}

void loop(){

}

ISR(TIMER1_OVF_vect){
  if(I_FLAG == true){ //フラグが真なら処理
    digitalWrite(B_CLK,out);  //CLK出力
    out = ~out;
    I_FLAG = false;
  }
  
  TCNT1 = TCNT1_BOTTOM;
  I_FLAG = true;
}


Arduinoで簡単にCLK出力出来ると思ったら甘かった。
あくまで、フィジカルコンピュータ。
delayなどの命令でそれらしい波形は出せるが、MHzは出せないし、
他の処理が並行して出来ない。
入出力デバイスの扱いは得意だが、カウンターを回して割り込みを・・というのは、不得手らしい。
しようがないので、ATMELで仕様書を探した。
基本的に、カウンタを回して出力したいCLK周期の半分で割り込みを発生し、
割り込み毎に出力ポートの極性を反転させれば、CLKになるはず。
Arduinoは16MHzか8MHzで発振させているので、ハードにあわせて設定すれば、数MHzくらい簡単に出せるのでは?
と考えた。
でも、自分はソフト開発は初心者なので手間取っている。


■Atmega168仕様書
http://www.atmel.com/dyn/products/product_card.asp?family_id=607&family_name=AVR%AE+8%2DBit+RISC+&part_id=3303
特に15章 16ビット タイマ/カウンタ1

有志により、日本語訳の仕様書もあった。
「HERO'S Download」というサイトにあります。
翻訳ソフトのままの日本語が多いけど。

仕様書を読んで、Timer1を使うとか、レジスタはそれなりに分かったが、具体的な記述は上手くできなかった。
割り込みベクターテーブルとか必要でなかったかなとか。
Timer用のTCCR1Aなどのレジスタをキーに検索したら、
ArduinoでTimer1を使った記述がそのまま見つかった。
大学の研究室のページらしい。
http://www.ine.sie.dendai.ac.jp/wiki/index.php?%C3%E6%C2%BC%A1%A1%C3%A3%CF%BA%2F%A5%E1%A5%E2%2F2007%2Fwiki%2FArduino%A4%C7%B3%E4%A4%EA%B9%FE%A4%DF%A1%CAISR%A1%CB
本名を連ねているのが逆に新鮮。
どこに書いていいのか分からないので、中村さんありがとうございます。参考になりました。

これをちょっと加工したのが上記のsketch。
オシロで実測してみたが、分周比とかいじっても、MHzは出てくれない。
もっと調べないといけないか。
例えば、全割り込み許可とかあやしい、このTimerだけ許可したい。
誰か分かる人に教えて貰えば直ぐだと思うんだけど。
自分は実力不足。CLK1つ満足に出せないとは!
それでもArduino上でもWiringとC言語がそのまま併記できるのは助かる。
今後、トラ技術付録PLD基板とかにArduinoからCLK供給して、組み合わせでいろいろ表現の幅を広げたいと思っている。

因みにこれは日記なので、sketchについて懇切丁寧には書かない。
忘念録目的以外では、基礎知識がある人で、同じような目的があってたまたま参考になればいいな程度で公開してます。
不具合を教えてくれる人や意見交換できる人が現れればいいなと考えているが、もう少し公開して意味があるものが蓄積されるまでは地道に頑張る。


■追記:
とりあえず、圧電ブザーだけ鳴らしてみた。

送信者 工作