Created
December 3, 2017 11:18
-
-
Save Tomokatsu-Sakamoto/742ada586cb20de40cb22e07426d475f to your computer and use it in GitHub Desktop.
PCA9685 を搭載したサーボコントローラのサンプル動作 for PIC16F887
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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