2016年8月21日日曜日

ATTiny85のUSIでI2C通信を試してみる。

ATTiny85はI2Cのハードウェアは実装されていないが、USI(Universal Serial Interface)が備わっているので半分ハードウェア制御でI2Cも使えるようだ。(AVRではTWIと称している)

Tiny85への書き込み


配線図


AVRライタには、SparkfunのAVR Pocket Programmerというのを使っている。Tiny85を使うのははじめてなのでとりあえずLチカしてみた。

Fuse Bit
hHuse DF
lFuse 62
eFuse FF
LED_Blink.cpp
#define F_CPU   10000000L

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

int main(void)
{
    DDRB = 0x08;
    
    while(1)
    { 
        PORTB ^= 0x08;
        _delay_ms(100);
    }
}

I2C出力




I2Cはオープンドレインなので、1kΩのRでVCC(+5V)にPullUpしている。

ライブラリは「https://github.com/adafruit/TinyWireM」を使わせてもらった。Aruduino用のライブラリだが、

USI_TWI_Master.cpp
USI_TWI_Master.h

は素のAVR用なのでこれを使ってみた。

#define F_CPU   8000000UL

#include <avr/io.h>
#include "USI_TWI_Master.h"

const unsigned char I2C_Address = 0xAA; // 0b10101010
const unsigned char I2C_Write   = 0x01;

unsigned char twiMsg[] = { I2C_Address | I2C_Write, 0x55 };

int main(void)
{
    USI_TWI_Master_Initialise();
    
    while(1)
    {
        USI_TWI_Start_Read_Write(twiMsg, 2);
        USI_TWI_Master_Stop();
    }
}

スレーブのアドレスは適当に0xAA(7bit)にして、最下位はI2CのWriteの1なのでSDAは0b10101011になる。

出力波形


I2C信号らしきものは出力されてるようだ。オシロのカーソルで測定するとI2CのSCLは約400KHzだった。

SCLの9bit目はスレーブがSDAをLに引っ張らないといけないのでマスター側としての最初の動作はうまく行っていると思う。(たぶん)

メモ:


ATTiny85のADCは差動入力+Gain20倍に対応しているようなので(http://dad8893.blogspot.jp/2016/07/blog-post_22.html)I2C LCDを制御できるようにしてみたい。