• 車種別
  • パーツ
  • 整備手帳
  • ブログ
  • みんカラ+

ケロタン少佐のブログ一覧

2008年12月05日 イイね!

角度検出の仕組みは?・・・【角度検出その3】

角度検出の仕組みは?・・・【角度検出その3】みなさん、こんにちは。
ケロタン少佐デあります・・・(^_^)ヾ




さてさて・・・♪


では、『角度センサー』は、いかにして

角度データを作り出しているのでしょう?




(例)を出して考えてみます。


今、手元にボリューム(ロータリーエンコーダ)が1つあるとします。

このボリュームは正午の位置で中立基準となっています。

ここで、時計回りに30度程傾けてみましょう。




【図1.】







はい、時計回りに30度程傾きましたね。



では、この時、『角度センサー』は、どの様なデータを生成しているのでしょう?









と、その前に、『角度センサー』の内部構造について

みてみましょう。



【図2.】







はい。これは、『角度センサー』の内部構造を簡略化した図になります。

一般的な『角度センサー』には、『機械式』と『光学式』の2つが

使われています。


・機械式の場合は、2つの接点を開け閉めすることにより、
合計4パターンのデジタルデータを生成しています。

・光学式の場合は、2つのフォトダイオードを使用して、
同じく合計4パターンのデジタルデータを生成しています。


どちらの場合も、AとBの出力があり、BはAよりもワンテンポずれて

信号を出力しています。この信号は、単純なON・OFFのデジタル

信号になっており、どちらもパルスを形成しています。

そして、このパルスのズレによって、4つのデジタルパターンが

形成されています。





それでは、その4パターンのデータから、どの様にして

角度情報を得るかですが・・・


【図3.】







こちらが、実際に生成されるデータ配列になります。

『機械式』でも『光学式』でも合計4つのデータが

生成されるのは、先ほど述べました。

今、仮にその4つのデータを、0・1・3・2と定義します。

すると、時計回りにボリュームを回し続けると、



0・1・3・2・0・1・3・2・・・・・・0・1・3・2・・・


と生成データは出力され続けます。


ここでこの配列パターンを分り易く置き換えてみます。

定義として・・・

・0_→_0
・1_→_1
・3_→_2
・2_→_3

と置き換えます。


すると、データの遷移パターンは、


・0_→_1_は_1_-_0_=_+1
・0_→_2_は_2_-_0_=_+2
・0_→_3_は_3_-_0_=_+3
・1_→_2_は_2_-_1_=_+1
・1_→_3_は_3_-_1_=_+2
・2_→_3_は_3_-_2_=_+1


と、+1、+2、+3の変化があることがわかります。(ちょっと簡略化してます)


ここで変化量が+値の場合は、時計回り

-値の場合は反時計周りであることが分りました。



次に、角度の求め方ですが・・・




こちらは次回に・・・♪





【角度検出その4】へつづく・・・

Posted at 2008/12/05 15:08:23 | コメント(2) | トラックバック(0) | 電子工作 | 日記
2008年12月05日 イイね!

ロータリーエンコーダ・・・【角度検出その2】

ロータリーエンコーダ・・・【角度検出その2】
みなさん、こんにちは。
ケロタン少佐デあります・・・(^_^)ヾ




さて、つづきデあります♪


ネットにて色々と調べていくと・・・

歯車の角度検出には、『角度センサー』なるものが

使われていることが、分りました。



さてさて・・・

では『角度センサー』とは、どの様な仕組みなのでしょう?



そこで、身近に『角度センサー』が組み込まれている

ものを探してみることにしました。




色々と調べていくと、表題の『ロータリーエンコーダ』にも

使われていることが分りました。



ロータリーエンコーダとは・・・


そう、アレです。


最近のオーディオのボリューム調整とか

電子レンジのダイヤルとかに使われていたり。

自動車だと、エアコンの温度調整ダイヤルなどにも

使用されていますね。


アレって、回せど回せど終わりがなく、

無限にまわりますよね。



みなさんは、気になったことはありませんか?

ケロタンちょっと調べて、考えました。



考察は次回に・・・♪





【角度検出その3】へつづく・・・

Posted at 2008/12/05 12:54:08 | コメント(6) | トラックバック(0) | 電子工作 | 日記
2008年12月05日 イイね!

歯車を回してみる!?・・・【角度検出その1】

みなさん、こんにちは。
ケロタン少佐デあります・・・(^_^)ヾ




最近、ながったらしいプログラムの記事ばかりで
ファンを無くしているとか、しないとか・・・(汗



ところで、歯車の角度検出ってどうやっているのでしょう?

みなさんは、気になったことはありませんか?

ケロタンちょっと調べて、考えました。



考察は次回に・・・♪





【角度検出その2】へつづく・・・
Posted at 2008/12/05 12:13:09 | コメント(2) | トラックバック(0) | 電子工作 | 日記
2008年11月29日 イイね!

アクセル開度もコントロールしちゃう♪

アクセル開度もコントロールしちゃう♪おはようございます。

ケロタン少佐デありま~す・・・(^_^;)ヾ




こんかいは・・・


TREC



PIVOT



BRITZ

の様なものを

自作にて考えてみまちた。


回路図は・・・







アクセル開度テーブルは・・・







1.ノーマル
2.フラット
3.スポーツ
4.エコ
5.バック

の5種類から・・・





【システム用件】

・運転席足元のアクセルペダル上に設置してある
アクセル開度センサーに割り込み配線

・開度センサーは、ボリューム抵抗によるアナログデータと推測。

・おそらく、0V~5Vのアナログデータである。

・角度検出のデジタルデータであった場合は、再度修正予定
こっちの方がデジタルなので楽かな…(例)舵角センサー



【制御フロー】

・アクセル開度に応じた電圧値のアナログデータを取得

・マイコン内にて、デジタルデータへ変換

・各モードテーブルに沿ったデジタルデータへ変更

・専用IC用にデータをデジタル変換

・専用ICへデータ送信

・デジタルデータをアナログ電圧データに変換

・アクセル開度センサーへ出力

・最初へ戻る(無限ループ)





【プログラム】

/*************************************************************************************************

AVR Studio 4 C言語用 Ver1.1(ATmega88用) 2008.11.28

アクセル開度コントロール プログラム (A・O・C)

Program Name : accel-open-control-ver1.1.c
Version : 1.1
Language : AVR C言語 (WinAVR)
Device : ATmega88
Clock : 1MHz(内蔵RC発振)
Author : ケロタン少佐


**************************************************************************************************

I/O

(PCINT14/RESET) PC6 | 1****28| PC5 (ADC5/SCL/PCINT13)
(PCINT16/RXD) PD0 | 2****27| PC4 (ADC4/SDA/PCINT12)
(PCINT17/TXD) PD1 | 3****26| PC3 (ADC3/PCINT11)
(PCINT18/INT0) PD2 | 4****25| PC2 (ADC2/PCINT10)
(PCINT19/OC2B/INT1) PD3 | 5****24| PC1 (ADC1/PCINT9)
(PCINT20/XCK/T0) PD4 | 6****23| PC0 (ADC0/PCINT8)
VCC | 7****22| GND
GND | 8****21| AREF
(PCINT6/XTAL1/TOSC1) PB6 | 9****20| AVCC
(PCINT7/XTAL2/TOSC2) PB7 |10****19| PB5 (SCK/PCINT5)
(PCINT21/OC0B/T1) PD5 |11****18| PB4 (MISO/PCINT4)
(PCINT22/OC0A/AIN0) PD6 |12****17| PB3 (MOSI/OC2A/PCINT3)
(PCINT23/AIN1) PD7 |13****16| PB2 (SS/OC1B/PCINT2)
(PCINT0/CLKO/ICP1) PB0 |14****15| PB1 (OC1A/PCINT1)


PORTB7 ; 出力 ; H ; def
PORTB6 ; 出力 ; H ; def
PORTB5 ; 出力 ; H ; def
PORTB4 ; 出力 ; H ; def
PORTB3 ; 出力 ; H ; def
PORTB2 ; 出力 ; H ; +信号 ; dat_ch ; データ送信チャンネル
PORTB1 ; 出力 ; H ; +信号 ; cs_ch
PORTB0 ; 出力 ; H ; +信号 ; clk_ch

PORTC6 ; 入力 ; L ; -信号 ; RESET
PORTC5 ; 出力 ; H ; def
PORTC4 ; 出力 ; H ; def
PORTC3 ; 入力 ; L ; -信号 ; menu_sw
PORTC2 ; 入力 ; L ; -信号 ; select_sw
PORTC1 ; 入力 ; L ; -信号 ; back_s
PORTC0 ; 入力 ; ADC0 ; アクセル開度信号入力 ; accel_s

PORTD7 ; 出力 ; H ; seg_a
PORTD6 ; 出力 ; H ; seg_b
PORTD5 ; 出力 ; H ; seg_c
PORTD4 ; 出力 ; H ; seg_d
PORTD3 ; 出力 ; H ; seg_e
PORTD2 ; 出力 ; H ; seg_f
PORTD1 ; 出力 ; H ; seg_g
PORTD0 ; 出力 ; H ; status_LED



**************************************************************************************************

動作仕様
1.アクセル開度データを取得して変換し、モードテーブルを参照して出力する
2.任意変換モードは、ノーマル(N:0)、フラット(F:1)、スポーツ(S:2)、エコ(E:3)の4モードとする
3.後進はバックモードとする
4.設定値は、EEPROMに記憶させる
5.アクセル開度は、7セグにより逐次%表示(10桁のみ)する
6.フローはA/D変換→データ変換→D/A変換とする
7.D/A変換には、専用IC(MCP4822)を使用する


STATUS LEDの動作
点滅1・・・(2Hz)
点滅2・・・(10Hz)

*********************************************************************************************** */

#include (avr/io.h)
#include (avr/eeprom.h)


// PORTB
//#define def 7
//#define def 6
//#define def 5
//#define def 4
//#define def 3
#define dat_ch 2
#define cs_ch 1
#define clk_ch 0

// PORTC
//#define RESET 6
//#define def 5
//#define def 4
//#define menu_sw 3
//#define select_sw 2
//#define back_s 1
//#define accel_s 0

// PORTD
#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 status_LED 0




/*************************************************************************************************
******* グローバル宣言 */

uint8_t mode; // 0:Normal,1:Flat,2:Sports,3:Eco,4:Back
uint8_t mode_e __attribute__((section(".eeprom")));

uint8_t menu_stu; // 0:def 1:select 2:EEPROM_write&read
uint8_t adc; // A/D converter


// 7セグ表示用データ

uint8_t seg_dat[] = {
0b11111101, // 0
0b01100001, // 1
0b11011011, // 2
0b11110011, // 3
0b01100111, // 4
0b10110111, // 5
0b10111111, // 6
0b11100101, // 7
0b11111111, // 8
0b11110111, // 9
0b11111101, // 1O:Normal
0b10001111, // 11:Flat
0b10110111, // 12:Sports
0b10011111 // 13:Eco
};

// モード別テーブル
uint8_t kaido_dat[50];

// Normal モード ;0
uint8_t table_n[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};

// Flat モード ;1
uint8_t table_f[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};
// Sports モード;2
uint8_t table_s[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};
// Eco モード;3
uint8_t table_e[] __attribute__((section(".eeprom"))) ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};
// Back モード;4
uint8_t table_b[] ={
0,2,4,6,8,10,12,14,16,18,
20,22,24,26,28,30,32,34,36,38,
40,42,44,46,48,50,52,54,56,58,
60,62,64,66,68,70,72,74,76,78,
80,82,84,86,88,90,92,94,96,99
};


/*************************************************************************************************
******* プロトタイプ宣言 */

void init_io(void);
void init_adc(void);
void init_dat(void);

void wait_100us(uint16_t);

void table_in(void);
void menu(void);
void select(void);
int adc_convert(uint8_t);
void dac_out(uint16_t);
void seg_out(uint8_t);

/*************************************************************************************************
******* メイン */

int main(void){

// 初期化
init_io(); // I/O初期化
init_adc(); // A/Dコンバーター初期化
init_dat(); // データ初期化

PORTD |= _BV(status_LED); // LED点灯


// セッティング記録の読込み
eeprom_busy_wait(); // 読み書き可能になるまで待つ
mode = eeprom_read_byte(&mode_e); // EEPROMよりmodeデータを読出し
eeprom_busy_wait(); // 読み書き可能になるまで待つ
table_in(); // モードテーブルを選択格納
uint8_t i =0;
i = mode +10; // modeに+10の下駄をはかす
seg_out(i); // 選択モード表示
wait_100us(10000); // 1s待ち
wait_100us(10000); // 1s待ち 合計2s待ちオープニング

uint8_t x,x0; // 各SW変化検出用
x0 = PINC & 0b00001110; // 入力信号初期値を代入


// メインループ
while(1) {

// ステータスLED点滅(red)
PORTD ^= _BV(status_LED); // LEDを反転


// セッティング監査
x = PINC & 0b00001110; //
if (x != x0) {
if ((x & 0b00001000) != 0) {
menu();
}
if ((x & 0b00000100) != 0) {
select();
}
if ((x & 0b00000010) != 0) {
for(i=0;i<50;i++)
kaido_dat[i] = table_b[i]; // Back テーブルを格納
} else {
eeprom_busy_wait(); // 読み書き可能になるまで待つ
table_in(); // モードテーブルを選択格納
}
x0 = x; // 前回のスイッチ状況を反映
wait_100us(100); // 10ms待ち チャタリング防止用wait
}


// A/D 変換
adc = adc_convert(10); // ADC10からAD変換 512(例)

// データ変換
uint8_t accel_kaido =0;
accel_kaido = adc / 1023 / 2 * 100; // 50段階へ変換 25

// D/A変換用データ作成
uint8_t dac =0;
dac = kaido_dat[accel_kaido]; // パターン表を参照 50
uint16_t dac_ic_dat =0;
dac_ic_dat = dac * 41; // 2050

// D/A変換器へデータ送信
dac_out(dac_ic_dat); // 2050


// 7セグ表示
if (menu_stu != 0){
i =0;
i = mode + 10; // modeに+10の下駄をはかす
seg_out(i); // 選択モード表示
wait_100us(5000); // 500ms待ち LED点滅変更用wait
} else {
i =0;
i = dac / 10; // 表示用補正
seg_out(i); // アクセル開度表示 50
wait_100us(100); // 10ms待ち LED点滅変更用wait
}
}
}

/*************************************************************************************************
******* init_io I/O 初期化処理  */

void init_io(void){

DDRB = 0b11111111; // 全出力
PORTB = 0b01110000; // 0=all

PORTC = 0b01001110; // 6,3-1プルアップ
DDRC = 0b00110000; // 5-4出力

DDRD = 0b11111111; // 全出力
PORTD = 0b00000000; // 0=all

}

/*************************************************************************************************
******* init_adc A/Dコンバータ 初期化処理 */

void init_adc(void){

ADMUX = (1<<REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
// 外部AVCC基準;データレジスタ右そろえ;ADC0;01 0 0 0000;
// 0<REFS1,1<REFS0,0<ADLAR,0<def,0<MUX3,0<MUX2,0<MUX1,0<MUX0

ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS1);
// A/D変換許可;1回目変換開始(調整);分周率1/4;1 1 0 0 0 010;
// 1<ADEN,1<ADSC,0<ADATE,0<ADIF,0<ADIE,0<ADPS2,1<ADPS1,0<ADPS0

ADCSRB = 0;
// 連続変換動作;0 0 000 000;
// 0<def,0<ACME,0<def,0<def,0<def,0<ADTS2,0<ADTS1,0<ADTS0
}

/*************************************************************************************************
******* init_dat 各種データ 初期化処理  */

void init_dat(void){

mode = 0; // Normal 初期値0
menu_stu = 0; //
adc = 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;
}

/*************************************************************************************************
******* テーブル格納 */

void table_in(void){
uint8_t i;

switch(mode){
case 0:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_n[i]); // Normalテーブル格納
};
break;
case 1:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_f[i]); // Flatテーブル格納
};
break;
case 2:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_s[i]); // Sportsテーブル格納
}
break;
case 3:for(i=0;i<50;i++){
eeprom_busy_wait();
kaido_dat[i] = eeprom_read_byte(&table_e[i]); // Ecoテーブル格納
}
break;
default:mode = 0;
}
}

/*************************************************************************************************
******* menu */

void menu(void){
menu_stu++;
if (2 < menu_stu) {
menu_stu = 0;
}
if (menu_stu == 2){
eeprom_busy_wait(); // 読み書き可能になるまで待つ
eeprom_write_byte (&mode_e, mode); // EEPROMへmodeデータを書込み
menu_stu = 0;
eeprom_busy_wait(); // 読み書き可能になるまで待つ
table_in(); // モードテーブルを選択格納
}
}

/*************************************************************************************************
******* select */

void select(void){

if (menu_stu == 1){
mode++;
if (3 < mode) {
mode = 0;
}
}
}

/*************************************************************************************************
******* ピンを指定してAD変換 戻り値(return) 0-1023 */

int adc_convert(uint8_t pin){

ADMUX = pin; // AD変換入力ピン
ADCSRA &= ~_BV(ADIF); //
ADCSRA |= _BV(ADSC); // 変換開始
loop_until_bit_is_set(ADCSRA,ADIF); // 変換完了まで待つ
adc = ADCL; // 下位8bit取得
return adc += (ADCH<<8); // 上位2bit取得
}

/*************************************************************************************************
******* dac_out D/A変換器へデータ送信 */

void dac_out(uint16_t out) // D/A_out
{
uint8_t i = 0;

// 開始処理
PORTB = _BV(0 << clk_ch); // clock low
PORTB = _BV(0 << cs_ch); // CS on

// 以下4ビットがステータス設定ビット
// bit-1 // チャンネル設定ビット 0:chanel A 1:chanel B
// VoutA に出力
// PORTB = _BV(1 << dat_ch); // data high
PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// bit-2 // dummy;常時 1
PORTB = _BV(1 << dat_ch); // data high
// PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// bit-3 // ゲイン設定ビット 1:G=1, 0:G=2
// G = 2; V = Data/4096 * 2.048*2 [V]
// PORTB = _BV(1 << dat_ch); // data high
PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// bit-4 // シャットダウン設定ビット 1:出力イネイブル, 0:シャットダウン
// output enable
PORTB = _BV(1 << dat_ch); // data high
// PORTB = _BV(0 << dat_ch); // data low
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low

// ここから、データビット

for(i=0; i<12; i++){ // 送信データをMSBから順次1ビットづつ合計12bit分を出力する
// outの第12bitをチェック 0なら0を1なら1を出力する
if ((out & 0b0000100000000000) != 0){ // 0000 1000 0000 0000;
PORTB = _BV(1 << dat_ch); // 12bit目が1ならdata highを出力
} else {
PORTB = _BV(0 << dat_ch); // 12bit目が0ならdata lowを出力
}
out = (out << 1); // 送信後1bitだけ左にビットシフト
PORTB = _BV(1 << clk_ch); // clock high
PORTB = _BV(0 << clk_ch); // clock low
}

// 終了処理
PORTB = _BV(1 << cs_ch); // CS off
}

/**************************************************************************************************
******* 7セグメント表示 */

void seg_out(uint8_t data) {
uint8_t j,x,y;

x = PORTD; // ポート状態データ取得
PORTD = (x & 0b00000001); // 7seg 表示クリア

x = PORTD; // ポート状態データ再取得
x = (x ^ 0b11111110); // bit0以外を反転マスク

j = data; // データ取得
y = seg_dat[j]; // 7segデータを展開

PORTD = (x & y); // 7segデータをポートへ出力

}

/*************************************************************************************************
******* END */

Posted at 2008/11/29 12:51:23 | コメント(10) | トラックバック(0) | MPV | 日記
2008年10月31日 イイね!

運転席以外の窓もオート化デあります♪

運転席以外の窓もオート化デあります♪みなさん、お久しぶりです。

ケロタン少佐デあります(^_^)ヾ




さて、表題の通りに運転席のウインドウオート機能を、
助手席と後席でも可能にするユニットを開発してみたデあります♪

これは、お友達の『冬道』さんから、以前にご相談があった件になります。

同じ様なユニットに、八木澤さんのオートユニットがありますが、
あちらは、ダブルクリックにて、オートを起動しています。

今回、私が開発したユニットは、運転席と同じく、スイッチの
1秒間長押しにて、オートが作動するようになっています。

更に、運転席の集中スイッチでも長押しすれば、各窓がオートに
なるように回路を工夫して設計してあります。

更に更に、イグニッションオンにしなくても、動作する
隠し味も・・・秘密に・・・♪


あとは、プロトタイプを製作しての実験になります・・・(汗
(いつになるのやら...orz)


【ユニット設計図】
・回路図と部品実装図はフォトギャラをご覧下さい。


【制御概略】
・統合制御はAVRマイコンへ移管。
・集中・個別ウインドスイッチの電圧を時間と共に監視。
・マイコンから各ウインドアクチュエーターを制御。



【プログラム】

/*********************************************************************************

AVR Studio 4 C言語用 Ver1.1(ATtiny2313用) 2008.10.29

窓ガラス自動開閉 プログラム (A・PW)

Program Name : auto-PW-ver1.1.c
Version : 1.1
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
INT0,PD2 | 6****15| PB3
INT1,PD3 | 7****14| PB2
T0,PD4 | 8****13| PB1
T1,PD5 | 9****12| PB0
GND |10****11| PD6,ICP



PORTA0 ; 出力 ; LED01(green),パイロット用
PORTA1 ; 出力 ; def
PORTA2 ; 入力 ; 内部プルアップ,立下り検出- ; RESET

PORTB0 ; 出力 ; def
PORTB1 ; 出力 ; def
PORTB2 ; 出力 ; def
PORTB3 ; 出力 ; def
PORTB4 ; 出力 ; def
PORTB5 ; 出力 ; def
PORTB6 ; 入力 ; sw_up ; 内部プルアップ,立下り検出-
PORTB7 ; 入力 ; sw_down ; 内部プルアップ,立下り検出-

PORTD0 ; 出力 ; pwr_supply
PORTD1 ; 出力 ; def
PORTD2 ; 出力 ; def
PORTD3 ; 出力 ; LED02(red);up
PORTD4 ; 出力 ; LED03(blue);down
PORTD5 ; 出力 ; up_act
PORTD6 ; 出力 ; down_act

**********************************************************************************

動作仕様
1.運転席の窓ガラス・オート開閉機能を、各窓ガラスでも可能にする。
2.窓ガラス開閉スイッチを1秒以上押し続けると、指を離しても自動で開閉する。
3.自動開閉中に、開閉スイッチをチョン押しすると、即座に停止する。
4.純正の窓ガラス開閉システムと共存制御。

*********************************************************************************/

#include
#include

//PORTA
#define RESET 2
//#define def 1
#define LED_green 0

//PORTB
#define sw_down 7
#define sw_up 6
//#define def 5
//#define def 4
//#define def 3
//#define def 2
//#define def 1
//#define def 0

//PORTD
#define down_act 6
#define up_act 5
#define LED_down 4
#define LED_up 3
//#define def 2
//#define def 1
#define pwr_supply 0


/*********************************************************************************
******* グローバル変数 */

unsigned char m_status; // 0:neg 1:down 2:up

unsigned char sw_sec = 1; // 0~256 ; 8bit ; 数値任意設定(def:1 =1秒, 2 =2秒)
unsigned char sw_cnt; // 0~256 ; 8bit
unsigned char sw_down_cnt; // 0~256 ; 8bit
unsigned char sw_up_cnt; // 0~256 ; 8bit

unsigned char motor_sec = 1; // 0~256 ; 8bit ; 数値任意設定(def:1 =1秒, 2 =2秒)
unsigned int st_cnt; // 0~65536 ; 16bit

/*********************************************************************************
******* プロトタイプ宣言 */

void init_io( void);
void wait_1ms( int);
void all_stop( void);
void down_work( void);
void up_work( void);

/*********************************************************************************
******* TIM0_OVF */

ISR( TIMER1_OVF_vect ) {
cli(); // 全割込み禁止

TCCR1B = 0b00000000; // タイマ1動作停止
TCNT1 = st_cnt; // スタート初期値を設定

PORTD &= ~_BV(pwr_supply); // 電源供給遮断
PORTD &= ~_BV(down_act); // 窓下がるrelay-off
PORTD &= ~_BV(up_act); // 窓上がるrelay-off
PORTD &= ~_BV(LED_down); // 動作LED03(blue)消灯
PORTD &= ~_BV(LED_up); // 動作LED02(red)消灯

m_status = 0; // モータ停止中

sei(); // 全割込み許可
}

/*********************************************************************************
******* メイン */

int main( void ) {

unsigned char x;
unsigned int i;

//初期化
init_io(); // I/O 初期化

m_status = 0; // 0:neg 1:act
sw_cnt = 0; // 0~256 ; 8bit
sw_down_cnt = 0; // 0~256 ; 8bit
sw_up_cnt = 0; // 0~256 ; 8bit
st_cnt = 0; // 0~65536 ; 16bit

sw_cnt = sw_sec * 100; // 1秒は100ループ
i = motor_sec * 4096; // 1秒は4096クロック
st_cnt = 65536 - i; // タイマ1初期値を計算

//タイマカウンタ設定
TCCR1A = 0b00000000; // 標準動作設定
TCCR1C = 0b00000000; // 標準動作設定
TCNT1 = st_cnt; // スタート初期値を設定
TIMSK = 0b10000000; // タイマ1割込み許可

sei(); // 全割込み許可


//メインループ
while (1) {

// ステータスLED点滅
PORTA ^= _BV(LED_green); // 排他的論理和 PA0を反転

// 各種スイッチ状態取込
x = PINB; //

// 状態監査
if (m_status == 0){ // モーターは停止中か?
// 各種スイッチ監査
if ((x & 0b10000000) != 0){ // downスイッチ押下か?
sw_down_cnt ++; //
} else {
sw_down_cnt = 0; //
}
if ((x & 0b01000000) != 0){ // upスイッチ押下か?
sw_up_cnt ++; //
} else {
sw_up_cnt = 0; //
}
if ((x & 0b11000000) != 0){ // error
sw_down_cnt = 0; //
sw_up_cnt = 0; //
}
// 緊急停止
} else {
// up作動中緊急停止
if (m_status == 2 & (x & 0b10000000) !=0)
all_stop(); //

// down作動中緊急停止
if (m_status == 1 & (x & 0b01000000) !=0)
all_stop(); //
}

// 機器制御
if (sw_down_cnt > sw_cnt){
m_status = 1; // モータdown作動中
down_work(); // 窓下げ動作へ
} else {
sw_down_cnt = 0; //
}

if (sw_up_cnt > sw_cnt){
m_status = 2; // モータup作動中
up_work(); // 窓上げ動作へ
} else {
sw_up_cnt = 0; //
}

wait_1ms(10); // 10ms待ち チャタリング対策
}
}

/*********************************************************************************
******* init_io I/O 初期化 */

void init_io(void) {

PORTA = 0b00000100; // bit2のプルアップを有効に設定
DDRA = 0b00000011; // bit2のみ入力に設定

PORTB = 0b11000000; // bit7-6のプルアップを有効に設定
DDRB = 0b00111111; // bit7-6のみ入力に設定

PORTD = 0b00000000; // プルアップ無しに設定
DDRD = 0b01111111; // 全出力に設定

}

/*********************************************************************************
******* wait_1ms */

void wait_1ms( int time){
int i,j;
for( i = 0 ; i < time ; i++ )
for( j = 0 ; j < 55 ; j++ )
;
return;
}

/*********************************************************************************
******* 緊急停止 */

void all_stop(void) {
cli(); // 全割込み禁止

TCCR1B = 0b00000000; // タイマ1動作停止
TCNT1 = st_cnt; // スタート初期値を設定

PORTD &= ~_BV(pwr_supply); // 電源供給遮断
PORTD &= ~_BV(up_act); // 窓上がるrelay-off
PORTD &= ~_BV(down_act); // 窓下がるrelay-off
PORTD &= ~_BV(LED_up); // 動作LED02(red)消灯
PORTD &= ~_BV(LED_down); // 動作LED03(blue)消灯
m_status = 0; // モータ停止中

sei(); // 全割込み許可
}

/*********************************************************************************
******* ダウンワーク */

void down_work(void) {
cli(); // 全割込み禁止

PORTD |= _BV(pwr_supply); // 電源供給接続
PORTD |= _BV(LED_down); // 動作LED03(blue)点灯
PORTD |= _BV(down_act); // 窓下がるrelay-on
TCCR1B = 0b00000100; // プリスケール256、タイマスタート
TCNT1 = st_cnt; // スタート初期値を設定

sei(); // 全割込み許可
}

/*********************************************************************************
******* アップワーク */

void up_work(void) {
cli(); // 全割込み禁止

PORTD |= _BV(pwr_supply); // 電源供給接続
PORTD |= _BV(LED_up); // 動作LED02(red)点灯
PORTD |= _BV(up_act); // 窓上がるrelay-on
TCCR1B = 0b00000100; // プリスケール256、タイマスタート
TCNT1 = st_cnt; // スタート初期値を設定

sei(); // 全割込み許可
}

/*********************************************************************************
******* end */
Posted at 2008/10/31 14:21:08 | コメント(18) | トラックバック(0) | MPV | 日記

プロフィール

「お仕事ちうデあります・・・(^_^)ヾ」
何シテル?   09/04 11:33
めぐりめぐって初マツダです。 皆さんよろしくお願いします。 お約束ですが、当ブログの内容を見て整備、修理して不具合が生じても、当プログ主は責任を負えませ...
みんカラ新規会員登録

ユーザー内検索

<< 2025/8 >>

     12
3456789
10111213141516
17181920212223
24252627282930
31      

愛車一覧

マツダ MPV マツダ MPV
家族の為にミニバンにしました。 新型MPVのあまりの出来に家族で 大満足です。 これ ...
ホンダ シビック ホンダ シビック
私に操る楽しさを教えてくれた車です。 VTECのハイカムに入ったときの 加速がたまりま ...
日産 スカイライン 日産 スカイライン
私に整備の楽しさを教えてくれた車です。 かなり高齢でしたが、まだまだ元気でした。 一 ...
その他 その他 その他 その他
ブログ用画像倉庫

過去のブログ

2009年
01月02月03月04月05月06月
07月08月09月10月11月12月
2008年
01月02月03月04月05月06月
07月08月09月10月11月12月
2007年
01月02月03月04月05月06月
07月08月09月10月11月12月
2006年
01月02月03月04月05月06月
07月08月09月10月11月12月
ヘルプ利用規約サイトマップ
© LY Corporation