
みなさん、こんにちは。
ケロタン少佐デあります・・・(^_^)ヾ
さてさてさて・・・♪
前回では、『角度センサー』からの、
データの変化量と、回転方向が分りました。
今回は実際に、これらのデータを使って、
角度を割り出してみたいと思います。
そこで、またまた例題を・・・
(例.)
【定義】
・正午位置での基準位置の、位置データを0とする。
・時計回りに回転させます。
・回転角度は30度
・データは、規定時間毎に現在データをサンプリングする
ことにより取得する
・サンプリング時間は、1/1000秒毎(1ms/)とする。
上記定義より、これから実験を行う為に、
専用実験機器を描いてみました。
これにロータリーエンコーダーを接続して、実際に
角度を表示させてみたいと思います。
【本体、回路図】
【本体、パターン図】
【表示部、回路図】
【表示部、パターン図】
今後は、実験機器を製作して、実際に角度を測ってみたいと思います。
ところで、なぜ、このようなことを
やっているかといいますと
・
・
・
『操舵角センサー』から、データを取出してやりたいからデあります。
ちなみに、こちらのユニットは、ハンドルシャフトにある
『操舵角センサー』にも取付できるように対応させています。
そして、ゆくゆくは、『自作AFS』とかできたらなと・・・
更には、『加速度センサー』からもデータを取出し
『DCS・TCS割込み制御ユニット』が作れないものかと
妄想しているデあります・・・(^_^;)ヾ
長々と、今回の駄ブログに、お付き合いくださいましてありがとうございました・・・m(__)m
最後に・・・
今回も、長ったらしいプログラムを・・・(笑
【プログラム】
/*************************************************************************************************
AVR Studio 4 C言語用 Ver1.0(ATtiny2313用) 2008.12.2
ロータリーエンコーダーのテスト プログラム (R・E・T)
Program Name : rotary-encoder-test-program-ver1.0.c
Version : 1.0
Language : AVR C言語 (WinAVR)
Device : ATtiny2313
Clock : 1MHz(内蔵RC発振)
Author : ケロタン少佐
**************************************************************************************************
I/O
RESET,PA2 | 1****20| VCC
PD0 | 2****19| PB7
PD1 | 3****18| PB6
XTAL2,PA1 | 4****17| PB5
XTAL1,PA0 | 5****16| PB4.OC1B
INT0,PD2 | 6****15| PB3,OC1A
INT1,PD3 | 7****14| PB2,OC0A
T0,PD4 | 8****13| PB1
OC0B,T1,PD5 | 9****12| PB0
GND |10****11| PD6,ICP
PORTA2 ; 入力 ; 内部プルアップ,立下り検出- ; RESET
PORTA1 ; 出力 ; LED(red),作動確認用
PORTA0 ; 出力 ; LED(green),パイロット用
PORTB7 ; 出力 ; seg_a
PORTB6 ; 出力 ; seg_b
PORTB5 ; 出力 ; seg_c
PORTB4 ; 出力 ; seg_d
PORTB3 ; 出力 ; seg_e
PORTB2 ; 出力 ; seg_f
PORTB1 ; 出力 ; seg_g
PORTB0 ; 出力 ; seg_p
PORTD6 ; 出力 ; tr_1000
PORTD5 ; 出力 ; tr_100
PORTD4 ; 出力 ; tr_10
PORTD3 ; 出力 ; tr_1
PORTD2 ; 出力 ; def
PORTD1 ; 入力 ; 内部プルアップ,立下り検出- ; rsw_b
PORTD0 ; 入力 ; 内部プルアップ,立下り検出- ; rsw_a
**************************************************************************************************
動作仕様
1.4桁の7セグメントに回転情報を表示する。
2.操舵角センサーにも取付可能
STATUS LEDの動作
点滅・・・(2Hz)
セッティングモード中
点灯・・・(1Hz)
通常モード中
*********************************************************************************************** */
#include
#include
#include
// PORTA
#define RESET 2
#define LED_red 1
#define LED_green 0
// PORTB
#define seg_a 7
#define seg_b 6
#define seg_c 5
#define seg_d 4
#define seg_e 3
#define seg_f 2
#define seg_g 1
#define seg_p 0
// PORTD
#define def 7
#define tr_1000 6
#define tr_100 5
#define tr_10 4
#define tr_1 3
#define def 2
#define rsw_b 1
#define rsw_a 0
/*************************************************************************************************
******* グローバル宣言 */
volatile char s1,s0,t1,t0;
volatile uint16_t cnt,cnt4;
// 7セグ表示用データ
uint8_t seg_dat[] = {
0b11111100, ;0
0b01100000, ;1
0b11011010, ;2
0b11110010, ;3
0b01100110, ;4
0b10110110, ;5
0b10111110, ;6
0b11100100, ;7
0b11111110, ;8
0b11110110 ;9
};
/*************************************************************************************************
******* プロトタイプ宣言 */
void init_io(void);
void init_tim(void);
void init_dat(void);
void wait_100us(uint16_t);
/*************************************************************************************************
******* タイマ0割込み 1ms毎にエンコーダのデータを取得 */
SIGNAL(SIG_OVERFLOW0){ // 1MHz/64 = 16kHz
TCNT0=241; // タイマーのカウンタセット 256-16=241 →1000Hz
s0=s1; // swを調べる 新データを旧データ変数に入れて
s1= (PIND & 0b00000011); // 新データを読み込む bit1-0 にrswがあるから off=1 on=0
if (s1 == 3){
s1 = 2; // 3→2へ変換
} else if (s1 == 2){
s1 = 3; // 2→3へ変換
}
if (((s1 - s0 == 1)||(s1 - s0 == -3)) && (cnt < 39997)){ // Max 39997 = 9999 × 4ターム
cnt++; // 3→0も正回転(CW)
}
if (((s1 - s0 == -1)||(s1 - s0 == 3)) && (cnt > 0)){ // Min 0
cnt--; // 0→3も逆回転(CCW)
}
cnt4=cnt; // クリック付きは4ターム1セットなので cnt4=cnt/4に変更
}
/*************************************************************************************************
******* メイン */
int main(void){
uint8_t d1,d10,d100,d1000,i; // 符号なし8bit変数宣言
uint16_t j; // 7seg桁変換用の一次変数
// 初期化
init_io(); // I/O初期化
init_tim(); // タイマー初期化
init_dat(); // データ初期化
sei(); //
PORTA |= _BV(LED_green); // LED点灯
// セッティング記録の読込み
// 中立位置の検出
s0 = PIND & 0b00000011; // 入力信号初期値を代入
d1 = 0; // クリア
d10 = 0; // クリア
// メインループ
while(1) {
// ステータスLED点滅(red)
PORTA ^= _BV(LED_red); // LEDを反転
// 7セグメント表示用にBCD変換
j = cnt4; // 表示数字のカウントアップ
d1000 = j / 1000; // 1000の位抽出
j = j - d1000 * 1000; // 1000の位除外
d100 = j / 100; // 100の位抽出
j = j - d100 * 100; // 100の位除外
d10 = j / 10; // 10の位抽出
j = j - d10 * 10; // 10の位除外
d1 = j; // 1の位抽出
// 7セグメント表示処理
for(i=1;i<250;i++){
PORTD |= ~_BV(tr_1000); // 最上位桁表示
PORTB = seg_dat[d1000]; // 1000の位
wait_100us(5); // 500us
PORTD &= ~_BV(tr_1000); // 全表示消灯
PORTD |= ~_BV(tr_100); // 100の位表示
PORTB = seg_dat[d100]; //
wait_100us(5); // 500us
PORTD &= ~_BV(tr_100); // 全表示消灯
PORTD |= ~_BV(tr_10); // 10の位表示
PORTB = seg_dat[d10]; //
wait_100us(5); // 500us
PORTD &= ~_BV(tr_10); // 全表示消灯
PORTD |=_BV(tr_1); // 最下位桁表示
PORTB = seg_dat[d1]; // 1の位
wait_100us(5); // 500us
PORTD &= ~_BV(tr_1);
}
}
}
/*************************************************************************************************
******* init_io I/O 初期化処理 */
void init_io(void){
PORTA = 0b00000100; // 2プルアップ
DDRA = 0b00000011; // 1-0出力
DDRB = 0b11111111; // 全出力
PORTB = 0b00000000; // 0=all
PORTD = 0b00000011; // 1-0プルアップ
DDRD = 0b01111100; // 6-2出力
}
/*************************************************************************************************
******* init_tim タイマー 初期化処理 */
void init_tim(void){
TCCR0=3; // タイマ0の分周比=1/64
TIMSK=(1<<TOIE0); // タイマ0 割り込み許可
TCNT0=241; // タイマーのカウンタセット
}
/*************************************************************************************************
******* init_dat 各種データ 初期化処理 */
void init_dat(void){
cnt = 0; // 初期値0
}
/*************************************************************************************************
******* wait関数_100us */
void wait_100us(uint16_t time) { // 100us wait ルーチン。 クロック設定のこと。
// 25MHzでも 260ms までとれる。
time*=1; // 8MHzのとき。timeにF_CPU(MHz)をかける。重要!!
uint8_t lpcnt;
__asm__ __volatile__("\n"
"Entry%=: \n\t"
"ldi %0,24\n" // 計算値は25。24の方が実測値は良い。
"Loop%=: \n\t"
"nop\n\t"
"dec %0\n\t"
"brne Loop%=\n\t"
"sbiw %1,1\n\t"
"brne Entry%=\n\t"
:"=&a"(lpcnt)
:"w"(time)
);
return;
}
/*************************************************************************************************
******* END */
Posted at 2008/12/05 16:00:53 | |
トラックバック(0) |
電子工作 | 日記