Hitech PICC Pro Liteモードは、私の趣味の電子工作に欠かすことができない存在だ。随分昔だったか、BBSの書き込みで「Delayが改善されている」と発言されていたのがあったことを思い出した。
Ver9.71までのDelayマクロは、生成されるサイクル数が197,120サイクルの制約で、時間の上限に限りがあった。1秒を作るには、これを更にループして作るなどの工夫が必要だった。
計算は最大取り扱い時間 = (1 ÷ 動作周波数Hz) x 4(サイクル) x 197120(最大取り扱いサイクル数)となる。ホームページ上の説明より。
HitecPICC9.71迄のDelay時間の扱い
動作周波数 | 最大時間 | __delay_ms(x) | __delay_us(x) |
---|
20MHz | 39,424us | __delay_ms(39); | __delay_us(39424); |
16MHz | 49,280us | __delay_ms(49); | __delay_us(49280); |
10MHz | 78848us | __delay_ms(78); | __delay_us(78848); |
8MHz | 98560us | __delay_ms(98); | __delay_us(98560); |
4MHz | 197120us | __delay_ms(197); | __delay_us(197120);
|
それがVer9.80以降、サイクル数が増えて、なんと50,660,096サイクルまで使用出来る様になった。つまり、8MHzならdelayマクロ一つについて25秒まで扱えるのだ。これは便利。
計算上では、8MHzの場合、
1/8,000,000 * 4 * 50,660,096 = 25.330048sec
なのだが、実際に使ってみると、delay_msの場合、25,231秒までであり、これを超えると、
595. delay exceeds maximum limit of 50660096 cycles
というエラーが起きてしまった。同様にusも調査。使えた数字は4MHzで
__delay_ms(50462);
__delay_us(50462464);
ver9.82の場合、逆算したサイクル数は
50462464
で計算すると、つじつまが合うようだ。恐らくエラーメッセージ上で表示されるサイクル数が修正されていないものと思われる。HitechPICC上では、特に最大限使える数字は記されていない。
HitecPICC9.82のDelay時間の扱い
動作周波数 | 最大時間 | __delay_ms(x) | __delay_us(x) |
---|
20MHz | 10,092,493us | __delay_ms(10092); | __delay_us(10092493); |
16MHz | 12,615,616us | __delay_ms1(2615); | __delay_us(12615616); |
10MHz | 20,184,986us | __delay_ms(20184); | __delay_us(20184986); |
8MHz | 25,231,232us | __delay_ms(25231); | __delay_us(25231232); |
4MHz | 50,462,464us | __delay_ms(50462); | __delay_us(50462464); |
32.768Khz | 6,159,968,750us | __delay_ms(6159968); | __delay_us(6159968750);
|
これがそれらを表にしたものである。上記表と比べてもお分かりの通り、かなり長い時間を作る事が可能である。4MHzで50秒のタイマーがDelayマクロ一つで出来てしまう。またMPSIMで計測してみても、時間誤差が小さくなっているのも特徴だ。
おっと、このdelayマクロを使うときは、先頭に使用する周波数に応じた値をセットする。
#define _XTAL_FREQ 20000000
#define _XTAL_FREQ 16000000
#define _XTAL_FREQ 10000000
#define _XTAL_FREQ 8000000
#define _XTAL_FREQ 4000000
この数字を使用してdelayマクロは計算されるからである。これが無いとエラーになる。
さらに、引数は固定値であるマクロのため、変数を値として代入する事は出来ない。
但し、このDelayマクロをLiteモードで使う場合は、ループで処理するより少し容量が増える様である。まずは、よく使う10msのループを使っているプログラムで検証
void delay_10ms(unsigned int temp){ //10ms multiple x times
while(temp--){
__delay_ms(10);
}
}
●Memory Summary:
Program space used FAFh ( 4015) of 1000h words ( 98.0%)
16個あるdelay_10ms()を__delay_ms();に全て置き換えた場合
●Memory Summary:
Program space used FE1h ( 4065) of 1000h words ( 99.2%)
なんと50ワードも増えてしまった。
ちなみに、このプログラムはDelayで255を超える部分はないので、16個あるdelay_10ms(unsigned int temp)のunsigned int型をunsigned charにしてみた
●Memory Summary:
Program space used F7Ah ( 3962) of 1000h words ( 96.7%)
おお、53バイトも節約した。プログラムコードが大きくなって、少しでも容量を増やしたい場合は、こういう小技も有効だろう。
それにしても、一回のDelay関数で扱える時間が大幅に増えたのは、ブログラムを書きやすくしてくれるので、ドンドン利用したいと思う。
ところで、
最近のコメント