Part3. トラ技のおまけ基板でNゲージを自動運転のソースリスト


//*****************************************************************************
// 2007/08/18 
// Part3. トラ技のおまけ基板でNゲージを自動運転
//
//「Part2. トラ技のおまけ基板でNゲージを自動加減速」のPwmPP2.cを改造しました。
// 前回のソフトでは、加減速を繰り返すだけでしたが、
// 今回は、発進→加速→定速走行→減速→停止→逆転発進を繰り返すようにしました。 
//*****************************************************************************
// 2007/07/29
// トラ技のおまけ基板で自動加減速パワーパックの実験をするソフト
// ハードはトランジスタ技術の2007年8月号に付属している基板を使用しました。
// ソフトは付属のCDをインストールすると作成される
// C:\CQ\tr0709\projects\AdcThruPwmフォルダ内のAdcThruPwm.cを元に改造しました。 
//*****************************************************************************

#include 
#include 
#include 
#include 

//--------------------------------------------------------------------
//ブートローダによる書き込みでは、コンフィグレーションレジスタは
//書き込まれません。
// configuration
	_FWDT(WDT_OFF);
//	_FGS(CODE_PROT_OFF);
	_FOSC(CSW_FSCM_OFF & FRC_PLL16);	// 7.37x16/4=29.48MHz Clock
	_FBORPOR(PBOR_OFF & PWRT_64 & MCLR_EN);
//--------------------------------------------------------------------

// A/D control register
unsigned int _ADCON1;
unsigned int _ADCON2;
unsigned int _ADCON3;
unsigned int _ADCHS;
unsigned int _ADPCFG;
unsigned int _ADCSSL;

// PWM control register
unsigned int _PTCON;
unsigned int _PWMCON1;
unsigned int _PWMCON2;

// data
unsigned int	AdData1;
unsigned int	PwmData;

#define		Dir_Cmd	_RB8 						// 正転/逆転指令出力
#define		Dir_SW	_RF4 						// 正転/逆転スイッチ入力
#define		AT_ML	_RF5 						// 自動/手動スイッチ入力

signed int	Kagen;								// 加速/減速のフラグです。
signed int	MaxSpeed;								// 最高速度を設定する変数です。
signed int	Teisoku;								// 定速のフラグです。これが1だと加減速を禁止します。
unsigned int	TeisokuTimer;							// 定速で走行する時間のタイマーです。この数値x20msecが定速走行時間になります。

//--------------------------------------------------------------------------------------------------------------------
// タイマー3の割り込みルーチンです。112.5Hz(8.88ms)
// 手動モードでは、A/D値(ボリュームムの入力)をPWMのDutyに変換します。
//
void __attribute__((__interrupt__, __shadow__, no_auto_psv)) _AltT3Interrupt(void)
{
    _RB6=~_RB6;									// タイマー3の周波数の確認用なので不要です。
    	if (TeisokuTimer !=0) {						// 定速タイマーがゼロでなければ(定速走行中ならば)
    		TeisokuTimer--;							// 定速タイマーをマイナス1
	}

	// --- A/D is 12bits, then trancate 2bits, PWM is 10bits
//	while(!IFS0bits.ADIF);							// A/D変換終了待ち
//	AdData12 = ReadADC12(0);						// 12bit resolution AD Data
//	AdData10 = AdData12>>2;						// 10bit resolution AD Data
	
	AdData1 = ReadADC12(0);						// 12bit resolution AD Data AN3
	
	if ( AT_ML==1) {								// AT_MLがHi(手動モード)ならば A/D値がPWMデータ。 
		PwmData = AdData1>>2;						// 10bit resolution for PWM
		SetDCOC2PWM(1024-PwmData);					// Duty値をセットしますがモータードライバの入力が負論理なので反転させます。
	}
	IFS0bits.ADIF = 0;								// clear A/D interuppt flag
	IFS0bits.T3IF = 0;								// clear T3 interuppt flag
}

//--------------------------------------------------------------------------------------------------------------------
// タイマー1の割り込みルーチンです。
// 加減速中にタイムアップする度にDUTYを1ディジット加減します。
//
void __attribute__((__interrupt__, __shadow__, no_auto_psv)) _AltT1Interrupt(void)
{
    _RB7=~_RB7;								// 加減速時間の周波数の確認用なので不要です。
 	    		
    if ( AT_ML==0) {							// AT_MLがLo(自動モード)で
	    
    		if (TeisokuTimer !=0) {				// 定速タイマーがゼロでなければ(定速走行中ならば)
//  			TeisokuTimer--;					// 定速タイマーをマイナス1
    		} else{

	    		if (Kagen==1) {					// 加減フラグが1ならば
				PwmData++;					// 1ディジット加速
				if (PwmData>=MaxSpeed){		// 最高速度以上ならば
					TeisokuTimer=563;			// 定速走行へ(563x8.88msec=5secが定速走行時間)
					Kagen=-1;					// 最高速で定速走行後は減速に転じます。
				}
			} else {							// 加減フラグが1でなければ
				PwmData--;					// 1ディジット減速
				if (PwmData==0){				// 停止(0%Duty)ならば
					TeisokuTimer=338;			// しばらく停止(338x8.88msec=3secが停止時間)
					Dir_Cmd=~Dir_Cmd;			// 停止後は、方向転換して 
					Kagen=+1;					// 加速に転じます。
				}
			}
		}
		SetDCOC2PWM(1024-PwmData);				// Duty値をセットしますがモータードライバの入力が負論理なので反転させます。
    }

	IFS0bits.T1IF = 0;							// clear T1 interuppt flagタイマー1の割り込み要因フラグをクリアします。
}
//
//--------------------------------------------------------------------------------------------------------------------
//   メ イ ン ル ー チ ン
//--------------------------------------------------------------------------------------------------------------------

int main(void)
{
	// port init
	TRISB=0x001F;							// RB9:5=OUT,RB4:0=IN
	TRISF=0b01111100;						// RF5:2=IN

	CNPU2bits.CN17PUE=1;					// CN17(RF4)=pullUp 自動/手動スイッチ入力
	CNPU2bits.CN18PUE=1;					// CN18(RF5)=pullUp 正転・逆転スイッチ入力


	// Use Alternate Interrupt Vector Table
	INTCON2bits.ALTIVT=1;
	// Confirm to turn off ADC
	ADCON1bits.ADON=0;
	// ADC init
	_ADCHS=	ADC_CH0_POS_SAMPLEA_AN3 & 
			ADC_CH0_NEG_SAMPLEA_NVREF;		// A-D channel-3 select
	SetChanADC12(_ADCHS);
	_ADCON1=ADC_MODULE_ON &
			ADC_IDLE_CONTINUE &
			ADC_FORMAT_INTG &
			ADC_CLK_TMR &
			ADC_AUTO_SAMPLING_ON &
			ADC_SAMP_OFF;
	_ADCON2=ADC_VREF_AVDD_AVSS &
			ADC_SCAN_OFF &
			ADC_SAMPLES_PER_INT_1 &
			ADC_ALT_BUF_OFF &
			ADC_ALT_INPUT_OFF;
	// Tad={Tcy(ADCS+1)}/2>334ns, Then ADCS>18.7, Tad=10*Tcy
	_ADCON3=ADC_SAMPLE_TIME_1 &
			ADC_CONV_CLK_SYSTEM &
			ADC_CONV_CLK_10Tcy;
	_ADPCFG=ENABLE_AN3_ANA & ENABLE_AN4_ANA;			// A-D channel-3&4 analog input
	_ADCSSL=SCAN_NONE;

	OpenADC12(_ADCON1, _ADCON2, _ADCON3, _ADPCFG, _ADCSSL);

// 加減速時間のタイマーにタイマー1を使用しました。
//	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152*4);	// この例では約80ms単位で1ディジットずつ加減します。
//	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152*3);	// この例では約40ms単位で1ディジットずつ加減します。
 	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152*2);	// この例では約20ms単位で1ディジットずつ加減します。
//	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152);		// この例では約10ms単位で1ディジットずつ加減します。
//	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152/2);	// この例では約5ms単位で1ディジットずつ加減します。
// 	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152/3);	// この例では約3.3ms単位で1ディジットずつ加減します。
// 	OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT, 1152/4);	// この例では約2.5ms単位で1ディジットずつ加減します。
																	// 加減速時間もボリュームで調節出来るようにしたいですね。
	ConfigIntTimer1(T1_INT_PRIOR_5 & T1_INT_ON);							// タイマー1の割り込み優先順位とON/OFF設定
// ----------------------------------------------------------------------------------------------------------------- 	

	// Timer3 setting
//	OpenTimer3(T3_ON & T3_GATE_OFF & T3_PS_1_1 & T3_SOURCE_INT, 1024-1);		// 28.8kHz sampling ADC
	OpenTimer3(T3_ON & T3_GATE_OFF & T3_PS_1_256 & T3_SOURCE_INT, 1024-1);	// 28.8kHz/256=112.5Hz(8.88ms)
	ConfigIntTimer3(T3_INT_PRIOR_5 & T3_INT_ON);

// PWMの周波数を決める部分です。下記の4種類から選べます。
// ロータリースイッチなどで選択可能にするのも面白いかも?
	// Timer2 setting
//	OpenTimer2(T2_ON & T2_GATE_OFF & T2_PS_1_1 & T2_SOURCE_INT, 1024-1);		// 28.8kHz carrier PWM
//	OpenTimer2(T2_ON & T2_GATE_OFF & T2_PS_1_8 & T2_SOURCE_INT, 1024-1);		// 28.8kHz/8=3.6kHz carrier PWM
//	OpenTimer2(T2_ON & T2_GATE_OFF & T2_PS_1_64 & T2_SOURCE_INT, 1024-1);	// 28.8kHz/64=450Hz carrier PWM
 	OpenTimer2(T2_ON & T2_GATE_OFF & T2_PS_1_256 & T2_SOURCE_INT, 1024-1);	// 28.8kHz/256=112.5Hz carrier PWM
// ----------------------------------------------------------------------------------------------------------------- 	
	OpenOC2(OC_IDLE_CON & OC_TIMER2_SRC &
		OC_PWM_FAULT_PIN_DISABLE, 0, 0);

	// enable interrupt
	DISICNT = 0x0000;
	MaxSpeed=700;									// 最高速度は700に設定しました。
												// 100%Dutyは1023(10bitに落としてる為)ですが、
												// 1023では早すぎるので上限(最高速度)を設定しています。
												// この数値を変えると最高速が変更されます。(1023が最大値)
													
	TeisokuTimer=0;								// 定速走行時間はゼロ
	PwmData=0;									// 最初は停止状態から
	Kagen=1;										// 加速します。
	
	// main loop
	while(1){

	    _RB5=~_RB5;                    				// CPUクロックの確認用。 
	
		if ( AT_ML==1) {							// 手動モードならば
			Dir_Cmd=Dir_SW;						// 正転・逆転チェック
		}


	}
}


inserted by FC2 system