2

私はmikroCを使用してpic16f84aをプログラムしており、次の機能があります

volatile unsigned short d;  // global variable

void put_data(){
    RA3_bit = d & 1;
    d >>= 1;
    RA4_bit = d & 1;
    d >>= 1;
    PORTB.B0 = d & 1;
    d >>= 1;
    PORTB.B1 = d & 1;
    d >>= 1;
    PORTB.B2 = d & 1;
    d >>= 1;
    PORTB.B3 = d & 1;
    d >>= 1;
    PORTB.B4 = d & 1;
    d >>= 1;
    PORTB.B5 = d & 1;
}

この関数は、d (8 ビット) から各ビットを取得し、ポートピン RA3、RA4、RB0、...、RB5 に出力します。

このコードを最適化するにはどうすればよいでしょうか。メモリが私の最初の関心事です。

アップデート::

pic16f84a.h から:

volatile unsigned char           PORTA               @ 0x005;
// bit and bitfield definitions
volatile bit RA0                 @ ((unsigned)&PORTA*8)+0;
volatile bit RA1                 @ ((unsigned)&PORTA*8)+1;
volatile bit RA2                 @ ((unsigned)&PORTA*8)+2;
volatile bit RA3                 @ ((unsigned)&PORTA*8)+3;
volatile bit RA4                 @ ((unsigned)&PORTA*8)+4;

volatile unsigned char           PORTB               @ 0x006;
// bit and bitfield definitions
volatile bit RB0                 @ ((unsigned)&PORTB*8)+0;
volatile bit RB1                 @ ((unsigned)&PORTB*8)+1;
volatile bit RB2                 @ ((unsigned)&PORTB*8)+2;
volatile bit RB3                 @ ((unsigned)&PORTB*8)+3;
volatile bit RB4                 @ ((unsigned)&PORTB*8)+4;
volatile bit RB5                 @ ((unsigned)&PORTB*8)+5;
volatile bit RB6                 @ ((unsigned)&PORTB*8)+6;
volatile bit RB7                 @ ((unsigned)&PORTB*8)+7;

ヘッダー ファイルからこれらの値を使用して、関数をループ内の数行のコードにすることはできますか?

4

2 に答える 2

3

PORTB.B0 から PORTB.B5 までが出力ポートのビットであると仮定すると、これを実行した方が高速になる可能性があります。


volatile unsigned short d;  // global variable

void put_data(){
    RA3_bit = d & 1;
    d >>= 1;
    RA4_bit = d & 1;
    d >>= 1;

    PORTB &= 0x3F; // Mask out the low 6 bits
    PORTB |= d & 0x3f;  // Or in the low 6 bits of d

    // Clean out the bits if needed in d
    d >>= 6;
}

アセンブラは、現在行っていることの約 2 倍、あるいはそれ以上の速さで出てくると思います。最初の 2 つの命令で 3 番目と 4 番目のビットを論理和することは、おそらく、ポート内のビットの位置に対して行う価値はありません。ただし、念のため、アセンブラの出力を常に再確認してください。アセンブラのオペコードは単純なので、すぐに確認できます。

于 2012-05-22T21:19:01.120 に答える
1

A & B の PORT または LAT レジスタの現在の値を読み取ります。その PIC に PORT と LAT の両方がある場合は、違いを知ることが重要です。どちらを使用すればよいかわからない場合は、調査を行うことをお勧めします。

次に、適切なピンのみを変更するために必要なシフトとマスキングを行い、ポート A に 1 つ、ポート B に 1 つの 2 つの書き込み操作のみを行います。

または、ポート A と B の他のすべてのピンが、各ポートに関連付けられた TRIS レジスタを介して入力に設定されている場合は、読み取りステップをスキップします。

たとえば、次のようになります。

tmp = PORTA;
tmp = (tmp & 0xFC) | (d & 0x3);
PORTA = tmp;

tmp = PORTB;
tmp = (tmp & 0xE0) | ((d >> 2) & 0x1F);
PORTB = tmp;

実際には、コードとは逆のビット順序が得られると思うので、ビット操作を「逆にする」か、dそのコードを使用する前にビット順序を反転する必要があるかもしれません。

また、これが実際により高速な PIC コードを生成することを保証するものではありません。本当に最速のアプローチが必要な場合は、数行のアセンブリを記述する必要があるかもしれません。

于 2012-05-22T21:23:10.590 に答える