Skip to content

Instantly share code, notes, and snippets.

@Tomokatsu-Sakamoto
Created December 3, 2017 11:18
Show Gist options
  • Save Tomokatsu-Sakamoto/742ada586cb20de40cb22e07426d475f to your computer and use it in GitHub Desktop.
Save Tomokatsu-Sakamoto/742ada586cb20de40cb22e07426d475f to your computer and use it in GitHub Desktop.
PCA9685 を搭載したサーボコントローラのサンプル動作 for PIC16F887
#include <16F887.h>
#fuses HS,NOWDT,BROWNOUT,NOMCLR,NOLVP,NOCPD
#device ADC=8 // AD変換分解能の指定
#use delay(clock=10M)
// I2C使用宣言
// MASTER - マスタ・デバイスを設定
// SLAVE - スレーブ・デバイスを設定
// SCL=pin - SCL ピンを指定(ビットアドレス)
// SDA=pin - SDA ピンを指定
// ADDRESS=nn - スレーブ・デバイス時のアドレスを設定
// FAST - 高速I2C を設定
// SLOW - 低速I2C を設定
// RESTART_WDT - I2C_READ でデータを取得中にWDT クリアを行う
// FORCE_HW - 内蔵ハードウェアI2C を使用する。
// NOFLOAT_HIGH - 信号がハイになることを許可しません。
#use i2c( MASTER, SDA=PIN_C4, SCL=PIN_C3 )
#define ADRESS_PCA9685 0x80 // PCA9685 のデバイスアドレス
///////////////////////////////////////////////////////////////////////
// I2Cデバイスへの16bitデータの書き込み
void write_PCA16(
unsigned char lowad, // I2Cアドレス下位6ビット
unsigned char reg, // レジスタNo.
unsigned long data ) // 16bitデータ
{
//書き込み開始
i2c_start( );
i2c_write( ADRESS_PCA9685 + ( lowad << 1 ) ); // I2Cアドレス
i2c_write( reg ); // レジスタNo.
i2c_write( data & 0x00FF ); // 下位データ
i2c_write( data >> 8 ); // 上位データ
i2c_stop( );
}
///////////////////////////////////////////////////////////////////////
// I2Cデバイスへの8bitデータの書き込み
void write_PCA8(
unsigned char lowad, // I2Cアドレス下位6ビット
unsigned char reg, // レジスタNo.
unsigned char data ) // 8bitデータ
{
//書き込み開始
i2c_start( );
i2c_write( ADRESS_PCA9685 + ( lowad << 1 ) ); // I2Cアドレス
i2c_write( reg ); // レジスタNo.
i2c_write( data ); // データ
i2c_stop( );
}
///////////////////////////////////////////////////////////////////////
// サーボコントローラ PCA9685を初期化
void init_servo( )
{
int i,j;
// いったんスタンバイにする(プリスケーラ設定のため)
write_PCA8( 0, 0, 0x31 );
// プリスケーラ設定。分解能4us、周期20ms(周波数50Hz)!!デバイスごとに調整!!
write_PCA8( 0, 0xFE, 121 );
// MODE1設定 レジスタインクリメント、All-Call有効、アクティブ
write_PCA8( 0, 0, 0x21 );
// MODE2設定 トーテムポール出力設定
write_PCA8( 0, 1, 0x04 );
// パルス初期値書き込み(1500us)
j = 0x06;
for ( i = 0 ; i < 16 ; i++ ) {
write_PCA16( 0, j, 0 ); // パルススタート
j += 2;
write_PCA16( 0, j, 375 ); // パルスエンド
j += 2;
}
}
///////////////////////////////////////////////////////////////////////
// サーボセット(サーボ位置をパルス幅で渡す)
void pos_servo(
int id, // サーボ0~15
unsigned long pos ) // パルス幅(us)1500usでニュートラル
{
int i;
i = 8 + id * 4 ;
write_PCA16( 0, i, pos / 4 );
}
void main( void )
{
set_tris_c( 0x00 ); // すべて出力
init_servo( );
while ( TRUE ) {
pos_servo( 15, 1000 );
delay_ms( 2000 );
pos_servo( 15, 1500 );
delay_ms( 2000 );
pos_servo( 15, 2000 );
delay_ms( 2000 );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment