メインプログラム:EVR.c
プロセッサーエキスパートで設定した結果、下図の様なソースが生成されます。初期設定は全て完了していますのでMAIN関数の含まれているEVR.cのみ記述すれば終わりです。
メインプログラムは以下の関数から構成されます。
VR設定値送信関数
SEND_DATA()
ボリューム設定値をSPIでPGA2311に送信して戻ります。
引数はありません。
例
SEND_DATA();
戻り値はありません。
/*******************
* VR設定値送信関数 *
*******************/
void SEND_DATA(void)
{
clrReg8Bits(TPM1C0SC, 0x40); // 割り込み禁止
CS_ClrVal(); // チップセレクト→LOW
result = SM1_SendChar(R_DATA); // Rch VRデータ送信
result = SM1_SendChar(L_DATA); // Lch VRデータ送信
while(!SPIS_SPTEF){} // 送信完了待ち
CS_SetVal(); // チップセレクト→HI
flg = 0; // 変化フラグクリア
setReg8Bits(TPM1C0SC,0x40); // 割り込み許可
}
最初に割り込みを禁止します。
割り込み原因はRE(ロータリーエンコーダー)を回した時だけですが、送信中は受け付けないようにします。
余談ですが最初に出てくる関数は、PEが自動生成したコードの中に良く出てくる8ビットレジスタのビット制御用関数です。
clrReg8Bits(引数1、引数2)
例
clrReg8Bits(TPM1C0SC, 0x40);
TPM1C0SCレジスタのBit2をクリアする。
引数1は操作したいレジスタ名(1バイトレジスタ)
引数2は操作したいビット位置です。ビット位置はマスクで取り出す様に指定しています。
bit0 0x01
bit1 0x02
bit2 0x04
bit3 0x08
bit4 0x10
bit5 0x20
bit6 0x40
bit7 0x80
同様にsetReg8Bits(引数1、引数2)は指定ビットをセットします。
便利なので愛用しています。
送信はまずCS(チップセレクト)をLOWにして、SM1の送信関数でRchのデータを送信します。戻り値は特に必要ありませんが引き取らないとコンパイラからワーニングが出たのでresultに入れておきます。エラーなどが戻ってきます。
PGA2311は連続してLchのデータも送信しなければならないので、引き続きLchデータを送信します。
次のwhile文は送信終了フラグを監視してフラグが来たら次の処理に移ります。
全送信が終了したのでCSをHIに戻します。flgは変化フラグとしてREでデータが書きかわた時1になります。送信したので変化フラグはクリアします。
最後に割り込みを許可して戻ります。
ロータリーエンコーダ割込関数
ISR(RE_Interrupt)
この関数はロータリーエンコーダーのB相が接続されているキャプチャ入力が変化したことによる割り込みで、ベクターテーブルにより指定されています。
割り込み処理終了後、割り込み前の位置に戻ります。
/*******************************
* ロータリーエンコーダ割込関数 *
*******************************/
ISR(RE_Interrupt)
{
clrReg8Bits(TPM1C0SC, 0x40); // 割り込み禁止
clrReg8Bits(TPM1C0SC, 0x80); // 割り込みフラグクリア
if(PTBD_PTBD0 == PTCD_PTCD0) // 回転方向判断 A=B 時計方向
{
if(R_DATA < 255) // 最大値制限
{
R_DATA = R_DATA++; // Rch VR値をインクリメント
}
if(L_DATA < 255) // 最大値制限
{
L_DATA = L_DATA++; // Lch VR値をインクリメント
}
}
else // A=!B 反時計方向
{
if(R_DATA > 0) // 最小値制限
{
R_DATA = R_DATA--; // Rch VR値をデクリメント
}
if(L_DATA > 0) // 最小値制限
{
L_DATA = L_DATA--; // Lch VR値をデクリメント
}
}
flg = 1; // 変化フラグをセット
setReg8Bits(TPM1C0SC,0x40); // 割り込み許可
}
割込み処理なのでまず、割り込みを禁止します。
割込みフラグをクリアします。
ロータリーエンコーダーが接続されているA相とB相のポートを比較して、同じであれば時計方向に回転したのでRchボリュームデータが最大値(255)でなければをインクリメントします。同様にLchも最大値でなければインクリメントします。
反時計方向に回った場合は最小値(0)でなければデクリメントします。最後にボリュームデータが変わったので変化フラグをセットします。
割り込みを許可して戻ります。
メイン関数
main();
メイン関数です。
/*************
* メイン関数 *
*************/
void main(void)
{
/* Write your local variable definition here */
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/
/* Write your code here */
/* For example: for(;;) { } */
/***** 初期設定 *****/
clrReg8Bits(TPM1C0SC, 0x80); // 割り込みフラグクリア
L_DATA = 128; // Lch初期設定値
R_DATA = 128; // Rch初期設定値
flg = 1;
Cpu_Delay100US(5000); // 0.5秒待ち
/***** メインループ *****/
for(;;)
{
if(flg == 1) // 変化フラグチェック
{
SEND_DATA(); // 変化有り→VR設定値送信関数へ
}
Cpu_Delay100US(100); // 10mS待ちしてループ
}
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;){}
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
PE_low_level_init()
プロセッサーエキスパートが自動生成したCPU.cの初期化関数群。引数および戻り値はありません。
初期設定
起動時の割込みフラグをクリアします。そしてボリュームデータに初期値を代入し、変化フラグをセットして起動時の初期データをPGA2311に送信させます。
起動時、PGA2311が設定を受け付けない事があったので、最後の行に0.5秒待機してからメインループに行くように追加しました。
メインループ
変化フラグがセットされていればVR設定値送信関数を実行します。
割り込みベクタテーブル:Vectors.c
PEで割り込みベクタを設定したのでベクタ番号5がRE_Interruptに設定されています。
extern near void _EntryPoint(void);
void (* near const _vect[])(void) @0xFFC0 = { /* Interrupt vector table */
Cpu_Interrupt, /* Int.no. 31 VReserved31 (at FFC0) Unassigned */
Cpu_Interrupt, /* Int.no. 30 Vacmp (at FFC2) Unassigned */
Cpu_Interrupt, /* Int.no. 29 VReserved29 (at FFC4) Unassigned */
Cpu_Interrupt, /* Int.no. 28 VReserved28 (at FFC6) Unassigned */
Cpu_Interrupt, /* Int.no. 27 VReserved27 (at FFC8) Unassigned */
Cpu_Interrupt, /* Int.no. 26 Vmtim (at FFCA) Unassigned */
Cpu_Interrupt, /* Int.no. 25 Vrtc (at FFCC) Unassigned */
Cpu_Interrupt, /* Int.no. 24 Viic (at FFCE) Unassigned */
Cpu_Interrupt, /* Int.no. 23 Vadc (at FFD0) Unassigned */
Cpu_Interrupt, /* Int.no. 22 VReserved22 (at FFD2) Unassigned */
Cpu_Interrupt, /* Int.no. 21 Vportb (at FFD4) Unassigned */
Cpu_Interrupt, /* Int.no. 20 Vporta (at FFD6) Unassigned */
Cpu_Interrupt, /* Int.no. 19 VReserved19 (at FFD8) Unassigned */
Cpu_Interrupt, /* Int.no. 18 Vscitx (at FFDA) Unassigned */
Cpu_Interrupt, /* Int.no. 17 Vscirx (at FFDC) Unassigned */
Cpu_Interrupt, /* Int.no. 16 Vscierr (at FFDE) Unassigned */
Cpu_Interrupt, /* Int.no. 15 Vspi (at FFE0) Unassigned */
Cpu_Interrupt, /* Int.no. 14 Vtpm2ovf (at FFE2) Unassigned */
Cpu_Interrupt, /* Int.no. 13 Vtpm2ch1 (at FFE4) Unassigned */
Cpu_Interrupt, /* Int.no. 12 Vtpm2ch0 (at FFE6) Unassigned */
Cpu_Interrupt, /* Int.no. 11 Vtpm1ovf (at FFE8) Unassigned */
Cpu_Interrupt, /* Int.no. 10 VReserved10 (at FFEA) Unassigned */
Cpu_Interrupt, /* Int.no. 9 VReserved9 (at FFEC) Unassigned */
Cpu_Interrupt, /* Int.no. 8 VReserved8 (at FFEE) Unassigned */
Cpu_Interrupt, /* Int.no. 7 VReserved7 (at FFF0) Unassigned */
Cpu_Interrupt, /* Int.no. 6 Vtpm1ch1 (at FFF2) Unassigned */
RE_Interrupt, /* Int.no. 5 Vtpm1ch0 (at FFF4) Used */
Cpu_Interrupt, /* Int.no. 4 VReserved4 (at FFF6) Unassigned */
Cpu_Interrupt, /* Int.no. 3 Vlvd (at FFF8) Unassigned */
Cpu_Interrupt, /* Int.no. 2 Virq (at FFFA) Unassigned */
Cpu_Interrupt, /* Int.no. 1 Vswi (at FFFC) Unassigned */
_EntryPoint /* Int.no. 0 Vreset (at FFFE) Reset vector */
};