<制御概要>

電流読取 -> PWM停止 -> PWM停止待ち -> 電圧読取 ->
目標電圧設定 -> 読取値表示 -> グラフに表示 -> 戻る

PWMの調整は、3.3msごとの割り込み処理でAD変換開始
-> 変換終了割り込みで目標値と比較しGRBを調整。

発電量を4行分の32dotいグラフ表示が面倒

unsigned char logh;  // dot数
unsigned long tempUL;
unsigned char *tempUCp;

tempUL = (unsigned long)volt * (unsigned long)amp * 4UL / 50000UL;
logh = (unsigned char)tempUL;

for ( tempUL = 0, loop = 0; loop < logh; loop++ ) {
  tempUL |= 0x80000000;
  tempUL >>= 1;
}
tempUL <<= 1;
tempUCp = (unsigned char *)&tempUL;

for ( wait = amp = 0; wait < 12; wait++ ) {

 tempUS = hlog >> 3;

 switch ( wait ) {
  case 0:
  case 1:
  case 2:
  case 3:
   lcdGraphic( ( tempUS + 2 ) & 0x7f, wait + 2, (unsigned char *)&, 1 );
   break;

  case 4:
  case 5:
  case 6:
  case 7:
   lcdGraphic( tempUS & 0x7f, wait - 2, (unsigned char *)&, 1 );
   break;

  case 8:
   lcdGraphic( tempUS & 0x7f, 5, tempUCp + 3, 1 );
   break;
  case 9:
   lcdGraphic( tempUS & 0x7f, 4, tempUCp + 2, 1 );
   break;
  case 10:
   lcdGraphic( tempUS & 0x7f, 3, tempUCp + 1, 1 );
   break;
  case 11:
   lcdGraphic( tempUS & 0x7f, 2, tempUCp, 1 );
   break;
  default:
   break;
 }
 wait();
}

if ( hlog == 2048 ) hlog = 0;
else hlog++;
秋月電子の「AQM1248A」は、LCDコントローラに「ST7565R」を使用。

ルネサスマイコンカーラリー事務局さんが、ここで公開されている、
グラフィック液晶(ST7565R)制御プログラムを使わせてもらう。
R8C/38A or R8C/38C 向きに実装されているので、使っている
R8C/29向けに小変更。

OSは、YAM氏のページマイコンコーナーで公開されている、
「MtOSM16」を使わせて頂いた(デバッグ機能は未使用)。

「main.cでの初期化処理」
// クロック:高速オンチップオシレータ 20MHz
prc0 = 1;        // プロテクト制御(書き換え許可)
fra00 = 1;       // 高速オンチップオシレータ発振
fra01 = 1;       // 高速オンチップオシレータ選択
*(volatile char*)0;   // 発振の安定待ち
*(volatile char*)0;   //   (同上)
*(volatile char*)0;   //   (同上)
fra2 = 0x00;      // 2分周モード(20MHz)
cm06 = 0;        // システムクロック:20MHz
cm16 = 0;
cm17 = 0;
ocd2 = 1;        // 高速オンチップオシレータ選択
prc0 = 0;        // プロテクト制御(書き換え禁止)

// AN8:電圧測定 (10bit)
// AN9:電流測定 (10bit)
adgsel0 = 1;      // 1:有効(AN8~AN11)
ch0  = 0;       // AN8
ch1  = 0;
ch2  = 1;
cks0_adcon0 = 0;    // CKS0 f4を選択
// ADCON1
bits = 1;       // 1:10ビットモード
cks1_adcon1 = 0;    // CKS1
vcut = 1;       // 1:Vref接続
// ADCON2
smp  = 1;       // 1:サンプル&ホールドあり
adic = 4;       // A/D変換割込レベル4

// TimerRA:LCD更新で使用 (1ms)
traic = 5;       // 割込レベル5
tramr = 0x10;     // ソース選択 20MHz / 8 = 2.5MHz
trapre = 250 - 1;    // 1/(250x10) = 1ms
tra  = 10 - 1;
tstart_tracr = 1;    // TimerRA START

// TimerRB:OSタイマーで使用 (3.32ms)
tck0_trbmr = 1;    // CLK:f8 20MHz / 8 = 2.5MHz
tck1_trbmr = 0;  
trbpre = 83 - 1;    // タイマRBプリスケーラ
trbpr = 100 - 1;    // 2.5MHz / 83 / 100 = 301Hz(3.32ms)
trbioc = 0x00;
trbic = 5;       // TimerRB 割込レベル5
tstart_trbcr = 1;    // TimerRB Start

// TimerRC:PWMで使用 (62.5KHz)
pwmb_trcmr = 1;     // TRCIOB PWMモード <<--- これをしないとPWM信号出ない
trccr1 = 0x92;     // TRCIOB 初期値:"H"
            // CLK:f2 = 20MHz / 2 = 10MHz
            // TRCGRAのコンペア一致でクリア
trcior0 = 0x18;     // GRBでTRCIOB="L"
eb_trcoer = 0;     // TRCIOB出力許可
trcgra = 160 - 1;    // GRA(周期) = 160:10MHz / 160 = 62.5KHz
trcgrb = 0;       // 初期値:0
tstart_trcmr = 1;    // TimerRC START

ei();          // 割り込み許可

「intprg.cので割り込み処理」
// timer RA    (software int 22)
#pragma interrupt _timer_ra(vect=22)
void _timer_ra(void);
void _timer_ra(void)
{
 lcdShowProcess( );  // 液晶表示処理用関数(1msごとに実行)
}