PV用DCDCコンバータ開発(29) 液晶表示部コーディング

この取組みでは、実験的なこと、かつ、金をかけないという課題もあり、制御用のCPUは、PIC16F1823という14ピンのDIP-ICを利用している。秋月電子でばら売りでも¥90で手に入るので使いやすい。安くても、内部クロック32MHz動作ができて、10ビットのAD変換は8チャンネル、パワコンやモータを制御するためのPWMまで持つ、機能的に盛りだくさんの優れもの。

私がマイコンをいじり始めた30年前にはとても考えられない。しかも、2年ほど前まではフリーの開発環境ではアセンブラしか使えなかったのが、C言語開発環境が開放され、デバッガを含めた開発環境まで無償で提供されている。至れりつくせり。

今回のチップは、AD変換の終了フラグが立たない時があるというバグ付ではあるが、ソフト的な解決法は確立されている方法で回避できた。盛りだくさんの機能をわずか14本の足で、外部とやりとりしなければならず、個々の機能は、特定の足に割当てられており、回路の最適化が設計者の腕の見せ所。

プログラムが機能拡充し、完成度が上がってきたが、高機能なMPPTや、定期的なキャリブレーション機能も盛り込みたい。しかし、そのためにはメモリ不足になってしまう。

これまでは、90%位で収っていたが、電圧測定の移動平均、MPPT機能、定期的なキャリブレーションと贅沢に機能を盛込んだところ、わずか2Kのメモリ空間はあふれてしまった。

アセンブラで書き直せば入るかもしれないが、Z80等と違いRISC系チップは命令が少なく書くのに手間がかかる。Cになじんだ身には辛い。

Cのプログラムをスリム化し、命令とメモリ消費量の関係を確認しながら、メモリ消費圧縮を進めることにした。

406129_267127070080481_1254526269_n

液晶ディスプレイ表示にC言語標準のprintf関数を使っている。「%04d」とフォーマットを指定すると簡単に表示形式を設定できる。しかし、こいつがくせ者。%sで文字列表示すると、メモリを大量消費する現象を発見。即座に却下。文字列は固定文字列のみを表示するように変更。

それでもメモリが足りない。20%ほど消費するprintf自体を泣く泣くあきらめる。数字を文字列に表示させるstdlib.hのitoa関数を利用してみたが、これもメモリ消費が多く却下。結局、自作に。

桁数を狙い撃ちしてやれば難しくないし、左をスペースパディングすれば、表示位置も揃う。試行錯誤し、シンプルになったのが、こちら。最初は、10進数表示を試したが、除算がメモリを20%以上消費する。10進除算の自作も考えたがメモリ消費は抑えられないと思い、16進表示で我慢することに。その結果、完成したのが、以下のプログラム。

// 左スペースパディング付き整数→文字列(16進4桁)変換
//   除算(/1000,/100など)はメモリを20%以上消費するため使えずシフト演算にした
//   呼び出し側で必要な桁数を得る場合は、(buf+1)などでアクセスすればよい
void utoa_zero_padding(unsigned short int num, unsigned char keta, unsigned char* buf){
*(buf+(keta–))=’’;
do{
*(buf+keta)=hex_num[num&0x000F];
num/=16;
}while(keta–);
}
// LCD1行目表示(モード、測定値モード、デューティー比)
void print_lcd_line1(){
unsigned char buf[5];
lcd_goto(LCD_LineNumber1);
lcd_putch(‘M’);
utoa_zero_padding(mode_code,4,buf);
lcd_putch(‘I’);
lcd_putch(hex_num[vstatus[V_IN]]);
lcd_putch(‘C’);
lcd_putch(hex_num[vstatus[V_CTL]]);
lcd_putch(‘O’);
lcd_putch(hex_num[vstatus[V_OUT]]);
lcd_puts(” D”);
utoa_zero_padding(duty,3,buf);
lcd_puts(buf);
}
// LCD2行目表示(測定値)
void print_lcd_line2(){
unsigned char buf[5];
// 表示用文字列(桁数+1)
lcd_goto(LCD_LineNumber2);
//  ターゲット電圧
lcd_putch(‘T’);
utoa_zero_padding(mppt_tgt_v,3,buf);
lcd_puts(buf);
//  入力電圧
lcd_putch(‘I’);
utoa_zero_padding(advalue[V_IN],3,buf);
lcd_puts(buf);
//  制御電圧
lcd_putch(‘C’);
utoa_zero_padding(advalue[V_CTL],3,buf);
lcd_puts(buf);
//  出力電圧
lcd_putch(‘O’);
utoa_zero_padding(advalue[V_OUT],3,buf);
lcd_puts(buf);
}

//  LCDディスプレイ表示
void display(void){
print_lcd_line1();
print_lcd_line2();
}
シンプルなのだが、クールではない。ひたすら、メモリ消費を抑えることを考え、読みやすさは二の次。シフト演算と、ポインタのいかがわしい利用満載でとても人には自慢できるものではないが、あえてご紹介。

ポインタは、過去に何度も地雷を踏んでおり、利用は極力避けたいのだが、Cで文字列を扱えば、避けて通れず。string.hやstdlib.hも利用できないとなると、なおさら。(一応、標準的なライブラリは、提供されているが、メモリ消費の関係で使うことができず。メモリがふんだんに使えれば、当然、PIC向けの標準ライブラリを使うべきだ。)

こんな苦労の甲斐あって、とりあえず、入れたかった機能は全て盛り込んだがメモリ使用率98%。機能追加は不可能な状況。制御ロジックの見直しで、もう少し、シンプルにすることを検討しよう。

長かった正月休みも、明日で最終日。どっぷりとDCDCコン開発に没頭できた幸せな数日間、家族のみなに感謝。。。。

前回へ  次回へ

(Visited 496 times, 1 visits today)
スポンサーリンク

シェアする

フォローする