picマイコンの勉強でLEDピカピカまでいきました。

前回までの記事です。

 

そう、私の目標はあくまでPICマイコンによってACモータをスピードコントロールする事です。

また、LCDにスピードや回転数を表示させたり、PICマイコンでフィードバック制御(PID制御で)させたりしたいのでpicマイコンの基礎から勉強しているわけです。

 

今回の勉強はpicマイコンによってサーボモータを動かすのが目標です。

サーボモータのwikiはこちら

サーボモータは基本的にPWMという制御を使います。

 

このPWMはPICマイコンだと簡単に作る事ができます。

でもつくり方はだいたい2種あって、マイコンのCCPという機能を使って簡単に作る方法と、もう一つは割り込みという機能を使ってPWM信号を作り出す方法があります。

 

今回は簡単なCCPという方法を試してみました。

 

まずPWMとはパルスワイドモジュレーションといってパルス幅変調と言います。

 

臨床工学技士ならしってて当然なPWMです。

 

 

簡単にいうと一定間隔でパルスが立ち上がって、そのパルスの幅を変化させる事で制御機器の動き方が変わるという寸法です。

 

サーボモータもだいたいですが、15〜20msecずつのパルス間隔でパルス幅が1〜2.5msecでモータの回転角度が決まってその位置が決まります。

servo1

下記サイトから借用です。

 

詳しくは制御するサーボモータの取説を参照する事が良いでしょう。

ここらへんが参考になりました。

 

 

今回の制作では

マイコンをPIC16F88を使用(CCP機能があるからと84Aとピン配置がほぼ同じ)

C言語でプログラム

MPLAB X 使用でXC8でコンパイル

んで書き込みはAKIプログラマー4でやりました。

サーボモータは秋月電子で買ったS03Tを利用

クロッックはPIC16F88は内臓クロック(むっちゃ便利)があったので内部クロック1MHzを利用

 

 

 

回路はこんな感じ

内部クロックは1MHz

かなりシンプルな感じに仕上がりました。

スポンサードリンク

pic16f88serboccp

 

〜プログラム〜

// PIC16F88 Configuration Bit Settings

#include <xc.h>

 

// CONFIG1

#pragma config FOSC = INTOSCIO//内部クロックを使用
#pragma config WDTE = OFF // ウォッチドッグタイマはオフ
#pragma config PWRTE = ON // パワーアップタイマーはオン
#pragma config MCLRE = OFF //
#pragma config BOREN = OFF //
#pragma config LVP = OFF //
#pragma config CPD = OFF //
#pragma config WRT = OFF // F
#pragma config CCPMX = RB3 // CCP1 はRB3から出力
#pragma config CP = OFF //コードプロテクトはオフ

 

// CONFIG2

#pragma config FCMEN = OFF //
#pragma config IESO = OFF //

 

#define _XTAL_FREQ 1000000 //delay関数を使う為の設定 クロックは1MHz

 

 

void main(void){
OSCCON =0b01000000;//クロックを1MHzに設定
ANSEL = 0b00000000;//AD設定はすべてデジタルで設定
TRISA = 0b00000000;//ポートAは全て出力に設定
TRISB = 0b00000000;//ポートBは全て出力に設定
PORTA = 0b00000000;//ポートをクリア
PORTB = 0b00000000;//ポートクリア
CCP1CON = 0b00001100; // PWMモードにする

/*パルス周期はT2CONとPR2によって変わる。クロックが1MHzなので1命令で4クロック。 なので4usec*255(PR2)*16(プリスケーラー)=16320usec*/
T2CON = 0b00000110; // プリスケール16
PR2 = 255; // PWM周期
CCPR1L=25; // 中央 パルス幅はCCPR1Lの値を可変させる事で変更できる 今回10-40の間でパルス幅がちょうど0.6msec-2.3msecになる。
while (1) {
CCPR1L=10;//中央の位置から右に90度移動
PORTBbits.RB1 = 1;
__delay_ms(1500);
PORTBbits.RB1 = 0;
__delay_ms(500);
CCPR1L=25;//中央にもどる
PORTBbits.RB1 = 1;
__delay_ms(1500);
PORTBbits.RB1 = 0;
__delay_ms(500);
CCPR1L=40;//中央から左に90度移動
PORTBbits.RB1 = 1;
__delay_ms(1500);
PORTBbits.RB1 = 0;
__delay_ms(500);
CCPR1L=25;//中央にもどる
PORTBbits.RB1 = 1;
__delay_ms(1500);
PORTBbits.RB1 = 0;
__delay_ms(500);
}
return;
}

CCP機能を使う場合、出力はRB0かRB3しか使えません。

それを決定するのがコンフィグ1のCCPMXです。

#pragma config CCPMX = RB3 // CCP1 はRB3から出力 というふうに記述します。

 

こんな感じでうごいてくれました。

スポンサードリンク