Part2. トラ技のおまけ基板でNゲージを自動加減速のソースリスト
//*****************************************************************************
// 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 ResultData;
signed int Kagen; // 行を追加しました。 加速/減速のフラグです。
// Timer subroutine
void __attribute__((__interrupt__, __shadow__, no_auto_psv)) _AltT3Interrupt(void)
{
// --- A/D is 12bits, then trancate 2bits, PWM is 10bits
while(!IFS0bits.ADIF); // wait A/D
if ( _RB6==1) { // 行を追加しました。RB6がHiならば A/D値がPWMデータ。
ResultData = ReadADC12(0)>>2; // 10bit resolution for PWM
SetDCOC2PWM(ResultData); // set PWM data
} // 行を追加しました。
IFS0bits.ADIF = 0; // clear A/D interuppt flag
IFS0bits.T3IF = 0; // clear T3 interuppt flag
}
//--------------------------------------------------------------------------------------------------------------------
// 行を追加しました。 自動減加減速ルーチンです。
// RB6がLoならば自動加減速が有効になります。
// タイマー1がタイムアップする度にDUTYを1ディジット加減します。
//
void __attribute__((__interrupt__, __shadow__, no_auto_psv)) _AltT1Interrupt(void)
{
_RB7=~_RB7; // 加減速時間の周波数の確認用なので不要です。
if ( _RB6==0) { // RB6がLoで
if (Kagen==1){ // 加減フラグが1ならば
ResultData++; // 1ディジット加速
if (ResultData==800){ // 100%Dutyは1023(10bitに落としてる為)ですが、
// 1023では早すぎるので800を上限にしています。
// この数値を変えると最高速が変更されます。(1023が最大値)
Kagen=-1; // 最高速に達すると減速に転じます。
}
} else { // 加減フラグが1でなければ
ResultData--; // 1ディジット減速
if (ResultData==0){ // 0%Dutyならば
Kagen=+1; // 加速に転じます。
}
}
SetDCOC2PWM(1024-ResultData); // Duty値をセットしますがモータードライバの出力が負論理なので反転させます。
}
IFS0bits.T1IF = 0; // clear T1 interuppt flagタイマー1の割り込み要因フラグをクリアします。
}
//行の追加ここまで。
//--------------------------------------------------------------------------------------------------------------------
// Main routine
int main(void)
{
// port init
TRISB=0x007F; // 変更しました。
// 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; // A-D channel-3 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*2); // この例では約20ms単位で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); // 変更しました。特に意味は無いです。
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;
ResultData=0; // 行を追加しました。最初は停止状態から
Kagen=1; // 行を追加しました。加速します。
// main loop
while(1)
_RB8=~_RB8; // 行を追加しました。周波数の確認用なので不要です。
{
// A/D result store in ResultData
}
// CloseTimer3(); // never excute
// CloseADC12(); // never excute
// CloseOC1(); // never excute
}