さて、マイコン単体でいろいろやるのも楽しいが、外部の装置と接続したい。
デジタル通信ができるようになればかなり幅が広がるはず。
バスにいくつも接続できるI2Cが良さそうだ。
さて、マイコン単体でいろいろやるのも楽しいが、外部の装置と接続したい。
デジタル通信ができるようになればかなり幅が広がるはず。
バスにいくつも接続できるI2Cが良さそうだ。
さて、ATTiny2313というマイコンは100円で買えた時期があったので、いくつか持っていたかとおもったが、どこにしまったかわからない。ストックから出てくるのはATMega88,168,328ばかりである。
ATTiny2313は諦めてATMegaで組もうかと思う。ATMega88は一つ170円@秋月電子ですし。
レジスタ周りは比較的似ているので、結構ソースそのままでいけるかんじ。
そして、サーボが動いた。とりあえず、往復するだけのワイパーみたいな動作だが、うごいた。
何かに応用しよう。
ATTiny2313には16bitタイマーがあるので、コレを使ってサーボモーターのコントロールをしようと思う。
パルスのHigh出力は500us~1500usの可変で、パルス周期は20msとする。
内蔵8MHzの8分周にて1MHzの信号が出力できて、20msは20,000カウントと、16bitタイマーにちょうど良い感じ。
とりあえずパルスhighを1000us±500usとなるようにプログラムを書いてみようと。三角波出力予定なので、サーボモータが右に行ったり左に行ったりを繰り返す予定。
マイコンのレジスタは同じATMELとはいえ、他のマイコンと少しずつちがって、ATTiny2313は高速PWMモードにてサーボのコントロールができる。
はじめデータシートを見ながらCTC(Clear Timer on Compare)が、PWMのカウント上限値をセットするモードだとおもってハマった。
PWMをやりたいときは、PWMモードから選べば良い。
さて、使うのは上記表46の14のモード。ちなみに15のモードはカウント上限をOCR1Aでセットするので、OC1AのピンにPWM出力ができない。しかし、14のモードはカウント上限をICR1という別のレジスタにセットできるので、OC1AとOC1Bにて違うduty比のパルスを出力することができる。
タブが潰れるが、いかが今のところテストしているコード。
#define F_CPU 1000000 //8MHz clock + DIV8
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
//16bitタイマーで回すからタイマーを16bitにするところから始めないと
//CTCじゃないみたいだぞ
DDRB = 0b00011000;
DDRD = 0b00000001;
ICR1 = 30;
OCR1A =10;
OCR1B =5;
TCCR1A = 1 << COM1A1
| 0 << COM1A0
| 1 << COM1B1
| 0 << COM1B0
| 1 << WGM11
| 0 << WGM10;
TCCR1B = 0 << ICNC1 /* */
| 0 << ICES1
| 1 << WGM13
| 1 << WGM12
| 0 << CS12
| 1 << CS11
| 0 << CS10;
// | 0 << CS12 /* 分周決定 */
// | 0 << CS11 /* CS1[2:1]が000 ,001,010,011,100, 101がそれぞれ次の分周 */
// | 1 << CS10; /* CS1[2:1]が停止, 1, 8, 64,256,1024 */
while(1)
{
//TODO:: Please write your application code
}
}